Update SetDecided to include the validators

Necessary for light-client protocols to follow along with consensus. Arguably,
anyone handling GRANDPA's consensus could peek at this through the consensus
commit anyways, but we shouldn't so defer that.
This commit is contained in:
Luke Parker
2025-11-15 14:59:33 -05:00
parent 46b1f1b7ec
commit 609cf06393
4 changed files with 27 additions and 5 deletions

View File

@@ -1,3 +1,5 @@
use alloc::vec::Vec;
use borsh::{BorshSerialize, BorshDeserialize}; use borsh::{BorshSerialize, BorshDeserialize};
use serai_primitives::{ use serai_primitives::{
@@ -96,6 +98,8 @@ pub enum Event {
SetDecided { SetDecided {
/// The set decided. /// The set decided.
set: ValidatorSet, set: ValidatorSet,
/// The validators decided to be included in the set.
validators: Vec<(SeraiAddress, KeyShares)>,
}, },
/// A validator set has set their keys. /// A validator set has set their keys.
SetKeys { SetKeys {

View File

@@ -30,6 +30,7 @@ async-lock = "3"
[dev-dependencies] [dev-dependencies]
blake2 = { version = "0.11.0-rc.3", default-features = false } blake2 = { version = "0.11.0-rc.3", default-features = false }
sp-core = { git = "https://github.com/serai-dex/patch-polkadot-sdk", rev = "e01101b68c5b0f588dd4cdee48f801a2c1f75b84" }
tokio = { version = "1", default-features = false, features = ["rt", "macros"] } tokio = { version = "1", default-features = false, features = ["rt", "macros"] }
dockertest = "0.5" dockertest = "0.5"

View File

@@ -1,8 +1,9 @@
use serai_abi::{ use serai_abi::{
primitives::{ primitives::{
address::SeraiAddress,
network_id::{ExternalNetworkId, NetworkId}, network_id::{ExternalNetworkId, NetworkId},
balance::Amount, balance::Amount,
validator_sets::{Session, ExternalValidatorSet, ValidatorSet}, validator_sets::{Session, ExternalValidatorSet, ValidatorSet, KeyShares},
}, },
validator_sets::Event, validator_sets::Event,
}; };
@@ -43,8 +44,13 @@ async fn validator_sets() {
panic!("finalized block remained the genesis block for over five minutes"); panic!("finalized block remained the genesis block for over five minutes");
}; };
// The genesis block should have the expected events
{ {
use sp_core::{Pair as _, sr25519::Pair};
let genesis_validators = vec![(
SeraiAddress::from(Pair::from_string("//Alice", None).unwrap().public()),
KeyShares(1),
)];
// The genesis block should have the expected events
{ {
let mut events = serai let mut events = serai
.as_of(serai.block_by_number(0).await.unwrap().header.hash()) .as_of(serai.block_by_number(0).await.unwrap().header.hash())
@@ -58,27 +64,32 @@ async fn validator_sets() {
let mut expected = vec![ let mut expected = vec![
Event::SetDecided { Event::SetDecided {
set: ValidatorSet { network: NetworkId::Serai, session: Session(0) }, set: ValidatorSet { network: NetworkId::Serai, session: Session(0) },
validators: genesis_validators.clone(),
}, },
Event::SetDecided { Event::SetDecided {
set: ValidatorSet { network: NetworkId::Serai, session: Session(1) }, set: ValidatorSet { network: NetworkId::Serai, session: Session(1) },
validators: genesis_validators.clone(),
}, },
Event::SetDecided { Event::SetDecided {
set: ValidatorSet { set: ValidatorSet {
network: NetworkId::External(ExternalNetworkId::Bitcoin), network: NetworkId::External(ExternalNetworkId::Bitcoin),
session: Session(0), session: Session(0),
}, },
validators: genesis_validators.clone(),
}, },
Event::SetDecided { Event::SetDecided {
set: ValidatorSet { set: ValidatorSet {
network: NetworkId::External(ExternalNetworkId::Ethereum), network: NetworkId::External(ExternalNetworkId::Ethereum),
session: Session(0), session: Session(0),
}, },
validators: genesis_validators.clone(),
}, },
Event::SetDecided { Event::SetDecided {
set: ValidatorSet { set: ValidatorSet {
network: NetworkId::External(ExternalNetworkId::Monero), network: NetworkId::External(ExternalNetworkId::Monero),
session: Session(0), session: Session(0),
}, },
validators: genesis_validators.clone(),
}, },
]; ];
expected.sort_by_key(|event| borsh::to_vec(event).unwrap()); expected.sort_by_key(|event| borsh::to_vec(event).unwrap());

View File

@@ -326,14 +326,20 @@ impl<Storage: SessionsStorage> Sessions for Storage {
latest_decided_set, latest_decided_set,
KeySharesStruct::try_from(total_key_shares).expect("amortization failure"), KeySharesStruct::try_from(total_key_shares).expect("amortization failure"),
); );
for (key, key_shares) in selected_validators { for (key, key_shares) in &selected_validators {
Storage::SelectedValidators::insert( Storage::SelectedValidators::insert(
selected_validators_key(latest_decided_set, key), selected_validators_key(latest_decided_set, *key),
key_shares, key_shares,
); );
} }
Core::<Storage::Config>::emit_event(Event::SetDecided { set: latest_decided_set }); Core::<Storage::Config>::emit_event(Event::SetDecided {
set: latest_decided_set,
validators: selected_validators
.into_iter()
.map(|(key, key_shares)| (key.into(), key_shares))
.collect(),
});
true true
} }