Migrate pallet-session to the new pallet macro (#9796)

* Migrate pallet-session to the new pallet macro

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Remove old macros

Signed-off-by: koushiro <koushiro.cqx@gmail.com>

* Fix

Signed-off-by: koushiro <koushiro.cqx@gmail.com>
This commit is contained in:
Qinxuan Chen
2021-09-28 11:12:57 +08:00
committed by GitHub
parent 6ec82c7a83
commit 7f550d6dd2
15 changed files with 314 additions and 266 deletions
@@ -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<T: Config> ValidatorSet<T::AccountId> for Module<T> {
type ValidatorIdOf = T::ValidatorIdOf;
fn session_index() -> sp_staking::SessionIndex {
super::Module::<T>::current_index()
super::Pallet::<T>::current_index()
}
fn validators() -> Vec<Self::ValidatorId> {
super::Module::<T>::validators()
super::Pallet::<T>::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<Test>;
@@ -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<T: Config> {
validator_set: Vec<IdentificationTuple<T>>,
@@ -142,23 +138,24 @@ pub fn keep_newest<T: Config>(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<Test>;
pub fn new_test_ext() -> sp_io::TestExternalities {
@@ -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).
@@ -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";
+238 -191
View File
@@ -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<T: pallet_session::Config>() -> Vec<<T as pallet_session::Config>::ValidatorId> {
//! <pallet_session::Module<T>>::validators()
//! <pallet_session::Pallet<T>>::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<ValidatorId> {
///
/// 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<ValidatorId> {
fn on_genesis_session<Ks: OpaqueKeys>(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<AId> SessionHandler<AId> for TestSessionHandler {
fn on_disabled(_: usize) {}
}
impl<T: Config> ValidatorRegistration<T::ValidatorId> for Module<T> {
fn is_registered(id: &T::ValidatorId) -> bool {
Self::load_keys(id).is_some()
}
}
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
pub trait Config: frame_system::Config {
/// The overarching event type.
type Event: From<Event> + Into<<Self as frame_system::Config>::Event>;
/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(0);
/// A stable ID for a validator.
type ValidatorId: Member + Parameter + MaxEncodedLen;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(_);
/// A conversion from account ID to validator ID.
///
/// Its cost must be at most one storage read.
type ValidatorIdOf: Convert<Self::AccountId, Option<Self::ValidatorId>>;
#[pallet::config]
pub trait Config: frame_system::Config {
/// The overarching event type.
type Event: From<Event> + IsType<<Self as frame_system::Config>::Event>;
/// Indicator for when to end the session.
type ShouldEndSession: ShouldEndSession<Self::BlockNumber>;
/// A stable ID for a validator.
type ValidatorId: Member + Parameter + MaybeSerializeDeserialize + MaxEncodedLen;
/// 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<Self::BlockNumber>;
/// Handler for managing new session.
type SessionManager: SessionManager<Self::ValidatorId>;
/// Handler when a session has changed.
type SessionHandler: SessionHandler<Self::ValidatorId>;
/// The keys.
type Keys: OpaqueKeys + Member + Parameter + Default;
/// 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<Perbill>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
decl_storage! {
trait Store for Module<T: Config> as Session {
/// The current set of validators.
Validators get(fn validators): Vec<T::ValidatorId>;
/// Current index of the session.
CurrentIndex get(fn current_index): SessionIndex;
/// True if the underlying economic identities or weighting behind the validators
/// has changed in the queued validator set.
QueuedChanged: bool;
/// 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)>;
/// Indices of disabled validators.
/// A conversion from account ID to validator ID.
///
/// The set is cleared when `on_session_ending` returns a new set of identities.
DisabledValidators get(fn disabled_validators): Vec<u32>;
/// Its cost must be at most one storage read.
type ValidatorIdOf: Convert<Self::AccountId, Option<Self::ValidatorId>>;
/// The next session keys for a validator.
NextKeys: map hasher(twox_64_concat) T::ValidatorId => Option<T::Keys>;
/// Indicator for when to end the session.
type ShouldEndSession: ShouldEndSession<Self::BlockNumber>;
/// The owner of a key. The key is the `KeyTypeId` + the encoded key.
KeyOwner: map hasher(twox_64_concat) (KeyTypeId, Vec<u8>) => Option<T::ValidatorId>;
/// 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<Self::BlockNumber>;
/// Handler for managing new session.
type SessionManager: SessionManager<Self::ValidatorId>;
/// Handler when a session has changed.
type SessionHandler: SessionHandler<Self::ValidatorId>;
/// The keys.
type Keys: OpaqueKeys + Member + Parameter + Default + MaybeSerializeDeserialize;
/// 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<Perbill>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
add_extra_genesis {
config(keys): Vec<(T::AccountId, T::ValidatorId, T::Keys)>;
build(|config: &GenesisConfig<T>| {
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub keys: Vec<(T::AccountId, T::ValidatorId, T::Keys)>,
}
#[cfg(feature = "std")]
impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self {
Self { keys: Default::default() }
}
}
#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
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() {
<Module<T>>::inner_set_keys(&val, keys)
for (account, val, keys) in self.keys.iter().cloned() {
<Pallet<T>>::inner_set_keys(&val, keys)
.expect("genesis config must not contain duplicates; qed");
if frame_system::Pallet::<T>::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(),
<Module<T>>::load_keys(&v).unwrap_or_default(),
))
.map(|v| (v.clone(), <Pallet<T>>::load_keys(&v).unwrap_or_default()))
.collect();
// Tell everyone about the genesis session keys
@@ -485,21 +488,62 @@ decl_storage! {
<QueuedKeys<T>>::put(queued_keys);
T::SessionManager::start_session(0);
});
}
}
}
decl_event!(
/// The current set of validators.
#[pallet::storage]
#[pallet::getter(fn validators)]
pub type Validators<T: Config> = StorageValue<_, Vec<T::ValidatorId>, ValueQuery>;
/// Current index of the session.
#[pallet::storage]
#[pallet::getter(fn current_index)]
pub type CurrentIndex<T> = 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<T> = 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<T: Config> = 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<T> = StorageValue<_, Vec<u32>, ValueQuery>;
/// The next session keys for a validator.
#[pallet::storage]
pub type NextKeys<T: Config> =
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<T: Config> =
StorageMap<_, Twox64Concat, (KeyTypeId, Vec<u8>), 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<T: Config> {
/// 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<T> {
/// Invalid ownership proof.
InvalidProof,
/// No associated validator ID for account.
@@ -511,57 +555,9 @@ decl_error! {
/// Key setting account is not live, so it's impossible to associate keys.
NoAccount,
}
}
decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::Origin {
type Error = Error<T>;
fn deposit_event() = default;
/// 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.
///
/// The dispatch origin of this function must be signed.
///
/// # <weight>
/// - 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>
#[weight = T::WeightInfo::set_keys()]
pub fn set_keys(origin, keys: T::Keys, proof: Vec<u8>) -> dispatch::DispatchResult {
let who = ensure_signed(origin)?;
ensure!(keys.ownership_proof_is_valid(&proof), Error::<T>::InvalidProof);
Self::do_set_keys(&who, keys)?;
Ok(())
}
/// Removes any session key(s) of the function caller.
/// This doesn't take effect until the next session.
///
/// The dispatch origin of this function must be signed.
///
/// # <weight>
/// - 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>
#[weight = T::WeightInfo::purge_keys()]
pub fn purge_keys(origin) {
let who = ensure_signed(origin)?;
Self::do_purge_keys(&who)?;
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
/// 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 {
@@ -576,17 +572,62 @@ decl_module! {
}
}
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// 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.
///
/// The dispatch origin of this function must be signed.
///
/// # <weight>
/// - 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>
#[pallet::weight(T::WeightInfo::set_keys())]
pub fn set_keys(origin: OriginFor<T>, keys: T::Keys, proof: Vec<u8>) -> DispatchResult {
let who = ensure_signed(origin)?;
ensure!(keys.ownership_proof_is_valid(&proof), Error::<T>::InvalidProof);
Self::do_set_keys(&who, keys)?;
Ok(())
}
/// Removes any session key(s) of the function caller.
/// This doesn't take effect until the next session.
///
/// The dispatch origin of this function must be signed.
///
/// # <weight>
/// - 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>
#[pallet::weight(T::WeightInfo::purge_keys())]
pub fn purge_keys(origin: OriginFor<T>) -> DispatchResult {
let who = ensure_signed(origin)?;
Self::do_purge_keys(&who)?;
Ok(())
}
}
}
impl<T: Config> Module<T> {
impl<T: Config> Pallet<T> {
/// 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 = <CurrentIndex<T>>::get();
log::trace!(target: "runtime::session", "rotating session {:?}", session_index);
let changed = QueuedChanged::get();
let changed = <QueuedChanged<T>>::get();
// Inform the session handlers that a session is going to end.
T::SessionHandler::on_before_session_ending();
@@ -600,12 +641,12 @@ impl<T: Config> Module<T> {
if changed {
// reset disabled validators
DisabledValidators::take();
<DisabledValidators<T>>::take();
}
// Increment session index.
let session_index = session_index + 1;
CurrentIndex::put(session_index);
<CurrentIndex<T>>::put(session_index);
T::SessionManager::start_session(session_index);
@@ -655,7 +696,7 @@ impl<T: Config> Module<T> {
};
<QueuedKeys<T>>::put(queued_amalgamated.clone());
QueuedChanged::put(next_changed);
<QueuedChanged<T>>::put(next_changed);
// Record that this happened.
Self::deposit_event(Event::NewSession(session_index));
@@ -669,7 +710,7 @@ impl<T: Config> Module<T> {
/// 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) = <DisabledValidators<T>>::mutate(|disabled| {
let i = i as u32;
if let Err(index) = disabled.binary_search(&i) {
let count = <Validators<T>>::decode_len().unwrap_or(0) as u32;
@@ -688,12 +729,12 @@ impl<T: Config> Module<T> {
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<bool, ()> {
Self::validators()
.iter()
@@ -711,7 +752,7 @@ impl<T: Config> Module<T> {
///
/// 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<T: Config> Module<T> {
///
/// 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::<T>::NoAssociatedValidatorId)?;
@@ -850,16 +891,40 @@ impl<T: Config> Module<T> {
}
}
impl<T: Config> ValidatorSet<T::AccountId> for Module<T> {
impl<T: Config> ValidatorRegistration<T::ValidatorId> for Pallet<T> {
fn is_registered(id: &T::ValidatorId) -> bool {
Self::load_keys(id).is_some()
}
}
impl<T: Config> ValidatorSet<T::AccountId> for Pallet<T> {
type ValidatorId = T::ValidatorId;
type ValidatorIdOf = T::ValidatorIdOf;
fn session_index() -> sp_staking::SessionIndex {
Module::<T>::current_index()
Pallet::<T>::current_index()
}
fn validators() -> Vec<Self::ValidatorId> {
Module::<T>::validators()
Pallet::<T>::validators()
}
}
impl<T: Config> EstimateNextNewSession<T::BlockNumber> for Pallet<T> {
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<T::BlockNumber>, Weight) {
T::NextSessionRotation::estimate_next_session_rotation(now)
}
}
impl<T: Config> frame_support::traits::DisabledValidators for Pallet<T> {
fn is_disabled(index: u32) -> bool {
<Pallet<T>>::disabled_validators().binary_search(&index).is_ok()
}
}
@@ -877,25 +942,7 @@ impl<T: Config, Inner: FindAuthor<u32>> FindAuthor<T::ValidatorId>
{
let i = Inner::find_author(digests)?;
let validators = <Module<T>>::validators();
let validators = <Pallet<T>>::validators();
validators.get(i as usize).map(|k| k.clone())
}
}
impl<T: Config> EstimateNextNewSession<T::BlockNumber> for Module<T> {
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<T::BlockNumber>, Weight) {
T::NextSessionRotation::estimate_next_session_rotation(now)
}
}
impl<T: Config> frame_support::traits::DisabledValidators for Module<T> {
fn is_disabled(index: u32) -> bool {
<Module<T>>::disabled_validators().binary_search(&index).is_ok()
}
}
+5 -2
View File
@@ -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 {
+5 -3
View File
@@ -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);