From 15e7536a4ed2ac6f1ec4034d44a2c366d96fddb4 Mon Sep 17 00:00:00 2001 From: Andronik Date: Thu, 12 May 2022 11:36:57 +0200 Subject: [PATCH] runtime/session_info: keep track of stash keys (#5473) --- polkadot/runtime/kusama/src/lib.rs | 4 +- polkadot/runtime/parachains/src/mock.rs | 38 ++++++++++++++++- .../runtime/parachains/src/session_info.rs | 41 ++++++++++++++++++- polkadot/runtime/polkadot/src/lib.rs | 4 +- polkadot/runtime/rococo/src/lib.rs | 4 +- polkadot/runtime/test-runtime/src/lib.rs | 4 +- polkadot/runtime/westend/src/lib.rs | 4 +- 7 files changed, 91 insertions(+), 8 deletions(-) diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs index a0e850771c..efaaa8fc84 100644 --- a/polkadot/runtime/kusama/src/lib.rs +++ b/polkadot/runtime/kusama/src/lib.rs @@ -1256,7 +1256,9 @@ impl parachains_configuration::Config for Runtime { impl parachains_shared::Config for Runtime {} -impl parachains_session_info::Config for Runtime {} +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} impl parachains_inclusion::Config for Runtime { type Event = Event; diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index 416903d187..064b9918ff 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -25,7 +25,7 @@ use crate::{ use frame_support::{ parameter_types, - traits::{GenesisBuild, KeyOwnerProofSystem}, + traits::{GenesisBuild, KeyOwnerProofSystem, ValidatorSet, ValidatorSetWithIdentification}, weights::Weight, }; use frame_support_test::TestRandomness; @@ -301,7 +301,41 @@ impl crate::paras_inherent::Config for Test { type WeightInfo = crate::paras_inherent::TestWeightInfo; } -impl crate::session_info::Config for Test {} +pub struct MockValidatorSet; + +impl ValidatorSet for MockValidatorSet { + type ValidatorId = AccountId; + type ValidatorIdOf = ValidatorIdOf; + fn session_index() -> SessionIndex { + 0 + } + fn validators() -> Vec { + Vec::new() + } +} + +impl ValidatorSetWithIdentification for MockValidatorSet { + type Identification = (); + type IdentificationOf = FoolIdentificationOf; +} + +pub struct FoolIdentificationOf; +impl sp_runtime::traits::Convert> for FoolIdentificationOf { + fn convert(_: AccountId) -> Option<()> { + Some(()) + } +} + +pub struct ValidatorIdOf; +impl sp_runtime::traits::Convert> for ValidatorIdOf { + fn convert(a: AccountId) -> Option { + Some(a) + } +} + +impl crate::session_info::Config for Test { + type ValidatorSet = MockValidatorSet; +} thread_local! { pub static DISCOVERY_AUTHORITIES: RefCell> = RefCell::new(Vec::new()); diff --git a/polkadot/runtime/parachains/src/session_info.rs b/polkadot/runtime/parachains/src/session_info.rs index e2dfdea872..5f19d995f8 100644 --- a/polkadot/runtime/parachains/src/session_info.rs +++ b/polkadot/runtime/parachains/src/session_info.rs @@ -23,7 +23,10 @@ use crate::{ configuration, paras, scheduler, shared, util::{take_active_subset, take_active_subset_and_inactive}, }; -use frame_support::{pallet_prelude::*, traits::OneSessionHandler}; +use frame_support::{ + pallet_prelude::*, + traits::{OneSessionHandler, ValidatorSet, ValidatorSetWithIdentification}, +}; use primitives::v2::{AssignmentId, AuthorityDiscoveryId, SessionIndex, SessionInfo}; use sp_std::vec::Vec; @@ -34,6 +37,20 @@ pub mod migration; #[cfg(test)] mod tests; +/// A type for representing the validator account id in a session. +pub type AccountId = <::ValidatorSet as ValidatorSet< + ::AccountId, +>>::ValidatorId; + +/// A tuple of `(AccountId, Identification)` where `Identification` +/// is the full identification of `AccountId`. +pub type IdentificationTuple = ( + AccountId, + <::ValidatorSet as ValidatorSetWithIdentification< + ::AccountId, + >>::Identification, +); + #[frame_support::pallet] pub mod pallet { use super::*; @@ -53,6 +70,10 @@ pub mod pallet { + scheduler::Config + AuthorityDiscoveryConfig { + /// A type for retrieving `AccountId`s of the validators in the current session. + /// These are stash keys of the validators. + /// It's used for rewards and slashing. `Identification` is only needed for slashing. + type ValidatorSet: ValidatorSetWithIdentification; } /// Assignment keys for the current session. @@ -73,6 +94,14 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn session_info)] pub(crate) type Sessions = StorageMap<_, Identity, SessionIndex, SessionInfo>; + + /// The validator account keys of the validators actively participating in parachain consensus. + // We do not store this in `SessionInfo` to avoid leaking the `AccountId` type to the client, + // which would complicate the migration process if we are to change it in the future. + #[pallet::storage] + #[pallet::getter(fn account_keys)] + pub(crate) type AccountKeys = + StorageMap<_, Identity, SessionIndex, Vec>>; } /// An abstraction for the authority discovery pallet @@ -121,6 +150,9 @@ impl Pallet { if old_earliest_stored_session != 0 || Sessions::::get(0).is_some() { for idx in old_earliest_stored_session..new_earliest_stored_session { Sessions::::remove(&idx); + // Idx will be missing for a few sessions after the runtime upgrade. + // But it shouldn'be be a problem. + AccountKeys::::remove(&idx); } // update `EarliestStoredSession` based on `config.dispute_period` EarliestStoredSession::::set(new_earliest_stored_session); @@ -128,6 +160,13 @@ impl Pallet { // just introduced on a live chain EarliestStoredSession::::set(new_session_index); } + + // The validator set is guaranteed to be of the current session + // because we delay `on_new_session` till the end of the block. + let account_ids = T::ValidatorSet::validators(); + let active_account_ids = take_active_subset(&active_set, &account_ids); + AccountKeys::::insert(&new_session_index, &active_account_ids); + // create a new entry in `Sessions` with information about the current session let new_session_info = SessionInfo { validators, // these are from the notification and are thus already correct. diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs index 179c19bf49..f11d0e20e5 100644 --- a/polkadot/runtime/polkadot/src/lib.rs +++ b/polkadot/runtime/polkadot/src/lib.rs @@ -1238,7 +1238,9 @@ impl parachains_configuration::Config for Runtime { impl parachains_shared::Config for Runtime {} -impl parachains_session_info::Config for Runtime {} +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} impl parachains_inclusion::Config for Runtime { type Event = Event; diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index a43e50addb..2a820d265a 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -603,7 +603,9 @@ impl parachains_paras::Config for Runtime { type NextSessionRotation = Babe; } -impl parachains_session_info::Config for Runtime {} +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} parameter_types! { pub const FirstMessageFactorPercent: u64 = 100; diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index a9f802f136..783c1801a8 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -499,7 +499,9 @@ impl parachains_initializer::Config for Runtime { type WeightInfo = (); } -impl parachains_session_info::Config for Runtime {} +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} parameter_types! { pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 5efaec73a2..b18610ad33 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -852,7 +852,9 @@ impl parachains_configuration::Config for Runtime { impl parachains_shared::Config for Runtime {} -impl parachains_session_info::Config for Runtime {} +impl parachains_session_info::Config for Runtime { + type ValidatorSet = Historical; +} impl parachains_inclusion::Config for Runtime { type Event = Event;