From 03c2c2fe44b405c4b84561cc2c65e5cf7d2c263a Mon Sep 17 00:00:00 2001 From: Qinxuan Chen Date: Tue, 28 Sep 2021 11:12:57 +0800 Subject: [PATCH] Migrate `pallet-session` to the new pallet macro (#9796) * Migrate pallet-session to the new pallet macro Signed-off-by: koushiro * Remove old macros Signed-off-by: koushiro * Fix Signed-off-by: koushiro --- frame/beefy-mmr/src/mock.rs | 3 +- frame/beefy/src/mock.rs | 3 +- frame/session/Cargo.toml | 24 +- frame/session/README.md | 8 +- frame/session/benchmarking/Cargo.toml | 28 +- frame/session/benchmarking/src/lib.rs | 6 +- frame/session/src/historical/mod.rs | 12 +- frame/session/src/historical/offchain.rs | 29 +- frame/session/src/historical/onchain.rs | 10 +- frame/session/src/historical/shared.rs | 2 +- frame/session/src/lib.rs | 377 +++++++++++++---------- frame/session/src/mock.rs | 7 +- frame/session/src/tests.rs | 8 +- frame/staking/src/mock.rs | 3 +- frame/staking/src/tests.rs | 2 +- 15 files changed, 285 insertions(+), 237 deletions(-) diff --git a/frame/beefy-mmr/src/mock.rs b/frame/beefy-mmr/src/mock.rs index a8d136b192aec..4c9e103eb7b82 100644 --- a/frame/beefy-mmr/src/mock.rs +++ b/frame/beefy-mmr/src/mock.rs @@ -19,7 +19,8 @@ use std::vec; use beefy_primitives::mmr::MmrLeafVersion; use frame_support::{ - construct_runtime, parameter_types, sp_io::TestExternalities, BasicExternalities, + construct_runtime, parameter_types, sp_io::TestExternalities, traits::GenesisBuild, + BasicExternalities, }; use sp_core::{Hasher, H256}; use sp_runtime::{ diff --git a/frame/beefy/src/mock.rs b/frame/beefy/src/mock.rs index 696d0d972e70c..baa2fae746fe3 100644 --- a/frame/beefy/src/mock.rs +++ b/frame/beefy/src/mock.rs @@ -18,7 +18,8 @@ use std::vec; use frame_support::{ - construct_runtime, parameter_types, sp_io::TestExternalities, BasicExternalities, + construct_runtime, parameter_types, sp_io::TestExternalities, traits::GenesisBuild, + BasicExternalities, }; use sp_core::H256; use sp_runtime::{ diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index 8f07de2e7a6db..3d2de5339543e 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -13,38 +13,40 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ - "derive", -] } +log = { version = "0.4.0", default-features = false } +impl-trait-for-tuples = "0.2.1" + +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } scale-info = { version = "1.0", default-features = false, features = ["derive"] } -sp-core = { version = "4.0.0-dev", default-features = false, path = "../../primitives/core" } + sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-core = { version = "4.0.0-dev", default-features = false, path = "../../primitives/core" } sp-io = { version = "4.0.0-dev", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" } sp-session = { version = "4.0.0-dev", default-features = false, path = "../../primitives/session" } sp-staking = { version = "4.0.0-dev", default-features = false, path = "../../primitives/staking" } +sp-trie = { version = "4.0.0-dev", default-features = false, path = "../../primitives/trie", optional = true } + frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } pallet-timestamp = { version = "4.0.0-dev", default-features = false, path = "../timestamp" } -sp-trie = { version = "4.0.0-dev", optional = true, default-features = false, path = "../../primitives/trie" } -log = { version = "0.4.0", default-features = false } -impl-trait-for-tuples = "0.2.1" [features] default = ["std", "historical"] historical = ["sp-trie"] std = [ + "log/std", "codec/std", "scale-info/std", "sp-std/std", - "sp-io/std", - "frame-support/std", "sp-core/std", + "sp-io/std", "sp-runtime/std", "sp-session/std", "sp-staking/std", - "pallet-timestamp/std", "sp-trie/std", - "log/std", + "frame-support/std", + "frame-system/std", + "pallet-timestamp/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/frame/session/README.md b/frame/session/README.md index c47b5610de09c..09132470d4433 100644 --- a/frame/session/README.md +++ b/frame/session/README.md @@ -1,11 +1,11 @@ -# Session Module +# Session Pallet The Session module allows validators to manage their session keys, provides a function for changing the session length, and handles session rotation. - [`session::Trait`](https://docs.rs/pallet-session/latest/pallet_session/trait.Config.html) - [`Call`](https://docs.rs/pallet-session/latest/pallet_session/enum.Call.html) -- [`Module`](https://docs.rs/pallet-session/latest/pallet_session/struct.Module.html) +- [`Pallet`](https://docs.rs/pallet-session/latest/pallet_session/struct.Pallet.html) ## Overview @@ -72,11 +72,11 @@ The [Staking pallet](https://docs.rs/pallet-staking/latest/pallet_staking/) uses use pallet_session as session; fn validators() -> Vec<::ValidatorId> { - >::validators() + >::validators() } ``` -## Related Modules +## Related Pallets - [Staking](https://docs.rs/pallet-staking/latest/pallet_staking/) diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index cc242085bf5e4..a24d4a1173ab1 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -13,39 +13,37 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-session = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/session" } -sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +rand = { version = "0.7.2", default-features = false } + sp-std = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/std" } -frame-system = { version = "4.0.0-dev", default-features = false, path = "../../system" } +sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +sp-session = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/session" } + frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../../benchmarking" } frame-support = { version = "4.0.0-dev", default-features = false, path = "../../support" } -pallet-staking = { version = "4.0.0-dev", default-features = false, features = [ - "runtime-benchmarks", -], path = "../../staking" } +frame-system = { version = "4.0.0-dev", default-features = false, path = "../../system" } pallet-session = { version = "4.0.0-dev", default-features = false, path = "../../session" } -rand = { version = "0.7.2", default-features = false } +pallet-staking = { version = "4.0.0-dev", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } [dev-dependencies] -codec = { package = "parity-scale-codec", version = "2.0.0", features = [ - "derive", -] } +codec = { package = "parity-scale-codec", version = "2.0.0", features = ["derive"] } scale-info = "1.0" sp-core = { version = "4.0.0-dev", path = "../../../primitives/core" } -pallet-staking-reward-curve = { version = "4.0.0-dev", path = "../../staking/reward-curve" } sp-io = { version = "4.0.0-dev", path = "../../../primitives/io" } -pallet-timestamp = { version = "4.0.0-dev", path = "../../timestamp" } pallet-balances = { version = "4.0.0-dev", path = "../../balances" } +pallet-timestamp = { version = "4.0.0-dev", path = "../../timestamp" } +pallet-staking-reward-curve = { version = "4.0.0-dev", path = "../../staking/reward-curve" } frame-election-provider-support = { version = "4.0.0-dev", path = "../../election-provider-support" } [features] default = ["std"] std = [ "sp-std/std", - "sp-session/std", "sp-runtime/std", - "frame-system/std", + "sp-session/std", "frame-benchmarking/std", "frame-support/std", - "pallet-staking/std", + "frame-system/std", "pallet-session/std", + "pallet-staking/std", ] diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index 8b84145c1acfd..c0131957c8732 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -30,7 +30,7 @@ use frame_support::{ traits::{KeyOwnerProofSystem, OnInitialize}, }; use frame_system::RawOrigin; -use pallet_session::{historical::Module as Historical, Module as Session, *}; +use pallet_session::{historical::Module as Historical, Pallet as Session, *}; use pallet_staking::{ benchmarking::create_validator_with_nominators, testing_utils::create_validators, RewardDestination, @@ -39,7 +39,7 @@ use sp_runtime::traits::{One, StaticLookup}; const MAX_VALIDATORS: u32 = 1000; -pub struct Pallet(pallet_session::Module); +pub struct Pallet(pallet_session::Pallet); pub trait Config: pallet_session::Config + pallet_session::historical::Config + pallet_staking::Config { @@ -47,7 +47,7 @@ pub trait Config: impl OnInitialize for Pallet { fn on_initialize(n: T::BlockNumber) -> frame_support::weights::Weight { - pallet_session::Module::::on_initialize(n) + pallet_session::Pallet::::on_initialize(n) } } diff --git a/frame/session/src/historical/mod.rs b/frame/session/src/historical/mod.rs index c9b13e3c7f262..0801b2aca1701 100644 --- a/frame/session/src/historical/mod.rs +++ b/frame/session/src/historical/mod.rs @@ -26,7 +26,7 @@ //! These roots and proofs of inclusion can be generated at any time during the current session. //! Afterwards, the proofs can be fed to a consensus module when reporting misbehavior. -use super::{Module as SessionModule, SessionIndex}; +use super::{Pallet as SessionModule, SessionIndex}; use codec::{Decode, Encode}; use frame_support::{ decl_module, decl_storage, print, @@ -114,11 +114,11 @@ impl ValidatorSet for Module { type ValidatorIdOf = T::ValidatorIdOf; fn session_index() -> sp_staking::SessionIndex { - super::Module::::current_index() + super::Pallet::::current_index() } fn validators() -> Vec { - super::Module::::validators() + super::Pallet::::validators() } } @@ -366,11 +366,13 @@ pub(crate) mod tests { use crate::mock::{ force_new_session, set_next_validators, Session, System, Test, NEXT_VALIDATORS, }; + + use sp_runtime::{key_types::DUMMY, testing::UintAuthorityId}; + use frame_support::{ - traits::{KeyOwnerProofSystem, OnInitialize}, + traits::{GenesisBuild, KeyOwnerProofSystem, OnInitialize}, BasicExternalities, }; - use sp_runtime::{key_types::DUMMY, testing::UintAuthorityId}; type Historical = Module; diff --git a/frame/session/src/historical/offchain.rs b/frame/session/src/historical/offchain.rs index 8583c2bb439be..b646ecc2764f7 100644 --- a/frame/session/src/historical/offchain.rs +++ b/frame/session/src/historical/offchain.rs @@ -30,15 +30,11 @@ use sp_runtime::{ KeyTypeId, }; use sp_session::MembershipProof; - -use super::{ - super::{Pallet as SessionModule, SessionIndex}, - Config, IdentificationTuple, ProvingTrie, -}; - -use super::shared; use sp_std::prelude::*; +use super::{shared, Config, IdentificationTuple, ProvingTrie}; +use crate::{Pallet as SessionModule, SessionIndex}; + /// A set of validators, which was used for a fixed session index. struct ValidatorSet { validator_set: Vec>, @@ -142,23 +138,24 @@ pub fn keep_newest(n_to_keep: usize) { #[cfg(test)] mod tests { - use super::{ - super::{onchain, Module}, - *, - }; - use crate::mock::{ - force_new_session, set_next_validators, Session, System, Test, NEXT_VALIDATORS, + use super::*; + use crate::{ + historical::{onchain, Module}, + mock::{force_new_session, set_next_validators, Session, System, Test, NEXT_VALIDATORS}, }; + use codec::Encode; - use frame_support::traits::{KeyOwnerProofSystem, OnInitialize}; use sp_core::{ crypto::key_types::DUMMY, offchain::{testing::TestOffchainExt, OffchainDbExt, OffchainWorkerExt, StorageKind}, }; - - use frame_support::BasicExternalities; use sp_runtime::testing::UintAuthorityId; + use frame_support::{ + traits::{GenesisBuild, KeyOwnerProofSystem, OnInitialize}, + BasicExternalities, + }; + type Historical = Module; pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/frame/session/src/historical/onchain.rs b/frame/session/src/historical/onchain.rs index 514e343f4e0f6..c80817c28d723 100644 --- a/frame/session/src/historical/onchain.rs +++ b/frame/session/src/historical/onchain.rs @@ -19,15 +19,11 @@ use codec::Encode; use sp_runtime::traits::Convert; - -use super::{ - super::{Config as SessionConfig, Pallet as SessionModule, SessionIndex}, - Config as HistoricalConfig, -}; - -use super::shared; use sp_std::prelude::*; +use super::{shared, Config as HistoricalConfig}; +use crate::{Config as SessionConfig, Pallet as SessionModule, SessionIndex}; + /// Store the validator-set associated to the `session_index` to the off-chain database. /// /// Further processing is then done [`off-chain side`](super::offchain). diff --git a/frame/session/src/historical/shared.rs b/frame/session/src/historical/shared.rs index e801aa80eef4c..182e9ecacee19 100644 --- a/frame/session/src/historical/shared.rs +++ b/frame/session/src/historical/shared.rs @@ -18,8 +18,8 @@ //! Shared logic between on-chain and off-chain components used for slashing using an off-chain //! worker. -use super::SessionIndex; use codec::Encode; +use sp_staking::SessionIndex; use sp_std::prelude::*; pub(super) const PREFIX: &[u8] = b"session_historical"; diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index e57decec8c651..2742d302ce439 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -15,14 +15,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Session Module +//! # Session Pallet //! -//! The Session module allows validators to manage their session keys, provides a function for +//! The Session pallet allows validators to manage their session keys, provides a function for //! changing the session length, and handles session rotation. //! //! - [`Config`] //! - [`Call`] -//! - [`Module`] +//! - [`Pallet`] //! //! ## Overview //! @@ -95,12 +95,12 @@ //! use pallet_session as session; //! //! fn validators() -> Vec<::ValidatorId> { -//! >::validators() +//! >::validators() //! } //! # fn main(){} //! ``` //! -//! ## Related Modules +//! ## Related Pallets //! //! - [Staking](../pallet_staking/index.html) @@ -114,22 +114,9 @@ mod mock; mod tests; pub mod weights; -use codec::{Decode, MaxEncodedLen}; -use frame_support::{ - decl_error, decl_event, decl_module, decl_storage, - dispatch::{self, DispatchError, DispatchResult}, - ensure, - traits::{ - EstimateNextNewSession, EstimateNextSessionRotation, FindAuthor, Get, OneSessionHandler, - ValidatorRegistration, ValidatorSet, - }, - weights::Weight, - ConsensusEngineId, Parameter, -}; -use frame_system::ensure_signed; use sp_runtime::{ traits::{AtLeast32BitUnsigned, Convert, Member, One, OpaqueKeys, Zero}, - KeyTypeId, Perbill, Permill, RuntimeAppPublic, + ConsensusEngineId, KeyTypeId, Perbill, Permill, RuntimeAppPublic, }; use sp_staking::SessionIndex; use sp_std::{ @@ -137,6 +124,20 @@ use sp_std::{ ops::{Rem, Sub}, prelude::*, }; + +use frame_support::{ + codec::{Decode, MaxEncodedLen}, + dispatch::{DispatchError, DispatchResult}, + ensure, + traits::{ + EstimateNextNewSession, EstimateNextSessionRotation, FindAuthor, Get, OneSessionHandler, + StorageVersion, ValidatorRegistration, ValidatorSet, + }, + weights::Weight, + Parameter, +}; + +pub use pallet::*; pub use weights::WeightInfo; /// Decides whether the session should be ended. @@ -228,7 +229,7 @@ pub trait SessionManager { /// /// Even if the validator-set is the same as before, if any underlying economic conditions have /// changed (i.e. stake-weights), the new validator set must be returned. This is necessary for - /// consensus engines making use of the session module to issue a validator-set change so + /// consensus engines making use of the session pallet to issue a validator-set change so /// misbehavior can be provably associated with the new economic conditions as opposed to the /// old. The returned validator set, if any, will not be applied until `new_index`. `new_index` /// is strictly greater than from previous call. @@ -280,7 +281,7 @@ pub trait SessionHandler { fn on_genesis_session(validators: &[(ValidatorId, Ks)]); /// Session set has changed; act appropriately. Note that this can be called - /// before initialization of your module. + /// before initialization of your pallet. /// /// `changed` is true whenever any of the session keys or underlying economic /// identities or weightings behind those keys has changed. @@ -356,86 +357,83 @@ impl SessionHandler for TestSessionHandler { fn on_disabled(_: usize) {} } -impl ValidatorRegistration for Module { - fn is_registered(id: &T::ValidatorId) -> bool { - Self::load_keys(id).is_some() - } -} - -pub trait Config: frame_system::Config { - /// The overarching event type. - type Event: From + Into<::Event>; +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; - /// A stable ID for a validator. - type ValidatorId: Member + Parameter + MaxEncodedLen; + /// The current storage version. + const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); - /// A conversion from account ID to validator ID. - /// - /// Its cost must be at most one storage read. - type ValidatorIdOf: Convert>; - - /// Indicator for when to end the session. - type ShouldEndSession: ShouldEndSession; - - /// Something that can predict the next session rotation. This should typically come from the - /// same logical unit that provides [`ShouldEndSession`], yet, it gives a best effort estimate. - /// It is helpful to implement [`EstimateNextNewSession`]. - type NextSessionRotation: EstimateNextSessionRotation; - - /// Handler for managing new session. - type SessionManager: SessionManager; + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); - /// Handler when a session has changed. - type SessionHandler: SessionHandler; + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type Event: From + IsType<::Event>; - /// The keys. - type Keys: OpaqueKeys + Member + Parameter + Default; + /// A stable ID for a validator. + type ValidatorId: Member + Parameter + MaybeSerializeDeserialize + MaxEncodedLen; - /// The fraction of validators set that is safe to be disabled. - /// - /// After the threshold is reached `disabled` method starts to return true, - /// which in combination with `pallet_staking` forces a new era. - type DisabledValidatorsThreshold: Get; + /// A conversion from account ID to validator ID. + /// + /// Its cost must be at most one storage read. + type ValidatorIdOf: Convert>; - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; -} + /// Indicator for when to end the session. + type ShouldEndSession: ShouldEndSession; -decl_storage! { - trait Store for Module as Session { - /// The current set of validators. - Validators get(fn validators): Vec; + /// Something that can predict the next session rotation. This should typically come from + /// the same logical unit that provides [`ShouldEndSession`], yet, it gives a best effort + /// estimate. It is helpful to implement [`EstimateNextNewSession`]. + type NextSessionRotation: EstimateNextSessionRotation; - /// Current index of the session. - CurrentIndex get(fn current_index): SessionIndex; + /// Handler for managing new session. + type SessionManager: SessionManager; - /// True if the underlying economic identities or weighting behind the validators - /// has changed in the queued validator set. - QueuedChanged: bool; + /// Handler when a session has changed. + type SessionHandler: SessionHandler; - /// The queued keys for the next session. When the next session begins, these keys - /// will be used to determine the validator's session keys. - QueuedKeys get(fn queued_keys): Vec<(T::ValidatorId, T::Keys)>; + /// The keys. + type Keys: OpaqueKeys + Member + Parameter + Default + MaybeSerializeDeserialize; - /// Indices of disabled validators. + /// The fraction of validators set that is safe to be disabled. /// - /// The set is cleared when `on_session_ending` returns a new set of identities. - DisabledValidators get(fn disabled_validators): Vec; + /// After the threshold is reached `disabled` method starts to return true, + /// which in combination with `pallet_staking` forces a new era. + type DisabledValidatorsThreshold: Get; - /// The next session keys for a validator. - NextKeys: map hasher(twox_64_concat) T::ValidatorId => Option; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub keys: Vec<(T::AccountId, T::ValidatorId, T::Keys)>, + } - /// The owner of a key. The key is the `KeyTypeId` + the encoded key. - KeyOwner: map hasher(twox_64_concat) (KeyTypeId, Vec) => Option; + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self { keys: Default::default() } + } } - add_extra_genesis { - config(keys): Vec<(T::AccountId, T::ValidatorId, T::Keys)>; - build(|config: &GenesisConfig| { + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { if T::SessionHandler::KEY_TYPE_IDS.len() != T::Keys::key_ids().len() { panic!("Number of keys in session handler and session keys does not match"); } - T::SessionHandler::KEY_TYPE_IDS.iter().zip(T::Keys::key_ids()).enumerate() + T::SessionHandler::KEY_TYPE_IDS + .iter() + .zip(T::Keys::key_ids()) + .enumerate() .for_each(|(i, (sk, kk))| { if sk != kk { panic!( @@ -445,8 +443,8 @@ decl_storage! { } }); - for (account, val, keys) in config.keys.iter().cloned() { - >::inner_set_keys(&val, keys) + for (account, val, keys) in self.keys.iter().cloned() { + >::inner_set_keys(&val, keys) .expect("genesis config must not contain duplicates; qed"); if frame_system::Pallet::::inc_consumers(&account).is_err() { // This will leak a provider reference, however it only happens once (at @@ -457,25 +455,30 @@ decl_storage! { } } - let initial_validators_0 = T::SessionManager::new_session_genesis(0) - .unwrap_or_else(|| { - frame_support::print("No initial validator provided by `SessionManager`, use \ - session config keys to generate initial validator set."); - config.keys.iter().map(|x| x.1.clone()).collect() + let initial_validators_0 = + T::SessionManager::new_session_genesis(0).unwrap_or_else(|| { + frame_support::print( + "No initial validator provided by `SessionManager`, use \ + session config keys to generate initial validator set.", + ); + self.keys.iter().map(|x| x.1.clone()).collect() }); - assert!(!initial_validators_0.is_empty(), "Empty validator set for session 0 in genesis block!"); + assert!( + !initial_validators_0.is_empty(), + "Empty validator set for session 0 in genesis block!" + ); let initial_validators_1 = T::SessionManager::new_session_genesis(1) .unwrap_or_else(|| initial_validators_0.clone()); - assert!(!initial_validators_1.is_empty(), "Empty validator set for session 1 in genesis block!"); + assert!( + !initial_validators_1.is_empty(), + "Empty validator set for session 1 in genesis block!" + ); let queued_keys: Vec<_> = initial_validators_1 .iter() .cloned() - .map(|v| ( - v.clone(), - >::load_keys(&v).unwrap_or_default(), - )) + .map(|v| (v.clone(), >::load_keys(&v).unwrap_or_default())) .collect(); // Tell everyone about the genesis session keys @@ -485,21 +488,62 @@ decl_storage! { >::put(queued_keys); T::SessionManager::start_session(0); - }); + } } -} -decl_event!( + /// The current set of validators. + #[pallet::storage] + #[pallet::getter(fn validators)] + pub type Validators = StorageValue<_, Vec, ValueQuery>; + + /// Current index of the session. + #[pallet::storage] + #[pallet::getter(fn current_index)] + pub type CurrentIndex = StorageValue<_, SessionIndex, ValueQuery>; + + /// True if the underlying economic identities or weighting behind the validators + /// has changed in the queued validator set. + #[pallet::storage] + pub type QueuedChanged = StorageValue<_, bool, ValueQuery>; + + /// The queued keys for the next session. When the next session begins, these keys + /// will be used to determine the validator's session keys. + #[pallet::storage] + #[pallet::getter(fn queued_keys)] + pub type QueuedKeys = StorageValue<_, Vec<(T::ValidatorId, T::Keys)>, ValueQuery>; + + /// Indices of disabled validators. + /// + /// The set is cleared when `on_session_ending` returns a new set of identities. + #[pallet::storage] + #[pallet::getter(fn disabled_validators)] + pub type DisabledValidators = StorageValue<_, Vec, ValueQuery>; + + /// The next session keys for a validator. + #[pallet::storage] + pub type NextKeys = + StorageMap<_, Twox64Concat, T::ValidatorId, T::Keys, OptionQuery>; + + /// The owner of a key. The key is the `KeyTypeId` + the encoded key. + #[pallet::storage] + pub type KeyOwner = + StorageMap<_, Twox64Concat, (KeyTypeId, Vec), T::ValidatorId, OptionQuery>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// New session has happened. Note that the argument is the \[session_index\], not the /// block number as the type might suggest. NewSession(SessionIndex), } -); -decl_error! { - /// Error for the session module. - pub enum Error for Module { + /// Old name generated by `decl_event`. + #[deprecated(note = "use `Event` instead")] + pub type RawEvent = Event; + + /// Error for the session pallet. + #[pallet::error] + pub enum Error { /// Invalid ownership proof. InvalidProof, /// No associated validator ID for account. @@ -511,14 +555,26 @@ decl_error! { /// Key setting account is not live, so it's impossible to associate keys. NoAccount, } -} -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - type Error = Error; - - fn deposit_event() = default; + #[pallet::hooks] + impl Hooks> for Pallet { + /// Called when a block is initialized. Will rotate session if it is the last + /// block of the current session. + fn on_initialize(n: T::BlockNumber) -> Weight { + if T::ShouldEndSession::should_end_session(n) { + Self::rotate_session(); + T::BlockWeights::get().max_block + } else { + // NOTE: the non-database part of the weight for `should_end_session(n)` is + // included as weight for empty block, the database part is expected to be in + // cache. + 0 + } + } + } + #[pallet::call] + impl Pallet { /// Sets the session key(s) of the function caller to `keys`. /// Allows an account to set its session key prior to becoming a validator. /// This doesn't take effect until the next session. @@ -526,21 +582,19 @@ decl_module! { /// The dispatch origin of this function must be signed. /// /// # - /// - Complexity: `O(1)` - /// Actual cost depends on the number of length of `T::Keys::key_ids()` which is fixed. + /// - Complexity: `O(1)`. Actual cost depends on the number of length of + /// `T::Keys::key_ids()` which is fixed. /// - DbReads: `origin account`, `T::ValidatorIdOf`, `NextKeys` /// - DbWrites: `origin account`, `NextKeys` /// - DbReads per key id: `KeyOwner` /// - DbWrites per key id: `KeyOwner` /// # - #[weight = T::WeightInfo::set_keys()] - pub fn set_keys(origin, keys: T::Keys, proof: Vec) -> dispatch::DispatchResult { + #[pallet::weight(T::WeightInfo::set_keys())] + pub fn set_keys(origin: OriginFor, keys: T::Keys, proof: Vec) -> DispatchResult { let who = ensure_signed(origin)?; - ensure!(keys.ownership_proof_is_valid(&proof), Error::::InvalidProof); Self::do_set_keys(&who, keys)?; - Ok(()) } @@ -550,43 +604,30 @@ decl_module! { /// The dispatch origin of this function must be signed. /// /// # - /// - Complexity: `O(1)` in number of key types. - /// Actual cost depends on the number of length of `T::Keys::key_ids()` which is fixed. + /// - Complexity: `O(1)` in number of key types. Actual cost depends on the number of length + /// of `T::Keys::key_ids()` which is fixed. /// - DbReads: `T::ValidatorIdOf`, `NextKeys`, `origin account` /// - DbWrites: `NextKeys`, `origin account` /// - DbWrites per key id: `KeyOwner` /// # - #[weight = T::WeightInfo::purge_keys()] - pub fn purge_keys(origin) { + #[pallet::weight(T::WeightInfo::purge_keys())] + pub fn purge_keys(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; Self::do_purge_keys(&who)?; - } - - /// Called when a block is initialized. Will rotate session if it is the last - /// block of the current session. - fn on_initialize(n: T::BlockNumber) -> Weight { - if T::ShouldEndSession::should_end_session(n) { - Self::rotate_session(); - T::BlockWeights::get().max_block - } else { - // NOTE: the non-database part of the weight for `should_end_session(n)` is - // included as weight for empty block, the database part is expected to be in - // cache. - 0 - } + Ok(()) } } } -impl Module { +impl Pallet { /// Move on to next session. Register new validator set and session keys. Changes to the /// validator set have a session of delay to take effect. This allows for equivocation /// punishment after a fork. pub fn rotate_session() { - let session_index = CurrentIndex::get(); + let session_index = >::get(); log::trace!(target: "runtime::session", "rotating session {:?}", session_index); - let changed = QueuedChanged::get(); + let changed = >::get(); // Inform the session handlers that a session is going to end. T::SessionHandler::on_before_session_ending(); @@ -600,12 +641,12 @@ impl Module { if changed { // reset disabled validators - DisabledValidators::take(); + >::take(); } // Increment session index. let session_index = session_index + 1; - CurrentIndex::put(session_index); + >::put(session_index); T::SessionManager::start_session(session_index); @@ -655,7 +696,7 @@ impl Module { }; >::put(queued_amalgamated.clone()); - QueuedChanged::put(next_changed); + >::put(next_changed); // Record that this happened. Self::deposit_event(Event::NewSession(session_index)); @@ -669,7 +710,7 @@ impl Module { /// Returns `true` if this causes a `DisabledValidatorsThreshold` of validators /// to be already disabled. pub fn disable_index(i: usize) -> bool { - let (fire_event, threshold_reached) = DisabledValidators::mutate(|disabled| { + let (fire_event, threshold_reached) = >::mutate(|disabled| { let i = i as u32; if let Err(index) = disabled.binary_search(&i) { let count = >::decode_len().unwrap_or(0) as u32; @@ -688,12 +729,12 @@ impl Module { threshold_reached } - /// Disable the validator identified by `c`. (If using with the staking module, + /// Disable the validator identified by `c`. (If using with the staking pallet, /// this would be their *stash* account.) /// /// Returns `Ok(true)` if more than `DisabledValidatorsThreshold` validators in current /// session is already disabled. - /// If used with the staking module it allows to force a new era in such case. + /// If used with the staking pallet it allows to force a new era in such case. pub fn disable(c: &T::ValidatorId) -> sp_std::result::Result { Self::validators() .iter() @@ -711,7 +752,7 @@ impl Module { /// /// Care should be taken that the raw versions of the /// added keys are unique for every `ValidatorId, KeyTypeId` combination. - /// This is an invariant that the session module typically maintains internally. + /// This is an invariant that the session pallet typically maintains internally. /// /// As the actual values of the keys are typically not known at runtime upgrade, /// it's recommended to initialize the keys to a (unique) dummy value with the expectation @@ -756,7 +797,7 @@ impl Module { /// /// This ensures that the reference counter in system is incremented appropriately and as such /// must accept an account ID, rather than a validator ID. - fn do_set_keys(account: &T::AccountId, keys: T::Keys) -> dispatch::DispatchResult { + fn do_set_keys(account: &T::AccountId, keys: T::Keys) -> DispatchResult { let who = T::ValidatorIdOf::convert(account.clone()) .ok_or(Error::::NoAssociatedValidatorId)?; @@ -850,16 +891,40 @@ impl Module { } } -impl ValidatorSet for Module { +impl ValidatorRegistration for Pallet { + fn is_registered(id: &T::ValidatorId) -> bool { + Self::load_keys(id).is_some() + } +} + +impl ValidatorSet for Pallet { type ValidatorId = T::ValidatorId; type ValidatorIdOf = T::ValidatorIdOf; fn session_index() -> sp_staking::SessionIndex { - Module::::current_index() + Pallet::::current_index() } fn validators() -> Vec { - Module::::validators() + Pallet::::validators() + } +} + +impl EstimateNextNewSession for Pallet { + fn average_session_length() -> T::BlockNumber { + T::NextSessionRotation::average_session_length() + } + + /// This session pallet always calls new_session and next_session at the same time, hence we + /// do a simple proxy and pass the function to next rotation. + fn estimate_next_new_session(now: T::BlockNumber) -> (Option, Weight) { + T::NextSessionRotation::estimate_next_session_rotation(now) + } +} + +impl frame_support::traits::DisabledValidators for Pallet { + fn is_disabled(index: u32) -> bool { + >::disabled_validators().binary_search(&index).is_ok() } } @@ -877,25 +942,7 @@ impl> FindAuthor { let i = Inner::find_author(digests)?; - let validators = >::validators(); + let validators = >::validators(); validators.get(i as usize).map(|k| k.clone()) } } - -impl EstimateNextNewSession for Module { - fn average_session_length() -> T::BlockNumber { - T::NextSessionRotation::average_session_length() - } - - /// This session module always calls new_session and next_session at the same time, hence we - /// do a simple proxy and pass the function to next rotation. - fn estimate_next_new_session(now: T::BlockNumber) -> (Option, Weight) { - T::NextSessionRotation::estimate_next_session_rotation(now) - } -} - -impl frame_support::traits::DisabledValidators for Module { - fn is_disabled(index: u32) -> bool { - >::disabled_validators().binary_search(&index).is_ok() - } -} diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 449acaff5305d..c6b5f64448114 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -21,7 +21,9 @@ use super::*; use crate as pallet_session; #[cfg(feature = "historical")] use crate::historical as pallet_session_historical; -use frame_support::{parameter_types, BasicExternalities}; + +use std::cell::RefCell; + use sp_core::{crypto::key_types::DUMMY, H256}; use sp_runtime::{ impl_opaque_keys, @@ -30,7 +32,8 @@ use sp_runtime::{ Perbill, }; use sp_staking::SessionIndex; -use std::cell::RefCell; + +use frame_support::{parameter_types, traits::GenesisBuild, BasicExternalities}; impl_opaque_keys! { pub struct MockSessionKeys { diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index 23e1c6a993427..47152042d204f 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -18,17 +18,19 @@ // Tests for the Session Pallet use super::*; -use codec::Decode; -use frame_support::{assert_noop, assert_ok, traits::OnInitialize}; -use mock::{ +use crate::mock::{ authorities, before_session_end_called, force_new_session, new_test_ext, reset_before_session_end_called, session_changed, set_next_validators, set_session_length, Origin, PreUpgradeMockSessionKeys, Session, System, Test, SESSION_CHANGED, TEST_SESSION_CHANGED, }; + +use codec::Decode; use sp_core::crypto::key_types::DUMMY; use sp_runtime::testing::UintAuthorityId; +use frame_support::{assert_noop, assert_ok, traits::OnInitialize}; + fn initialize_block(block: u64) { SESSION_CHANGED.with(|l| *l.borrow_mut() = false); System::set_block_number(block); diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index b3ce8e063cb61..06c9be9c01e11 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -22,8 +22,7 @@ use frame_election_provider_support::{onchain, SortedListProvider}; use frame_support::{ assert_ok, parameter_types, traits::{ - Currency, FindAuthor, GenesisBuild, Get, Hooks, Imbalance, OnInitialize, OnUnbalanced, - OneSessionHandler, + Currency, FindAuthor, GenesisBuild, Get, Hooks, Imbalance, OnUnbalanced, OneSessionHandler, }, weights::constants::RocksDbWeight, }; diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 38b760896d7d8..6f024eb1e6b04 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -23,7 +23,7 @@ use frame_support::{ assert_noop, assert_ok, dispatch::WithPostDispatchInfo, pallet_prelude::*, - traits::{Currency, Get, OnInitialize, ReservableCurrency}, + traits::{Currency, Get, ReservableCurrency}, weights::{extract_actual_weight, GetDispatchInfo}, }; use mock::*;