From 7b46477ca00b513dece1d7ea0a3512d382476438 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sat, 20 Sep 2025 01:41:54 -0400 Subject: [PATCH] Add explicit hook for deciding whether to include the genesis validators --- substrate/abi/src/economic_security.rs | 7 +++ substrate/validator-sets/src/lib.rs | 59 ++++++++++++++++---------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/substrate/abi/src/economic_security.rs b/substrate/abi/src/economic_security.rs index f4fcd1ce..84a1f263 100644 --- a/substrate/abi/src/economic_security.rs +++ b/substrate/abi/src/economic_security.rs @@ -11,3 +11,10 @@ pub enum Event { network: ExternalNetworkId, }, } + +/// A trait representing access to the information on economic security. +pub trait EconomicSecurity { + /// If am external network has _ever_ achieved economic security. + #[must_use] + fn achieved_economic_security(network: ExternalNetworkId) -> bool; +} diff --git a/substrate/validator-sets/src/lib.rs b/substrate/validator-sets/src/lib.rs index 0ba6d84a..9e9dfe9c 100644 --- a/substrate/validator-sets/src/lib.rs +++ b/substrate/validator-sets/src/lib.rs @@ -51,13 +51,16 @@ mod pallet { use pallet_babe::Pallet as Babe; use pallet_grandpa::Pallet as Grandpa; - use serai_abi::primitives::{ - crypto::SignedEmbeddedEllipticCurveKeys, - network_id::*, - coin::*, - balance::*, - validator_sets::{Session, ValidatorSet, KeyShares as KeySharesStruct}, - address::SeraiAddress, + use serai_abi::{ + primitives::{ + crypto::SignedEmbeddedEllipticCurveKeys, + network_id::*, + coin::*, + balance::*, + validator_sets::{Session, ValidatorSet, KeyShares as KeySharesStruct}, + address::SeraiAddress, + }, + economic_security::EconomicSecurity, }; use serai_coins_pallet::Pallet as Coins; @@ -73,6 +76,7 @@ mod pallet { + serai_coins_pallet::Config { type ShouldEndSession: ShouldEndSession>; + type EconomicSecurity: EconomicSecurity; } #[pallet::genesis_config] @@ -250,14 +254,10 @@ mod pallet { // Spawn BABE's, GRANDPA's genesis session let genesis_serai_validators = Abstractions::::serai_validators(Session(0)); Babe::::on_genesis_session( - genesis_serai_validators - .iter() - .map(|(validator, key)| (validator, (*key).into())), + genesis_serai_validators.iter().map(|(validator, key)| (validator, (*key).into())), ); Grandpa::::on_genesis_session( - genesis_serai_validators - .iter() - .map(|(validator, key)| (validator, (*key).into())), + genesis_serai_validators.iter().map(|(validator, key)| (validator, (*key).into())), ); } } @@ -306,13 +306,16 @@ mod pallet { Abstractions::::stake_for_current_validator_set(network) } - fn attempt_external_network_session_rotation() { - for network in ExternalNetworkId::all() { - let include_genesis_validators = true; // TODO - Abstractions::::attempt_new_session(network.into(), include_genesis_validators); + fn include_genesis_validators(network: NetworkId) -> bool { + match network { + // For Serai, we include the genesis validators as long as any other set does + NetworkId::Serai => { + ExternalNetworkId::all().all(T::EconomicSecurity::achieved_economic_security) + } + // For the other networks, we include the genesis validators if they have yet to achieve + // economic security + NetworkId::External(network) => T::EconomicSecurity::achieved_economic_security(network), } - - // TODO Dex::::on_new_session(network); } /* @@ -568,14 +571,16 @@ mod pallet { // Accept the hand-over to the next session for the Serai network Abstractions::::accept_handover(NetworkId::Serai); // Decide the next session for the Serai network - let include_genesis_validators = true; // TODO assert!( - Abstractions::::attempt_new_session(NetworkId::Serai, include_genesis_validators), + Abstractions::::attempt_new_session( + NetworkId::Serai, + Self::include_genesis_validators(NetworkId::Serai) + ), "failed to attempt the next session for the Serai network" ); } - // Update BABE + // Update BABE, GRANDPA { let current_serai_session = Abstractions::::current_session(NetworkId::Serai) .expect("never selected a session for Serai"); @@ -624,7 +629,15 @@ mod pallet { ); } - Self::attempt_external_network_session_rotation(); + // Attempt new sessions for all external networks + for network in ExternalNetworkId::all() { + Abstractions::::attempt_new_session( + network.into(), + Self::include_genesis_validators(network.into()), + ); + } + + // TODO Dex::::on_new_session(network); Weight::zero() // TODO } else {