From 609cf063932b07c6c87ec256136c321e2be654ef Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 15 Nov 2025 14:59:33 -0500 Subject: [PATCH] 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. --- substrate/abi/src/validator_sets.rs | 4 ++++ substrate/client/serai/Cargo.toml | 1 + substrate/client/serai/tests/validator_sets.rs | 15 +++++++++++++-- substrate/validator-sets/src/sessions.rs | 12 +++++++++--- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/substrate/abi/src/validator_sets.rs b/substrate/abi/src/validator_sets.rs index 42576328..40b30e16 100644 --- a/substrate/abi/src/validator_sets.rs +++ b/substrate/abi/src/validator_sets.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use borsh::{BorshSerialize, BorshDeserialize}; use serai_primitives::{ @@ -96,6 +98,8 @@ pub enum Event { SetDecided { /// The set decided. set: ValidatorSet, + /// The validators decided to be included in the set. + validators: Vec<(SeraiAddress, KeyShares)>, }, /// A validator set has set their keys. SetKeys { diff --git a/substrate/client/serai/Cargo.toml b/substrate/client/serai/Cargo.toml index d5ff35eb..48fb0611 100644 --- a/substrate/client/serai/Cargo.toml +++ b/substrate/client/serai/Cargo.toml @@ -30,6 +30,7 @@ async-lock = "3" [dev-dependencies] 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"] } dockertest = "0.5" diff --git a/substrate/client/serai/tests/validator_sets.rs b/substrate/client/serai/tests/validator_sets.rs index be0000d6..cc9ca300 100644 --- a/substrate/client/serai/tests/validator_sets.rs +++ b/substrate/client/serai/tests/validator_sets.rs @@ -1,8 +1,9 @@ use serai_abi::{ primitives::{ + address::SeraiAddress, network_id::{ExternalNetworkId, NetworkId}, balance::Amount, - validator_sets::{Session, ExternalValidatorSet, ValidatorSet}, + validator_sets::{Session, ExternalValidatorSet, ValidatorSet, KeyShares}, }, validator_sets::Event, }; @@ -43,8 +44,13 @@ async fn validator_sets() { 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 .as_of(serai.block_by_number(0).await.unwrap().header.hash()) @@ -58,27 +64,32 @@ async fn validator_sets() { let mut expected = vec![ Event::SetDecided { set: ValidatorSet { network: NetworkId::Serai, session: Session(0) }, + validators: genesis_validators.clone(), }, Event::SetDecided { set: ValidatorSet { network: NetworkId::Serai, session: Session(1) }, + validators: genesis_validators.clone(), }, Event::SetDecided { set: ValidatorSet { network: NetworkId::External(ExternalNetworkId::Bitcoin), session: Session(0), }, + validators: genesis_validators.clone(), }, Event::SetDecided { set: ValidatorSet { network: NetworkId::External(ExternalNetworkId::Ethereum), session: Session(0), }, + validators: genesis_validators.clone(), }, Event::SetDecided { set: ValidatorSet { network: NetworkId::External(ExternalNetworkId::Monero), session: Session(0), }, + validators: genesis_validators.clone(), }, ]; expected.sort_by_key(|event| borsh::to_vec(event).unwrap()); diff --git a/substrate/validator-sets/src/sessions.rs b/substrate/validator-sets/src/sessions.rs index 0f1121e8..ed54029d 100644 --- a/substrate/validator-sets/src/sessions.rs +++ b/substrate/validator-sets/src/sessions.rs @@ -326,14 +326,20 @@ impl Sessions for Storage { latest_decided_set, 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( - selected_validators_key(latest_decided_set, key), + selected_validators_key(latest_decided_set, *key), key_shares, ); } - Core::::emit_event(Event::SetDecided { set: latest_decided_set }); + Core::::emit_event(Event::SetDecided { + set: latest_decided_set, + validators: selected_validators + .into_iter() + .map(|(key, key_shares)| (key.into(), key_shares)) + .collect(), + }); true }