From 2ae0c018ff6bf03b9e5c8ae26ef0cc4860b9b390 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 19 Apr 2021 21:39:35 -0400 Subject: [PATCH 01/32] update pallet --- frame/aura/src/lib.rs | 49 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index a9b91737235ae..d731e30ea67c7 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -37,10 +37,14 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::prelude::*; +use sp_std::{ + prelude::*, + convert::TryInto, +}; use codec::{Encode, Decode}; use frame_support::{ - Parameter, traits::{Get, FindAuthor, OneSessionHandler, OnTimestampSet}, ConsensusEngineId, + Parameter, BoundedVec, ConsensusEngineId, + traits::{Get, FindAuthor, OneSessionHandler, OnTimestampSet}, }; use sp_runtime::{ RuntimeAppPublic, @@ -64,11 +68,21 @@ pub mod pallet { pub trait Config: pallet_timestamp::Config + frame_system::Config { /// The identifier type for an authority. type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + MaybeSerializeDeserialize; + + /// The maximum number of authorities that can be registered in this pallet. + type MaxAuthorities: Get; } #[pallet::pallet] pub struct Pallet(sp_std::marker::PhantomData); + // Errors inform users that something went wrong. + #[pallet::error] + pub enum Error { + /// You are trying to add more authorities than allowed in the pallet configuration. + TooManyAuthorities, + } + #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_: T::BlockNumber) -> Weight { @@ -93,7 +107,11 @@ pub mod pallet { /// The current authority set. #[pallet::storage] #[pallet::getter(fn authorities)] - pub(super) type Authorities = StorageValue<_, Vec, ValueQuery>; + pub(super) type Authorities = StorageValue< + _, + BoundedVec, + ValueQuery, + >; /// The current slot of this block. /// @@ -123,12 +141,12 @@ pub mod pallet { } impl Pallet { - fn change_authorities(new: Vec) { + fn change_authorities(new: BoundedVec) { >::put(&new); let log: DigestItem = DigestItem::Consensus( AURA_ENGINE_ID, - ConsensusLog::AuthoritiesChange(new).encode() + ConsensusLog::AuthoritiesChange(new.to_vec()).encode() ); >::deposit_log(log.into()); } @@ -136,7 +154,11 @@ impl Pallet { fn initialize_authorities(authorities: &[T::AuthorityId]) { if !authorities.is_empty() { assert!(>::get().is_empty(), "Authorities are already initialized!"); - >::put(authorities); + let bounded_authorities: BoundedVec = authorities + .to_vec() + .try_into() + .expect("Too many initial authorities!"); + >::put(&bounded_authorities); } } @@ -180,10 +202,19 @@ impl OneSessionHandler for Pallet { { // instant changes if changed { - let next_authorities = validators.map(|(_, k)| k).collect::>(); + let next_authorities = validators + .map(|(_, k)| k) + // Only take a number of authorities that would fit in the set. + .take(T::MaxAuthorities::get() as usize) + .collect::>(); + let bounded_next_authorities = BoundedVec::::force_from( + next_authorities, + Some("Aura Authority Change"), + ); + let last_authorities = Self::authorities(); - if next_authorities != last_authorities { - Self::change_authorities(next_authorities); + if bounded_next_authorities != last_authorities { + Self::change_authorities(bounded_next_authorities); } } } From fb14e4082ed33b80f3b87e843803babb583f3d20 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 19 Apr 2021 21:39:45 -0400 Subject: [PATCH 02/32] update and add tests --- frame/aura/src/mock.rs | 5 +++++ frame/aura/src/tests.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 26d5a2754974f..b41d5ad0656f6 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -80,8 +80,13 @@ impl pallet_timestamp::Config for Test { type WeightInfo = (); } +parameter_types! { + pub const MaxAuthorities: u32 = 10; +} + impl pallet_aura::Config for Test { type AuthorityId = AuthorityId; + type MaxAuthorities = MaxAuthorities; } pub fn new_test_ext(authorities: Vec) -> sp_io::TestExternalities { diff --git a/frame/aura/src/tests.rs b/frame/aura/src/tests.rs index 18e14e802bd32..9f4a01e81945c 100644 --- a/frame/aura/src/tests.rs +++ b/frame/aura/src/tests.rs @@ -20,6 +20,8 @@ #![cfg(test)] use crate::mock::{Aura, new_test_ext}; +use sp_runtime::testing::UintAuthorityId; +use frame_support::traits::OneSessionHandler; #[test] fn initial_values() { @@ -28,3 +30,30 @@ fn initial_values() { assert_eq!(Aura::authorities().len(), 4); }); } + +// Should not be able to put more authorities than allowed in genesis. +#[test] +#[should_panic(expected = "Too many initial authorities!")] +fn too_many_initial_fails() { + new_test_ext((0..100).collect::>()); +} + +// Session change should truncate the new authorities to fit into the limits +// of the Aura pallet. +#[test] +fn session_change_truncates() { + new_test_ext(vec![0, 1, 2, 3]).execute_with(|| { + Aura::on_new_session( + true, + (0..100) + .map(|x| { + let auth_id = UintAuthorityId(x).to_public_key(); + (&0, auth_id) + }) + .collect::>() + .into_iter(), + vec![].into_iter(), + ); + assert_eq!(Aura::authorities().len(), 10); + }); +} From fcf8809012c5c6b6d053f921eee0653739169679 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 19 Apr 2021 21:40:09 -0400 Subject: [PATCH 03/32] Fix typo `One` -> `On` --- frame/aura/src/lib.rs | 4 ++-- frame/aura/src/tests.rs | 2 +- frame/authority-discovery/src/lib.rs | 14 +++++++------- frame/babe/src/lib.rs | 4 ++-- frame/babe/src/mock.rs | 2 +- frame/grandpa/src/lib.rs | 4 ++-- frame/grandpa/src/mock.rs | 2 +- frame/grandpa/src/tests.rs | 2 +- frame/im-online/src/lib.rs | 4 ++-- frame/session/src/lib.rs | 4 ++-- frame/staking/src/mock.rs | 4 ++-- frame/support/src/traits.rs | 2 +- frame/support/src/traits/validation.rs | 2 +- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index d731e30ea67c7..daa57aabb1e49 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -44,7 +44,7 @@ use sp_std::{ use codec::{Encode, Decode}; use frame_support::{ Parameter, BoundedVec, ConsensusEngineId, - traits::{Get, FindAuthor, OneSessionHandler, OnTimestampSet}, + traits::{Get, FindAuthor, OnSessionHandler, OnTimestampSet}, }; use sp_runtime::{ RuntimeAppPublic, @@ -187,7 +187,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = T::AuthorityId; } -impl OneSessionHandler for Pallet { +impl OnSessionHandler for Pallet { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) diff --git a/frame/aura/src/tests.rs b/frame/aura/src/tests.rs index 9f4a01e81945c..42f678558be62 100644 --- a/frame/aura/src/tests.rs +++ b/frame/aura/src/tests.rs @@ -21,7 +21,7 @@ use crate::mock::{Aura, new_test_ext}; use sp_runtime::testing::UintAuthorityId; -use frame_support::traits::OneSessionHandler; +use frame_support::traits::OnSessionHandler; #[test] fn initial_values() { diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 6b7608b10c3bd..fb62bc4c74156 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -24,7 +24,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::prelude::*; -use frame_support::traits::OneSessionHandler; +use frame_support::traits::OnSessionHandler; #[cfg(feature = "std")] use frame_support::traits::GenesisBuild; use sp_authority_discovery::AuthorityId; @@ -53,7 +53,7 @@ pub mod pallet { Vec, ValueQuery, >; - + #[pallet::storage] #[pallet::getter(fn next_keys)] /// Keys of the next authority set. @@ -127,7 +127,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = AuthorityId; } -impl OneSessionHandler for Pallet { +impl OnSessionHandler for Pallet { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(authorities: I) @@ -275,7 +275,7 @@ mod tests { #[test] fn authorities_returns_current_and_next_authority_set() { // The whole authority discovery pallet ignores account ids, but we still need them for - // `pallet_session::OneSessionHandler::on_new_session`, thus its safe to use the same value + // `pallet_session::OnSessionHandler::on_new_session`, thus its safe to use the same value // everywhere. let account_id = AuthorityPair::from_seed_slice(vec![10; 32].as_ref()).unwrap().public(); @@ -288,7 +288,7 @@ mod tests { .map(|i| AuthorityPair::from_seed_slice(vec![i; 32].as_ref()).unwrap().public()) .map(AuthorityId::from) .collect(); - // Needed for `pallet_session::OneSessionHandler::on_new_session`. + // Needed for `pallet_session::OnSessionHandler::on_new_session`. let second_authorities_and_account_ids = second_authorities.clone() .into_iter() .map(|id| (&account_id, id)) @@ -298,7 +298,7 @@ mod tests { .map(|i| AuthorityPair::from_seed_slice(vec![i; 32].as_ref()).unwrap().public()) .map(AuthorityId::from) .collect(); - // Needed for `pallet_session::OneSessionHandler::on_new_session`. + // Needed for `pallet_session::OnSessionHandler::on_new_session`. let third_authorities_and_account_ids = third_authorities.clone() .into_iter() .map(|id| (&account_id, id)) @@ -319,7 +319,7 @@ mod tests { let mut externalities = TestExternalities::new(t); externalities.execute_with(|| { - use frame_support::traits::OneSessionHandler; + use frame_support::traits::OnSessionHandler; AuthorityDiscovery::on_genesis_session( first_authorities.iter().map(|id| (id, id.clone())) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index fb1e32e5350b5..fdebb3f014386 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -24,7 +24,7 @@ use codec::{Decode, Encode}; use frame_support::{ dispatch::DispatchResultWithPostInfo, - traits::{FindAuthor, Get, KeyOwnerProofSystem, OneSessionHandler, OnTimestampSet}, + traits::{FindAuthor, Get, KeyOwnerProofSystem, OnSessionHandler, OnTimestampSet}, weights::{Pays, Weight}, }; use sp_application_crypto::Public; @@ -868,7 +868,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = AuthorityId; } -impl OneSessionHandler for Pallet { +impl OnSessionHandler for Pallet { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 39831eceb75ba..801c8eb4d1efa 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -407,7 +407,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec) -> sp_io::Tes .collect(); // NOTE: this will initialize the babe authorities - // through OneSessionHandler::on_genesis_session + // through OnSessionHandler::on_genesis_session pallet_session::GenesisConfig:: { keys: session_keys } .assimilate_storage(&mut t) .unwrap(); diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index eb3dc4f110acb..fe5f43751321c 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -41,7 +41,7 @@ use fg_primitives::{ }; use frame_support::{ decl_error, decl_event, decl_module, decl_storage, dispatch::DispatchResultWithPostInfo, - storage, traits::{OneSessionHandler, KeyOwnerProofSystem}, weights::{Pays, Weight}, Parameter, + storage, traits::{OnSessionHandler, KeyOwnerProofSystem}, weights::{Pays, Weight}, Parameter, }; use frame_system::{ensure_none, ensure_root, ensure_signed}; use sp_runtime::{ @@ -587,7 +587,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl OneSessionHandler for Module +impl OnSessionHandler for Module where T: pallet_session::Config { type Key = AuthorityId; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index d59d0d19d0e87..8d56913896071 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -305,7 +305,7 @@ pub fn new_test_ext_raw_authorities(authorities: AuthorityList) -> sp_io::TestEx .collect(); // NOTE: this will initialize the grandpa authorities - // through OneSessionHandler::on_genesis_session + // through OnSessionHandler::on_genesis_session pallet_session::GenesisConfig:: { keys: session_keys } .assimilate_storage(&mut t) .unwrap(); diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 92d2c6c751a24..14c04c38a2b43 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -25,7 +25,7 @@ use codec::{Decode, Encode}; use fg_primitives::ScheduledChange; use frame_support::{ assert_err, assert_ok, assert_noop, - traits::{Currency, OnFinalize, OneSessionHandler}, + traits::{Currency, OnFinalize, OnSessionHandler}, weights::{GetDispatchInfo, Pays}, }; use frame_system::{EventRecord, Phase}; diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index d8f3fdc854b16..37a9c142d6d72 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -95,7 +95,7 @@ use sp_staking::{ use frame_support::{ decl_error, decl_event, decl_module, decl_storage, traits::{ - EstimateNextSessionRotation, Get, OneSessionHandler, ValidatorSet, + EstimateNextSessionRotation, Get, OnSessionHandler, ValidatorSet, ValidatorSetWithIdentification, }, Parameter, @@ -652,7 +652,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = T::AuthorityId; } -impl OneSessionHandler for Module { +impl OnSessionHandler for Module { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index cbe70598a91b3..345643eec69fc 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -125,7 +125,7 @@ use frame_support::{ ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId, Parameter, traits::{ Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession, - OneSessionHandler, ValidatorSet, + OnSessionHandler, ValidatorSet, }, dispatch::{self, DispatchResult, DispatchError}, weights::Weight, @@ -291,7 +291,7 @@ pub trait SessionHandler { } #[impl_trait_for_tuples::impl_for_tuples(1, 30)] -#[tuple_types_custom_trait_bound(OneSessionHandler)] +#[tuple_types_custom_trait_bound(OnSessionHandler)] impl SessionHandler for Tuple { for_tuples!( const KEY_TYPE_IDS: &'static [KeyTypeId] = &[ #( ::ID ),* ]; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 188eda801095e..39f37709d0150 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -21,7 +21,7 @@ use crate::*; use crate as staking; use frame_support::{ assert_ok, parameter_types, - traits::{Currency, FindAuthor, Get, OnFinalize, OnInitialize, OneSessionHandler}, + traits::{Currency, FindAuthor, Get, OnFinalize, OnInitialize, OnSessionHandler}, weights::constants::RocksDbWeight, IterableStorageMap, StorageDoubleMap, StorageMap, StorageValue, }; @@ -51,7 +51,7 @@ thread_local! { /// Another session handler struct to test on_disabled. pub struct OtherSessionHandler; -impl OneSessionHandler for OtherSessionHandler { +impl OnSessionHandler for OtherSessionHandler { type Key = UintAuthorityId; fn on_genesis_session<'a, I: 'a>(_: I) diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 7ee2b0a56094b..a52131f8d01a6 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -36,7 +36,7 @@ pub use members::{ mod validation; pub use validation::{ - ValidatorSet, ValidatorSetWithIdentification, OneSessionHandler, FindAuthor, VerifySeal, + ValidatorSet, ValidatorSetWithIdentification, OnSessionHandler, FindAuthor, VerifySeal, EstimateNextNewSession, EstimateNextSessionRotation, KeyOwnerProofSystem, ValidatorRegistration, Lateness, }; diff --git a/frame/support/src/traits/validation.rs b/frame/support/src/traits/validation.rs index 900be7bb8e7e2..e013cd68a5efd 100644 --- a/frame/support/src/traits/validation.rs +++ b/frame/support/src/traits/validation.rs @@ -72,7 +72,7 @@ pub trait VerifySeal { } /// A session handler for specific key type. -pub trait OneSessionHandler: BoundToRuntimeAppPublic { +pub trait OnSessionHandler: BoundToRuntimeAppPublic { /// The key type expected. type Key: Decode + Default + RuntimeAppPublic; From 0b21a93a31b15c707f0993f5ac2de20f8f555a81 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 19 Apr 2021 21:51:39 -0400 Subject: [PATCH 04/32] fix node build --- bin/node-template/runtime/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index d72a558e1dd28..24b7c5760eab8 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -201,8 +201,13 @@ impl frame_system::Config for Runtime { type OnSetCode = (); } +parameter_types! { + pub const MaxAuthorities: u64 = 100; +} + impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; + type MaxAuthorities = MaxAuthorities; } impl pallet_grandpa::Config for Runtime { From 530c4a7c890fee49ab9f5720b060e40b57fbd998 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 19 Apr 2021 23:48:50 -0400 Subject: [PATCH 05/32] use types in session handler --- frame/aura/src/lib.rs | 4 ++-- frame/im-online/src/lib.rs | 28 ++++++++++++++++++++------ frame/im-online/src/mock.rs | 11 +++++++--- frame/session/src/lib.rs | 13 +++++++----- frame/session/src/mock.rs | 4 +++- frame/support/src/traits/validation.rs | 2 +- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index daa57aabb1e49..9f6c2b0d5d637 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -187,7 +187,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = T::AuthorityId; } -impl OnSessionHandler for Pallet { +impl OnSessionHandler for Pallet { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -209,7 +209,7 @@ impl OnSessionHandler for Pallet { .collect::>(); let bounded_next_authorities = BoundedVec::::force_from( next_authorities, - Some("Aura Authority Change"), + Some("Aura New Session"), ); let last_authorities = Self::authorities(); diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 37a9c142d6d72..8d4f257db6349 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -98,7 +98,7 @@ use frame_support::{ EstimateNextSessionRotation, Get, OnSessionHandler, ValidatorSet, ValidatorSetWithIdentification, }, - Parameter, + Parameter, BoundedVec, }; use frame_system::{ensure_none, offchain::{SendTransactionTypes, SubmitTransaction}}; pub use weights::WeightInfo; @@ -270,6 +270,9 @@ pub trait Config: SendTransactionTypes> + frame_system::Config { /// multiple pallets send unsigned transactions. type UnsignedPriority: Get; + /// The maximum number of authority keys that can be stored by this pallet. + type MaxAuthorityKeys: Get; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -304,7 +307,7 @@ decl_storage! { HeartbeatAfter get(fn heartbeat_after): T::BlockNumber; /// The current set of keys that may issue a heartbeat. - Keys get(fn keys): Vec; + Keys get(fn keys): BoundedVec; /// For each session index, we keep a mapping of `AuthIndex` to /// `offchain::OpaqueNetworkState`. @@ -638,12 +641,16 @@ impl Module { fn initialize_keys(keys: &[T::AuthorityId]) { if !keys.is_empty() { assert!(Keys::::get().is_empty(), "Keys are already initialized!"); - Keys::::put(keys); + let bounded_keys: BoundedVec = keys + .to_vec() + .try_into() + .expect("Too many initial keys!"); + Keys::::put(bounded_keys); } } #[cfg(test)] - fn set_keys(keys: Vec) { + fn set_keys(keys: BoundedVec) { Keys::::put(&keys) } } @@ -652,7 +659,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = T::AuthorityId; } -impl OnSessionHandler for Module { +impl OnSessionHandler for Module { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -673,7 +680,16 @@ impl OnSessionHandler for Module { >::put(block_number + half_session); // Remember who the authorities are for the new session. - Keys::::put(validators.map(|x| x.1).collect::>()); + let next_validators = validators + .map(|x| x.1) + .take(T::MaxAuthorityKeys::get() as usize) + .collect::>(); + + let bounded_validators = BoundedVec::::force_from( + next_validators, + Some("Im Online New Session"), + ); + Keys::::put(bounded_validators); } fn on_before_session_ending() { diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 4f21012abc510..20dee12f455fd 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -21,9 +21,10 @@ use std::cell::RefCell; -use frame_support::{parameter_types, weights::Weight}; +use frame_support::{parameter_types, weights::Weight, BoundedVec}; use pallet_session::historical as pallet_session_historical; use sp_core::H256; +use sp_std::convert::TryInto; use sp_runtime::testing::{Header, TestXt, UintAuthorityId}; use sp_runtime::traits::{BlakeTwo256, ConvertInto, IdentityLookup}; use sp_runtime::{Perbill, Percent}; @@ -150,6 +151,7 @@ parameter_types! { parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); + pub const MaxValidators: u32 = 10; } impl pallet_session::Config for Runtime { @@ -158,6 +160,7 @@ impl pallet_session::Config for Runtime { type SessionHandler = (ImOnline, ); type ValidatorId = u64; type ValidatorIdOf = ConvertInto; + type MaxValidators = MaxValidators; type Keys = UintAuthorityId; type Event = Event; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; @@ -227,6 +230,7 @@ impl Config for Runtime { type NextSessionRotation = TestNextSessionRotation; type ReportUnresponsiveness = OffenceHandler; type UnsignedPriority = UnsignedPriority; + type MaxAuthorityKeys = MaxValidators; type WeightInfo = (); } @@ -241,7 +245,8 @@ pub fn advance_session() { let now = System::block_number().max(1); System::set_block_number(now + 1); Session::rotate_session(); - let keys = Session::validators().into_iter().map(UintAuthorityId).collect(); - ImOnline::set_keys(keys); + let keys: Vec = Session::validators().into_iter().map(UintAuthorityId).collect(); + let bounded_keys: BoundedVec = keys.try_into().unwrap(); + ImOnline::set_keys(bounded_keys); assert_eq!(Session::current_index(), (now / Period::get()) as u32); } diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 345643eec69fc..53ce5b92a34ed 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -256,7 +256,7 @@ impl SessionManager for () { } /// Handler for session life cycle events. -pub trait SessionHandler { +pub trait SessionHandler { /// All the key type ids this session handler can process. /// /// The order must be the same as it expects them in @@ -291,8 +291,8 @@ pub trait SessionHandler { } #[impl_trait_for_tuples::impl_for_tuples(1, 30)] -#[tuple_types_custom_trait_bound(OnSessionHandler)] -impl SessionHandler for Tuple { +#[tuple_types_custom_trait_bound(OnSessionHandler)] +impl> SessionHandler for Tuple { for_tuples!( const KEY_TYPE_IDS: &'static [KeyTypeId] = &[ #( ::ID ),* ]; ); @@ -338,7 +338,7 @@ impl SessionHandler for Tuple { /// `SessionHandler` for tests that use `UintAuthorityId` as `Keys`. pub struct TestSessionHandler; -impl SessionHandler for TestSessionHandler { +impl> SessionHandler for TestSessionHandler { const KEY_TYPE_IDS: &'static [KeyTypeId] = &[sp_runtime::key_types::DUMMY]; fn on_genesis_session(_: &[(AId, Ks)]) {} @@ -368,6 +368,9 @@ pub trait Config: frame_system::Config { /// Its cost must be at most one storage read. type ValidatorIdOf: Convert>; + /// The maximum number of validators supported by the session handler. + type MaxValidators: Get; + /// Indicator for when to end the session. type ShouldEndSession: ShouldEndSession; @@ -380,7 +383,7 @@ pub trait Config: frame_system::Config { type SessionManager: SessionManager; /// Handler when a session has changed. - type SessionHandler: SessionHandler; + type SessionHandler: SessionHandler; /// The keys. type Keys: OpaqueKeys + Member + Parameter + Default; diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 3459ab73d6afe..a3dbe9fff89dc 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -119,7 +119,7 @@ impl ShouldEndSession for TestShouldEndSession { } pub struct TestSessionHandler; -impl SessionHandler for TestSessionHandler { +impl SessionHandler for TestSessionHandler { const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[UintAuthorityId::ID]; fn on_genesis_session(_validators: &[(u64, T)]) {} fn on_new_session( @@ -262,6 +262,7 @@ impl pallet_timestamp::Config for Test { parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33); + pub const MaxValidators: u32 = 10; } impl Config for Test { @@ -273,6 +274,7 @@ impl Config for Test { type SessionHandler = TestSessionHandler; type ValidatorId = u64; type ValidatorIdOf = ConvertInto; + type MaxValidators = MaxValidators; type Keys = MockSessionKeys; type Event = Event; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; diff --git a/frame/support/src/traits/validation.rs b/frame/support/src/traits/validation.rs index e013cd68a5efd..02ebb05c91cb4 100644 --- a/frame/support/src/traits/validation.rs +++ b/frame/support/src/traits/validation.rs @@ -72,7 +72,7 @@ pub trait VerifySeal { } /// A session handler for specific key type. -pub trait OnSessionHandler: BoundToRuntimeAppPublic { +pub trait OnSessionHandler: BoundToRuntimeAppPublic { /// The key type expected. type Key: Decode + Default + RuntimeAppPublic; From 3885e7acf52d94b6682b2310a33348fd749086f7 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 00:38:22 -0400 Subject: [PATCH 06/32] fix compile --- bin/node-template/runtime/src/lib.rs | 6 ++++-- bin/node/runtime/src/lib.rs | 8 ++++++++ frame/authority-discovery/src/lib.rs | 2 +- frame/babe/src/lib.rs | 5 ++++- frame/grandpa/src/lib.rs | 11 ++++++++--- frame/staking/src/lib.rs | 7 +++++-- test-utils/runtime/src/lib.rs | 3 +++ 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 24b7c5760eab8..cb8a90085aaf4 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -202,7 +202,7 @@ impl frame_system::Config for Runtime { } parameter_types! { - pub const MaxAuthorities: u64 = 100; + pub const MaxAuthorities: u32 = 100; } impl pallet_aura::Config for Runtime { @@ -226,6 +226,8 @@ impl pallet_grandpa::Config for Runtime { type HandleEquivocation = (); + type MaxAuthorities = MaxAuthorities; + type WeightInfo = (); } @@ -399,7 +401,7 @@ impl_runtime_apis! { } fn authorities() -> Vec { - Aura::authorities() + Aura::authorities().to_vec() } } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 648bbff633046..022e4a05accfb 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -332,6 +332,7 @@ parameter_types! { pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; pub const ReportLongevity: u64 = BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); + pub const MaxAuthorities: u32 = 100; } impl pallet_babe::Config for Runtime { @@ -354,6 +355,8 @@ impl pallet_babe::Config for Runtime { type HandleEquivocation = pallet_babe::EquivocationHandler; + type MaxAuthorities = MaxAuthorities; + type WeightInfo = (); } @@ -446,6 +449,7 @@ impl pallet_session::Config for Runtime { type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type MaxValidators = MaxAuthorities; type WeightInfo = pallet_session::weights::SubstrateWeight; } @@ -496,6 +500,7 @@ impl pallet_staking::Config for Runtime { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type ElectionProvider = ElectionProviderMultiPhase; + type MaxValidators = MaxAuthorities; type WeightInfo = pallet_staking::weights::SubstrateWeight; } @@ -891,6 +896,7 @@ impl pallet_im_online::Config for Runtime { type ValidatorSet = Historical; type ReportUnresponsiveness = Offences; type UnsignedPriority = ImOnlineUnsignedPriority; + type MaxAuthorityKeys = MaxAuthorities; type WeightInfo = pallet_im_online::weights::SubstrateWeight; } @@ -925,6 +931,8 @@ impl pallet_grandpa::Config for Runtime { type HandleEquivocation = pallet_grandpa::EquivocationHandler; + type MaxAuthorities = MaxAuthorities; + type WeightInfo = (); } diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index fb62bc4c74156..55b88bc713ee7 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -127,7 +127,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = AuthorityId; } -impl OnSessionHandler for Pallet { +impl OnSessionHandler for Pallet { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(authorities: I) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index fdebb3f014386..ca6e0a0ad7803 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -161,6 +161,9 @@ pub mod pallet { /// definition. type HandleEquivocation: HandleEquivocation; + /// Maximum number of authorities handled by the session manager. + type MaxAuthorities: Get; + type WeightInfo: WeightInfo; } @@ -868,7 +871,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = AuthorityId; } -impl OnSessionHandler for Pallet { +impl OnSessionHandler for Pallet { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index fe5f43751321c..043ef037b5a73 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -40,8 +40,10 @@ use fg_primitives::{ GRANDPA_ENGINE_ID, }; use frame_support::{ - decl_error, decl_event, decl_module, decl_storage, dispatch::DispatchResultWithPostInfo, - storage, traits::{OnSessionHandler, KeyOwnerProofSystem}, weights::{Pays, Weight}, Parameter, + decl_error, decl_event, decl_module, decl_storage, storage, + dispatch::DispatchResultWithPostInfo, + traits::{OnSessionHandler, KeyOwnerProofSystem}, weights::{Pays, Weight}, + pallet_prelude::Get, Parameter, }; use frame_system::{ensure_none, ensure_root, ensure_signed}; use sp_runtime::{ @@ -98,6 +100,9 @@ pub trait Config: frame_system::Config { /// definition. type HandleEquivocation: HandleEquivocation; + /// The maximum number of authorities for the session handler. + type MaxAuthorities: Get; + /// Weights for this pallet. type WeightInfo: WeightInfo; } @@ -587,7 +592,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl OnSessionHandler for Module +impl OnSessionHandler for Module where T: pallet_session::Config { type Key = AuthorityId; diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index c938dceb76e49..9db3d1aac9386 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -648,7 +648,7 @@ impl SessionInterface<::AccountId> for T w FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::SessionHandler: pallet_session::SessionHandler<::AccountId, ::MaxValidators>, T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>>, @@ -785,6 +785,9 @@ pub trait Config: frame_system::Config + SendTransactionTypes> { /// their reward. This used to limit the i/o cost for the nominator payout. type MaxNominatorRewardedPerValidator: Get; + /// The maximum number of validators supported by the session handler and should be selected by the staking system. + type MaxValidators: Get; + /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -2754,7 +2757,7 @@ where FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::SessionHandler: pallet_session::SessionHandler<::AccountId, ::MaxValidators>, T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: Convert< ::AccountId, diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 150bc403732c7..ef2a798596366 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -529,6 +529,7 @@ impl pallet_timestamp::Config for Runtime { parameter_types! { pub const EpochDuration: u64 = 6; pub const ExpectedBlockTime: u64 = 10_000; + pub const MaxAuthorities: u32 = 100; } impl pallet_babe::Config for Runtime { @@ -551,6 +552,8 @@ impl pallet_babe::Config for Runtime { type HandleEquivocation = (); + type MaxAuthorities = MaxAuthorities; + type WeightInfo = (); } From 41e9820417885163c7ee8bc7ef1ef6d2d5e9edfd Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 00:50:15 -0400 Subject: [PATCH 07/32] fix test compile --- frame/authority-discovery/src/lib.rs | 7 ++++++- frame/babe/src/mock.rs | 8 ++++++++ frame/grandpa/src/mock.rs | 5 +++++ frame/staking/src/mock.rs | 9 ++++++++- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 55b88bc713ee7..d6748877a287e 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -211,6 +211,7 @@ mod tests { type ValidatorIdOf = ConvertInto; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type NextSessionRotation = pallet_session::PeriodicSessions; + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -256,8 +257,12 @@ mod tests { type OnSetCode = (); } + parameter_types! { + pub const MaxValidators: u32 = 10; + } + pub struct TestSessionHandler; - impl pallet_session::SessionHandler for TestSessionHandler { + impl pallet_session::SessionHandler for TestSessionHandler { const KEY_TYPE_IDS: &'static [KeyTypeId] = &[key_types::DUMMY]; fn on_new_session( diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 801c8eb4d1efa..0a18295890ce1 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -109,6 +109,10 @@ impl_opaque_keys! { } } +parameter_types! { + pub const MaxValidators: u32 = 10; +} + impl pallet_session::Config for Test { type Event = Event; type ValidatorId = ::AccountId; @@ -119,6 +123,7 @@ impl pallet_session::Config for Test { type SessionHandler = ::KeyTypeIdProviders; type Keys = MockSessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -211,6 +216,7 @@ impl pallet_staking::Config for Test { type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type NextNewSession = Session; type ElectionProvider = onchain::OnChainSequentialPhragmen; + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -251,6 +257,8 @@ impl Config for Test { type HandleEquivocation = super::EquivocationHandler; + type MaxAuthorities = MaxValidators; + type WeightInfo = (); } diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 8d56913896071..a1cb0506938d0 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -112,6 +112,7 @@ parameter_types! { pub const Period: u64 = 1; pub const Offset: u64 = 0; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17); + pub const MaxValidators: u32 = 10; } /// Custom `SessionHandler` since we use `TestSessionKeys` as `Keys`. @@ -125,6 +126,7 @@ impl pallet_session::Config for Test { type SessionHandler = ::KeyTypeIdProviders; type Keys = TestSessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -217,6 +219,7 @@ impl pallet_staking::Config for Test { type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type NextNewSession = Session; type ElectionProvider = onchain::OnChainSequentialPhragmen; + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -253,6 +256,8 @@ impl Config for Test { type HandleEquivocation = super::EquivocationHandler; + type MaxAuthorities = MaxValidators; + type WeightInfo = (); } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 39f37709d0150..6e70927ad83bb 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -51,7 +51,7 @@ thread_local! { /// Another session handler struct to test on_disabled. pub struct OtherSessionHandler; -impl OnSessionHandler for OtherSessionHandler { +impl OnSessionHandler for OtherSessionHandler { type Key = UintAuthorityId; fn on_genesis_session<'a, I: 'a>(_: I) @@ -180,6 +180,7 @@ impl pallet_session::Config for Test { type ValidatorIdOf = crate::StashOf; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type NextSessionRotation = pallet_session::PeriodicSessions; + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -240,6 +241,11 @@ impl onchain::Config for Test { type Accuracy = Perbill; type DataProvider = Staking; } + +parameter_types! { + pub const MaxValidators: u32 = 10; +} + impl Config for Test { const MAX_NOMINATIONS: u32 = 16; type Currency = Balances; @@ -258,6 +264,7 @@ impl Config for Test { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type ElectionProvider = onchain::OnChainSequentialPhragmen; + type MaxValidators = MaxValidators; type WeightInfo = (); } From 307e969abfaf6d993369b5ff0978536b4913b5ef Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 01:02:45 -0400 Subject: [PATCH 08/32] bound authority discovery --- frame/authority-discovery/src/lib.rs | 52 +++++++++++++++++++--------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index d6748877a287e..2313f4c6d6f0d 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -23,10 +23,10 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::prelude::*; -use frame_support::traits::OnSessionHandler; +use sp_std::{prelude::*, convert::TryInto}; +use frame_support::{traits::OnSessionHandler, BoundedVec}; #[cfg(feature = "std")] -use frame_support::traits::GenesisBuild; +use frame_support::traits::{GenesisBuild, Get}; use sp_authority_discovery::AuthorityId; pub use pallet::*; @@ -50,7 +50,7 @@ pub mod pallet { /// Keys of the current authority set. pub(super) type Keys = StorageValue< _, - Vec, + BoundedVec, ValueQuery, >; @@ -59,7 +59,7 @@ pub mod pallet { /// Keys of the next authority set. pub(super) type NextKeys = StorageValue< _, - Vec, + BoundedVec, ValueQuery, >; @@ -79,7 +79,9 @@ pub mod pallet { #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - Pallet::::initialize_keys(&self.keys) + let bounded_keys: BoundedVec:: = + self.keys.clone().try_into().expect("Too many genesis keys!"); + Pallet::::initialize_keys(&bounded_keys) } } @@ -94,8 +96,8 @@ impl Pallet { /// Retrieve authority identifiers of the current and next authority set /// sorted and deduplicated. pub fn authorities() -> Vec { - let mut keys = Keys::::get(); - let next = NextKeys::::get(); + let mut keys = Keys::::get().to_vec(); + let next = NextKeys::::get().to_vec(); keys.extend(next); keys.sort(); @@ -106,19 +108,21 @@ impl Pallet { /// Retrieve authority identifiers of the current authority set in the original order. pub fn current_authorities() -> Vec { - Keys::::get() + Keys::::get().to_vec() } /// Retrieve authority identifiers of the next authority set in the original order. pub fn next_authorities() -> Vec { - NextKeys::::get() + NextKeys::::get().to_vec() } fn initialize_keys(keys: &[AuthorityId]) { if !keys.is_empty() { assert!(Keys::::get().is_empty(), "Keys are already initialized!"); - Keys::::put(keys); - NextKeys::::put(keys); + let bounded_keys: BoundedVec = + keys.to_vec().try_into().expect("Too many initial keys!"); + Keys::::put(&bounded_keys); + NextKeys::::put(&bounded_keys); } } } @@ -143,10 +147,26 @@ impl OnSessionHandler for Pallet { { // Remember who the authorities are for the new and next session. if changed { - let keys = validators.map(|x| x.1); - Keys::::put(keys.collect::>()); - let next_keys = queued_validators.map(|x| x.1); - NextKeys::::put(next_keys.collect::>()); + let keys = validators + .map(|x| x.1) + // Truncate to bounded vec + .take(T::MaxValidators::get() as usize) + .collect::>(); + let bounded_keys = BoundedVec::::force_from( + keys, + Some("Authority Discovery New Session Keys"), + ); + Keys::::put(bounded_keys); + let next_keys = queued_validators + .map(|x| x.1) + // Truncate to bounded vec + .take(T::MaxValidators::get() as usize) + .collect::>(); + let bounded_next_keys = BoundedVec::::force_from( + next_keys, + Some("Authority Discovery New Session Next Keys"), + ); + NextKeys::::put(bounded_next_keys); } } From a8a68cd11437d50a5340e24e852b85e92bac0742 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 01:21:16 -0400 Subject: [PATCH 09/32] bound babe --- frame/babe/src/lib.rs | 42 ++++++++++++++++++++++++++++------------- frame/babe/src/tests.rs | 2 +- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index ca6e0a0ad7803..a03eae7dee482 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -23,6 +23,7 @@ use codec::{Decode, Encode}; use frame_support::{ + BoundedVec, dispatch::DispatchResultWithPostInfo, traits::{FindAuthor, Get, KeyOwnerProofSystem, OnSessionHandler, OnTimestampSet}, weights::{Pays, Weight}, @@ -34,7 +35,7 @@ use sp_runtime::{ ConsensusEngineId, KeyTypeId, Percent, }; use sp_session::{GetSessionNumber, GetValidatorCount}; -use sp_std::prelude::*; +use sp_std::{prelude::*, convert::TryInto}; use sp_consensus_babe::{ digests::{NextConfigDescriptor, NextEpochDescriptor, PreDigest}, @@ -93,7 +94,7 @@ impl EpochChangeTrigger for SameAuthoritiesForever { let authorities = >::authorities(); let next_authorities = authorities.clone(); - >::enact_epoch_change(authorities, next_authorities); + >::enact_epoch_change(authorities.to_vec(), next_authorities.to_vec()); } } } @@ -185,7 +186,11 @@ pub mod pallet { /// Current epoch authorities. #[pallet::storage] #[pallet::getter(fn authorities)] - pub type Authorities = StorageValue<_, Vec<(AuthorityId, BabeAuthorityWeight)>, ValueQuery>; + pub type Authorities = StorageValue< + _, + BoundedVec<(AuthorityId, BabeAuthorityWeight), T::MaxAuthorities>, + ValueQuery, + >; /// The slot at which the first epoch actually started. This is 0 /// until the first block of the chain. @@ -225,9 +230,9 @@ pub mod pallet { /// Next epoch authorities. #[pallet::storage] - pub(super) type NextAuthorities = StorageValue< + pub(super) type NextAuthorities = StorageValue< _, - Vec<(AuthorityId, BabeAuthorityWeight)>, + BoundedVec<(AuthorityId, BabeAuthorityWeight), T::MaxAuthorities>, ValueQuery, >; @@ -521,7 +526,12 @@ impl Pallet { .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); EpochIndex::::put(epoch_index); - Authorities::::put(authorities); + + let bounded_authorities = BoundedVec::<(AuthorityId, BabeAuthorityWeight), T::MaxAuthorities>::force_from( + authorities.into_iter().take(T::MaxAuthorities::get() as usize).collect::>(), + Some("Babe Enact Epoch Change"), + ); + Authorities::::put(bounded_authorities); // Update epoch randomness. let next_epoch_index = epoch_index @@ -534,7 +544,11 @@ impl Pallet { Randomness::::put(randomness); // Update the next epoch authorities. - NextAuthorities::::put(&next_authorities); + let bounded_next_authorities = BoundedVec::<(AuthorityId, BabeAuthorityWeight), T::MaxAuthorities>::force_from( + next_authorities.into_iter().take(T::MaxAuthorities::get() as usize).collect::>(), + Some("Babe Enact Epoch Change"), + ); + NextAuthorities::::put(&bounded_next_authorities); // Update the start blocks of the previous and new current epoch. >::mutate(|(previous_epoch_start_block, current_epoch_start_block)| { @@ -547,7 +561,7 @@ impl Pallet { let next_randomness = NextRandomness::::get(); let next_epoch = NextEpochDescriptor { - authorities: next_authorities, + authorities: bounded_next_authorities.to_vec(), randomness: next_randomness, }; Self::deposit_consensus(ConsensusLog::NextEpochData(next_epoch)); @@ -578,7 +592,7 @@ impl Pallet { epoch_index: EpochIndex::::get(), start_slot: Self::current_epoch_start(), duration: T::EpochDuration::get(), - authorities: Self::authorities(), + authorities: Self::authorities().to_vec(), randomness: Self::randomness(), config: EpochConfig::::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed"), } @@ -596,7 +610,7 @@ impl Pallet { epoch_index: next_epoch_index, start_slot: Self::epoch_start(next_epoch_index), duration: T::EpochDuration::get(), - authorities: NextAuthorities::::get(), + authorities: NextAuthorities::::get().to_vec(), randomness: NextRandomness::::get(), config: NextEpochConfig::::get().unwrap_or_else(|| { EpochConfig::::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed") @@ -670,7 +684,7 @@ impl Pallet { // we use the same values as genesis because we haven't collected any // randomness yet. let next = NextEpochDescriptor { - authorities: Self::authorities(), + authorities: Self::authorities().to_vec(), randomness: Self::randomness(), }; @@ -752,8 +766,10 @@ impl Pallet { fn initialize_authorities(authorities: &[(AuthorityId, BabeAuthorityWeight)]) { if !authorities.is_empty() { assert!(Authorities::::get().is_empty(), "Authorities are already initialized!"); - Authorities::::put(authorities); - NextAuthorities::::put(authorities); + let bounded_authorities: BoundedVec<(AuthorityId, BabeAuthorityWeight), T::MaxAuthorities> = + authorities.to_vec().try_into().expect("Too many initial authorities!"); + Authorities::::put(&bounded_authorities); + NextAuthorities::::put(&bounded_authorities); } } diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 6aa80e9697339..75b6189518817 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -104,7 +104,7 @@ fn first_block_epoch_zero_start() { let consensus_log = sp_consensus_babe::ConsensusLog::NextEpochData( sp_consensus_babe::digests::NextEpochDescriptor { - authorities: Babe::authorities(), + authorities: Babe::authorities().to_vec(), randomness: Babe::randomness(), } ); From 6359f643e2cda506a7aabb448ae25611704b18d1 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 01:27:29 -0400 Subject: [PATCH 10/32] some compile fixes --- bin/node/runtime/src/lib.rs | 2 +- frame/authority-discovery/src/lib.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 022e4a05accfb..b5ef6a1dde0cb 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1302,7 +1302,7 @@ impl_runtime_apis! { slot_duration: Babe::slot_duration(), epoch_length: EpochDuration::get(), c: BABE_GENESIS_EPOCH_CONFIG.c, - genesis_authorities: Babe::authorities(), + genesis_authorities: Babe::authorities().to_vec(), randomness: Babe::randomness(), allowed_slots: BABE_GENESIS_EPOCH_CONFIG.allowed_slots, } diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 2313f4c6d6f0d..a026464249ec2 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -24,9 +24,9 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::{prelude::*, convert::TryInto}; -use frame_support::{traits::OnSessionHandler, BoundedVec}; +use frame_support::{traits::{OnSessionHandler, Get}, BoundedVec}; #[cfg(feature = "std")] -use frame_support::traits::{GenesisBuild, Get}; +use frame_support::traits::GenesisBuild; use sp_authority_discovery::AuthorityId; pub use pallet::*; From 8f6ae0c55a3c4635713d17da0b403e9e735b00e0 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 01:38:52 -0400 Subject: [PATCH 11/32] fix session benchmark compile --- frame/session/benchmarking/src/mock.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index cf2fa8a07cfe0..145f26a84ac20 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -103,7 +103,7 @@ sp_runtime::impl_opaque_keys! { } pub struct TestSessionHandler; -impl pallet_session::SessionHandler for TestSessionHandler { +impl pallet_session::SessionHandler for TestSessionHandler { const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[]; fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} @@ -117,6 +117,9 @@ impl pallet_session::SessionHandler for TestSessionHandler { fn on_disabled(_: usize) {} } +parameter_types! { + pub const MaxValidators: u32 = 10; +} impl pallet_session::Config for Test { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type Keys = SessionKeys; @@ -127,6 +130,7 @@ impl pallet_session::Config for Test { type ValidatorId = AccountId; type ValidatorIdOf = pallet_staking::StashOf; type DisabledValidatorsThreshold = (); + type MaxValidators = MaxValidators; type WeightInfo = (); } pallet_staking_reward_curve::build! { @@ -181,6 +185,7 @@ impl pallet_staking::Config for Test { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type ElectionProvider = onchain::OnChainSequentialPhragmen; + type MaxValidators = MaxValidators; type WeightInfo = (); } From 5d748193a6ff488550a88d1defe2464ca8d3269e Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 01:41:41 -0400 Subject: [PATCH 12/32] make pallet offences benchmarks compile --- frame/offences/benchmarking/src/mock.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index a0a09e0fbb897..f01544728f404 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -101,7 +101,7 @@ sp_runtime::impl_opaque_keys! { } pub struct TestSessionHandler; -impl pallet_session::SessionHandler for TestSessionHandler { +impl pallet_session::SessionHandler for TestSessionHandler { const KEY_TYPE_IDS: &'static [sp_runtime::KeyTypeId] = &[]; fn on_genesis_session(_validators: &[(AccountId, Ks)]) {} @@ -118,6 +118,7 @@ impl pallet_session::SessionHandler for TestSessionHandler { parameter_types! { pub const Period: u64 = 1; pub const Offset: u64 = 0; + pub const MaxValidators: u32 = 10; } impl pallet_session::Config for Test { @@ -130,6 +131,7 @@ impl pallet_session::Config for Test { type ValidatorId = AccountId; type ValidatorIdOf = pallet_staking::StashOf; type DisabledValidatorsThreshold = (); + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -176,6 +178,7 @@ impl pallet_staking::Config for Test { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type ElectionProvider = onchain::OnChainSequentialPhragmen; + type MaxValidators = MaxValidators; type WeightInfo = (); } @@ -186,6 +189,7 @@ impl pallet_im_online::Config for Test { type NextSessionRotation = pallet_session::PeriodicSessions; type ReportUnresponsiveness = Offences; type UnsignedPriority = (); + type MaxAuthorityKeys = MaxValidators; type WeightInfo = (); } From 78799984bdd01aa3c476be00cc1ca12d6aa0ba7b Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 02:14:49 -0400 Subject: [PATCH 13/32] fix benchmark --- frame/im-online/src/benchmarking.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/frame/im-online/src/benchmarking.rs b/frame/im-online/src/benchmarking.rs index 287a2c6fd3a73..6fa1864aecf20 100644 --- a/frame/im-online/src/benchmarking.rs +++ b/frame/im-online/src/benchmarking.rs @@ -31,17 +31,18 @@ use frame_support::traits::UnfilteredDispatchable; use crate::Module as ImOnline; -const MAX_KEYS: u32 = 1000; const MAX_EXTERNAL_ADDRESSES: u32 = 100; pub fn create_heartbeat(k: u32, e: u32) -> Result<(crate::Heartbeat, ::Signature), &'static str> { let mut keys = Vec::new(); + assert!(k <= T::MaxAuthorityKeys::get(), "Trying to add too many keys!"); for _ in 0..k { keys.push(T::AuthorityId::generate_pair(None)); } - Keys::::put(keys.clone()); + let bounded_keys: BoundedVec::<_, T::MaxAuthorityKeys> = keys.try_into().unwrap(); + Keys::::put(&bounded_keys); let network_state = OpaqueNetworkState { peer_id: OpaquePeerId::default(), @@ -52,11 +53,11 @@ pub fn create_heartbeat(k: u32, e: u32) -> network_state, session_index: 0, authority_index: k-1, - validators_len: keys.len() as u32, + validators_len: bounded_keys.len() as u32, }; let encoded_heartbeat = input_heartbeat.encode(); - let authority_id = keys.get((k-1) as usize).ok_or("out of range")?; + let authority_id = bounded_keys.get((k-1) as usize).ok_or("out of range")?; let signature = authority_id.sign(&encoded_heartbeat).ok_or("couldn't make signature")?; Ok((input_heartbeat, signature)) @@ -65,14 +66,14 @@ pub fn create_heartbeat(k: u32, e: u32) -> benchmarks! { #[extra] heartbeat { - let k in 1 .. MAX_KEYS; + let k in 1 .. T::MaxAuthorityKeys::get(); let e in 1 .. MAX_EXTERNAL_ADDRESSES; let (input_heartbeat, signature) = create_heartbeat::(k, e)?; }: _(RawOrigin::None, input_heartbeat, signature) #[extra] validate_unsigned { - let k in 1 .. MAX_KEYS; + let k in 1 .. T::MaxAuthorityKeys::get(); let e in 1 .. MAX_EXTERNAL_ADDRESSES; let (input_heartbeat, signature) = create_heartbeat::(k, e)?; let call = Call::heartbeat(input_heartbeat, signature); @@ -81,7 +82,7 @@ benchmarks! { } validate_unsigned_and_then_heartbeat { - let k in 1 .. MAX_KEYS; + let k in 1 .. T::MaxAuthorityKeys::get(); let e in 1 .. MAX_EXTERNAL_ADDRESSES; let (input_heartbeat, signature) = create_heartbeat::(k, e)?; let call = Call::heartbeat(input_heartbeat, signature); From 5383e004c64f5cf91a9cba5c9ef04f9c4cd6a093 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 02:20:36 -0400 Subject: [PATCH 14/32] line width stuff --- frame/babe/src/lib.rs | 10 ++++++++-- frame/staking/src/lib.rs | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index a03eae7dee482..fd57441bfc045 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -527,7 +527,10 @@ impl Pallet { EpochIndex::::put(epoch_index); - let bounded_authorities = BoundedVec::<(AuthorityId, BabeAuthorityWeight), T::MaxAuthorities>::force_from( + let bounded_authorities = BoundedVec::< + (AuthorityId, BabeAuthorityWeight), + T::MaxAuthorities, + >::force_from( authorities.into_iter().take(T::MaxAuthorities::get() as usize).collect::>(), Some("Babe Enact Epoch Change"), ); @@ -544,7 +547,10 @@ impl Pallet { Randomness::::put(randomness); // Update the next epoch authorities. - let bounded_next_authorities = BoundedVec::<(AuthorityId, BabeAuthorityWeight), T::MaxAuthorities>::force_from( + let bounded_next_authorities = BoundedVec::< + (AuthorityId, BabeAuthorityWeight), + T::MaxAuthorities, + >::force_from( next_authorities.into_iter().take(T::MaxAuthorities::get() as usize).collect::>(), Some("Babe Enact Epoch Change"), ); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 9db3d1aac9386..60907fcafe124 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -648,7 +648,10 @@ impl SessionInterface<::AccountId> for T w FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId, ::MaxValidators>, + T::SessionHandler: pallet_session::SessionHandler< + ::AccountId, + ::MaxValidators, + >, T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>>, @@ -2757,7 +2760,10 @@ where FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId, ::MaxValidators>, + T::SessionHandler: pallet_session::SessionHandler< + ::AccountId, + ::MaxValidators, + >, T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: Convert< ::AccountId, From f9491e2c15365bf9308980f951f780e0019719de Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 20 Apr 2021 16:45:08 +0200 Subject: [PATCH 15/32] add truncating_from --- frame/support/src/storage/bounded_vec.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/frame/support/src/storage/bounded_vec.rs b/frame/support/src/storage/bounded_vec.rs index 9fcfe4035294f..ddc4aeb48a1df 100644 --- a/frame/support/src/storage/bounded_vec.rs +++ b/frame/support/src/storage/bounded_vec.rs @@ -65,6 +65,21 @@ impl> BoundedVec { Self(t, Default::default()) } + /// Create self from `t` in a lossy way. In case too many items exist, a log with the given + /// scope is emitted and `t` is truncated to fit the size. + fn truncating_from(mut t: Vec, scope: Option<&'static str>) -> Self { + if t.len() > Self::bound() { + log::warn!( + target: crate::LOG_TARGET, + "length of a bounded vector in scope {} is not respected. Truncating...", + scope.unwrap_or("UNKNOWN"), + ); + t.truncate(Self::bound()) + } + + Self::unchecked_from(t) + } + /// Create `Self` from `t` without any checks. Logs warnings if the bound is not being /// respected. The additional scope can be used to indicate where a potential overflow is /// happening. @@ -76,7 +91,7 @@ impl> BoundedVec { if t.len() > Self::bound() { log::warn!( target: crate::LOG_TARGET, - "length of a bounded vector in scope {} is not respected.", + "length of a bounded vector in scope {} is not respected. Forcing...", scope.unwrap_or("UNKNOWN"), ); } @@ -467,4 +482,10 @@ pub mod test { assert_eq!(bounded.len(), 7); assert!(bounded.try_mutate(|v| v.push(8)).is_none()); } + + #[test] + fn truncating_from_works() { + let bounded = BoundedVec::truncating_from(vec![1, 2, 3, 4, 5, 6]) + assert_eq!(*bounded, vec![1, 2, 3, 4]); + } } From 64bd953174cc234ee4acf87a9d7dcb53f7b54bf1 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 20 Apr 2021 16:46:31 +0200 Subject: [PATCH 16/32] make pub --- frame/support/src/storage/bounded_vec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/support/src/storage/bounded_vec.rs b/frame/support/src/storage/bounded_vec.rs index ddc4aeb48a1df..b642c55dc15f3 100644 --- a/frame/support/src/storage/bounded_vec.rs +++ b/frame/support/src/storage/bounded_vec.rs @@ -67,7 +67,7 @@ impl> BoundedVec { /// Create self from `t` in a lossy way. In case too many items exist, a log with the given /// scope is emitted and `t` is truncated to fit the size. - fn truncating_from(mut t: Vec, scope: Option<&'static str>) -> Self { + pub fn truncating_from(mut t: Vec, scope: Option<&'static str>) -> Self { if t.len() > Self::bound() { log::warn!( target: crate::LOG_TARGET, @@ -485,7 +485,7 @@ pub mod test { #[test] fn truncating_from_works() { - let bounded = BoundedVec::truncating_from(vec![1, 2, 3, 4, 5, 6]) + let bounded = BoundedVec::::truncating_from(vec![1, 2, 3, 4, 5, 6]); assert_eq!(*bounded, vec![1, 2, 3, 4]); } } From a9ba4ebac5fc2eac54ab0a3c1ee1da4230fb8f2f Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 20 Apr 2021 16:47:00 +0200 Subject: [PATCH 17/32] Fix --- frame/support/src/storage/bounded_vec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/src/storage/bounded_vec.rs b/frame/support/src/storage/bounded_vec.rs index b642c55dc15f3..17e79b9f747f3 100644 --- a/frame/support/src/storage/bounded_vec.rs +++ b/frame/support/src/storage/bounded_vec.rs @@ -485,7 +485,7 @@ pub mod test { #[test] fn truncating_from_works() { - let bounded = BoundedVec::::truncating_from(vec![1, 2, 3, 4, 5, 6]); + let bounded = BoundedVec::::truncating_from(vec![1, 2, 3, 4, 5, 6], None); assert_eq!(*bounded, vec![1, 2, 3, 4]); } } From f643584ac362ad3f07c8c6b470a588b0d1626f12 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 20:26:06 -0400 Subject: [PATCH 18/32] Update frame/aura/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/aura/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index 9f6c2b0d5d637..9c3976a3d700f 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -76,7 +76,7 @@ pub mod pallet { #[pallet::pallet] pub struct Pallet(sp_std::marker::PhantomData); - // Errors inform users that something went wrong. + // Errors inform users that something went wrong. #[pallet::error] pub enum Error { /// You are trying to add more authorities than allowed in the pallet configuration. From ce8d0c3ad88bdf242a51919d34937a480e95b365 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 20 Apr 2021 20:26:47 -0400 Subject: [PATCH 19/32] undo `One` -> `On` --- frame/aura/src/lib.rs | 4 ++-- frame/aura/src/tests.rs | 2 +- frame/authority-discovery/src/lib.rs | 12 ++++++------ frame/babe/src/lib.rs | 4 ++-- frame/babe/src/mock.rs | 2 +- frame/grandpa/src/lib.rs | 4 ++-- frame/grandpa/src/mock.rs | 2 +- frame/grandpa/src/tests.rs | 2 +- frame/im-online/src/lib.rs | 4 ++-- frame/session/src/lib.rs | 4 ++-- frame/staking/src/mock.rs | 4 ++-- frame/support/src/traits.rs | 2 +- frame/support/src/traits/validation.rs | 2 +- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index 9c3976a3d700f..8ea8adb4d9736 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -44,7 +44,7 @@ use sp_std::{ use codec::{Encode, Decode}; use frame_support::{ Parameter, BoundedVec, ConsensusEngineId, - traits::{Get, FindAuthor, OnSessionHandler, OnTimestampSet}, + traits::{Get, FindAuthor, OneSessionHandler, OnTimestampSet}, }; use sp_runtime::{ RuntimeAppPublic, @@ -187,7 +187,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = T::AuthorityId; } -impl OnSessionHandler for Pallet { +impl OneSessionHandler for Pallet { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) diff --git a/frame/aura/src/tests.rs b/frame/aura/src/tests.rs index 42f678558be62..9f4a01e81945c 100644 --- a/frame/aura/src/tests.rs +++ b/frame/aura/src/tests.rs @@ -21,7 +21,7 @@ use crate::mock::{Aura, new_test_ext}; use sp_runtime::testing::UintAuthorityId; -use frame_support::traits::OnSessionHandler; +use frame_support::traits::OneSessionHandler; #[test] fn initial_values() { diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index a026464249ec2..79154426c314c 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -24,7 +24,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::{prelude::*, convert::TryInto}; -use frame_support::{traits::{OnSessionHandler, Get}, BoundedVec}; +use frame_support::{traits::{OneSessionHandler, Get}, BoundedVec}; #[cfg(feature = "std")] use frame_support::traits::GenesisBuild; use sp_authority_discovery::AuthorityId; @@ -131,7 +131,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = AuthorityId; } -impl OnSessionHandler for Pallet { +impl OneSessionHandler for Pallet { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(authorities: I) @@ -300,7 +300,7 @@ mod tests { #[test] fn authorities_returns_current_and_next_authority_set() { // The whole authority discovery pallet ignores account ids, but we still need them for - // `pallet_session::OnSessionHandler::on_new_session`, thus its safe to use the same value + // `pallet_session::OneSessionHandler::on_new_session`, thus its safe to use the same value // everywhere. let account_id = AuthorityPair::from_seed_slice(vec![10; 32].as_ref()).unwrap().public(); @@ -313,7 +313,7 @@ mod tests { .map(|i| AuthorityPair::from_seed_slice(vec![i; 32].as_ref()).unwrap().public()) .map(AuthorityId::from) .collect(); - // Needed for `pallet_session::OnSessionHandler::on_new_session`. + // Needed for `pallet_session::OneSessionHandler::on_new_session`. let second_authorities_and_account_ids = second_authorities.clone() .into_iter() .map(|id| (&account_id, id)) @@ -323,7 +323,7 @@ mod tests { .map(|i| AuthorityPair::from_seed_slice(vec![i; 32].as_ref()).unwrap().public()) .map(AuthorityId::from) .collect(); - // Needed for `pallet_session::OnSessionHandler::on_new_session`. + // Needed for `pallet_session::OneSessionHandler::on_new_session`. let third_authorities_and_account_ids = third_authorities.clone() .into_iter() .map(|id| (&account_id, id)) @@ -344,7 +344,7 @@ mod tests { let mut externalities = TestExternalities::new(t); externalities.execute_with(|| { - use frame_support::traits::OnSessionHandler; + use frame_support::traits::OneSessionHandler; AuthorityDiscovery::on_genesis_session( first_authorities.iter().map(|id| (id, id.clone())) diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index fd57441bfc045..97a158c118a9e 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -25,7 +25,7 @@ use codec::{Decode, Encode}; use frame_support::{ BoundedVec, dispatch::DispatchResultWithPostInfo, - traits::{FindAuthor, Get, KeyOwnerProofSystem, OnSessionHandler, OnTimestampSet}, + traits::{FindAuthor, Get, KeyOwnerProofSystem, OneSessionHandler, OnTimestampSet}, weights::{Pays, Weight}, }; use sp_application_crypto::Public; @@ -893,7 +893,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = AuthorityId; } -impl OnSessionHandler for Pallet { +impl OneSessionHandler for Pallet { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 0a18295890ce1..0e0aaf684adfa 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -415,7 +415,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec) -> sp_io::Tes .collect(); // NOTE: this will initialize the babe authorities - // through OnSessionHandler::on_genesis_session + // through OneSessionHandler::on_genesis_session pallet_session::GenesisConfig:: { keys: session_keys } .assimilate_storage(&mut t) .unwrap(); diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 043ef037b5a73..f7a80974790e4 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -42,7 +42,7 @@ use fg_primitives::{ use frame_support::{ decl_error, decl_event, decl_module, decl_storage, storage, dispatch::DispatchResultWithPostInfo, - traits::{OnSessionHandler, KeyOwnerProofSystem}, weights::{Pays, Weight}, + traits::{OneSessionHandler, KeyOwnerProofSystem}, weights::{Pays, Weight}, pallet_prelude::Get, Parameter, }; use frame_system::{ensure_none, ensure_root, ensure_signed}; @@ -592,7 +592,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = AuthorityId; } -impl OnSessionHandler for Module +impl OneSessionHandler for Module where T: pallet_session::Config { type Key = AuthorityId; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index a1cb0506938d0..f51887f31c6b8 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -310,7 +310,7 @@ pub fn new_test_ext_raw_authorities(authorities: AuthorityList) -> sp_io::TestEx .collect(); // NOTE: this will initialize the grandpa authorities - // through OnSessionHandler::on_genesis_session + // through OneSessionHandler::on_genesis_session pallet_session::GenesisConfig:: { keys: session_keys } .assimilate_storage(&mut t) .unwrap(); diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 14c04c38a2b43..92d2c6c751a24 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -25,7 +25,7 @@ use codec::{Decode, Encode}; use fg_primitives::ScheduledChange; use frame_support::{ assert_err, assert_ok, assert_noop, - traits::{Currency, OnFinalize, OnSessionHandler}, + traits::{Currency, OnFinalize, OneSessionHandler}, weights::{GetDispatchInfo, Pays}, }; use frame_system::{EventRecord, Phase}; diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 8d4f257db6349..f7ace41bddbc0 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -95,7 +95,7 @@ use sp_staking::{ use frame_support::{ decl_error, decl_event, decl_module, decl_storage, traits::{ - EstimateNextSessionRotation, Get, OnSessionHandler, ValidatorSet, + EstimateNextSessionRotation, Get, OneSessionHandler, ValidatorSet, ValidatorSetWithIdentification, }, Parameter, BoundedVec, @@ -659,7 +659,7 @@ impl sp_runtime::BoundToRuntimeAppPublic for Module { type Public = T::AuthorityId; } -impl OnSessionHandler for Module { +impl OneSessionHandler for Module { type Key = T::AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 53ce5b92a34ed..4f38ced82cce0 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -125,7 +125,7 @@ use frame_support::{ ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId, Parameter, traits::{ Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession, - OnSessionHandler, ValidatorSet, + OneSessionHandler, ValidatorSet, }, dispatch::{self, DispatchResult, DispatchError}, weights::Weight, @@ -291,7 +291,7 @@ pub trait SessionHandler { } #[impl_trait_for_tuples::impl_for_tuples(1, 30)] -#[tuple_types_custom_trait_bound(OnSessionHandler)] +#[tuple_types_custom_trait_bound(OneSessionHandler)] impl> SessionHandler for Tuple { for_tuples!( const KEY_TYPE_IDS: &'static [KeyTypeId] = &[ #( ::ID ),* ]; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 6e70927ad83bb..df1e1949a1049 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -21,7 +21,7 @@ use crate::*; use crate as staking; use frame_support::{ assert_ok, parameter_types, - traits::{Currency, FindAuthor, Get, OnFinalize, OnInitialize, OnSessionHandler}, + traits::{Currency, FindAuthor, Get, OnFinalize, OnInitialize, OneSessionHandler}, weights::constants::RocksDbWeight, IterableStorageMap, StorageDoubleMap, StorageMap, StorageValue, }; @@ -51,7 +51,7 @@ thread_local! { /// Another session handler struct to test on_disabled. pub struct OtherSessionHandler; -impl OnSessionHandler for OtherSessionHandler { +impl OneSessionHandler for OtherSessionHandler { type Key = UintAuthorityId; fn on_genesis_session<'a, I: 'a>(_: I) diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index a52131f8d01a6..7ee2b0a56094b 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -36,7 +36,7 @@ pub use members::{ mod validation; pub use validation::{ - ValidatorSet, ValidatorSetWithIdentification, OnSessionHandler, FindAuthor, VerifySeal, + ValidatorSet, ValidatorSetWithIdentification, OneSessionHandler, FindAuthor, VerifySeal, EstimateNextNewSession, EstimateNextSessionRotation, KeyOwnerProofSystem, ValidatorRegistration, Lateness, }; diff --git a/frame/support/src/traits/validation.rs b/frame/support/src/traits/validation.rs index 02ebb05c91cb4..c3ab7c9649858 100644 --- a/frame/support/src/traits/validation.rs +++ b/frame/support/src/traits/validation.rs @@ -72,7 +72,7 @@ pub trait VerifySeal { } /// A session handler for specific key type. -pub trait OnSessionHandler: BoundToRuntimeAppPublic { +pub trait OneSessionHandler: BoundToRuntimeAppPublic { /// The key type expected. type Key: Decode + Default + RuntimeAppPublic; From 8e96900d88d44acd3da104ff305e48e4928d8465 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 15:17:20 -0400 Subject: [PATCH 20/32] use truncating_from --- frame/aura/src/lib.rs | 9 +++------ frame/authority-discovery/src/lib.rs | 20 +++++++------------- frame/babe/src/lib.rs | 8 ++++---- frame/im-online/src/lib.rs | 7 ++----- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index 8ea8adb4d9736..d07a0ca32a33f 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -202,12 +202,9 @@ impl OneSessionHandler for Pallet { // instant changes if changed { - let next_authorities = validators - .map(|(_, k)| k) - // Only take a number of authorities that would fit in the set. - .take(T::MaxAuthorities::get() as usize) - .collect::>(); - let bounded_next_authorities = BoundedVec::::force_from( + let next_authorities = validators.map(|(_, k)| k).collect::>(); + // Truncate any extra that would not fit into storage... + let bounded_next_authorities = BoundedVec::::truncating_from( next_authorities, Some("Aura New Session"), ); diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 79154426c314c..4b250e1440630 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -24,7 +24,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::{prelude::*, convert::TryInto}; -use frame_support::{traits::{OneSessionHandler, Get}, BoundedVec}; +use frame_support::{traits::OneSessionHandler, BoundedVec}; #[cfg(feature = "std")] use frame_support::traits::GenesisBuild; use sp_authority_discovery::AuthorityId; @@ -147,22 +147,16 @@ impl OneSessionHandler for Pallet { // Remember who the authorities are for the new and next session. if changed { - let keys = validators - .map(|x| x.1) - // Truncate to bounded vec - .take(T::MaxValidators::get() as usize) - .collect::>(); - let bounded_keys = BoundedVec::::force_from( + let keys = validators.map(|x| x.1).collect::>(); + // Truncate any extra that would not fit in storage... + let bounded_keys = BoundedVec::::truncating_from( keys, Some("Authority Discovery New Session Keys"), ); Keys::::put(bounded_keys); - let next_keys = queued_validators - .map(|x| x.1) - // Truncate to bounded vec - .take(T::MaxValidators::get() as usize) - .collect::>(); - let bounded_next_keys = BoundedVec::::force_from( + let next_keys = queued_validators.map(|x| x.1).collect::>(); + // Truncate any extra that would not fit in storage... + let bounded_next_keys = BoundedVec::::truncating_from( next_keys, Some("Authority Discovery New Session Next Keys"), ); diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 97a158c118a9e..df37bc1fd00bc 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -530,8 +530,8 @@ impl Pallet { let bounded_authorities = BoundedVec::< (AuthorityId, BabeAuthorityWeight), T::MaxAuthorities, - >::force_from( - authorities.into_iter().take(T::MaxAuthorities::get() as usize).collect::>(), + >::truncating_from( + authorities, Some("Babe Enact Epoch Change"), ); Authorities::::put(bounded_authorities); @@ -550,8 +550,8 @@ impl Pallet { let bounded_next_authorities = BoundedVec::< (AuthorityId, BabeAuthorityWeight), T::MaxAuthorities, - >::force_from( - next_authorities.into_iter().take(T::MaxAuthorities::get() as usize).collect::>(), + >::truncating_from( + next_authorities, Some("Babe Enact Epoch Change"), ); NextAuthorities::::put(&bounded_next_authorities); diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index f7ace41bddbc0..6cfc8173608a3 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -680,12 +680,9 @@ impl OneSessionHandler for Module< >::put(block_number + half_session); // Remember who the authorities are for the new session. - let next_validators = validators - .map(|x| x.1) - .take(T::MaxAuthorityKeys::get() as usize) - .collect::>(); + let next_validators = validators.map(|x| x.1).collect::>(); - let bounded_validators = BoundedVec::::force_from( + let bounded_validators = BoundedVec::::truncating_from( next_validators, Some("Im Online New Session"), ); From 551457659932bd6aba91f2d6bc905408d7bc932d Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 16:46:48 -0400 Subject: [PATCH 21/32] integrate max validators into staking --- frame/staking/src/benchmarking.rs | 5 ++--- frame/staking/src/lib.rs | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 1d8a5c1fd6451..4c0691391ce4e 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -29,7 +29,6 @@ pub use frame_benchmarking::{ const SEED: u32 = 0; const MAX_SPANS: u32 = 100; -const MAX_VALIDATORS: u32 = 1000; const MAX_SLASHES: u32 = 1000; // Add slashing spans to a user account. Not relevant for actual use, only to benchmark @@ -300,7 +299,7 @@ benchmarks! { } set_validator_count { - let validator_count = MAX_VALIDATORS; + let validator_count = T::MaxValidators::get(); }: _(RawOrigin::Root, validator_count) verify { assert_eq!(ValidatorCount::get(), validator_count); @@ -317,7 +316,7 @@ benchmarks! { // Worst case scenario, the list of invulnerables is very long. set_invulnerables { - let v in 0 .. MAX_VALIDATORS; + let v in 0 .. T::MaxValidators::get(); let mut invulnerables = Vec::new(); for i in 0 .. v { invulnerables.push(account("invulnerable", i, SEED)); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 60907fcafe124..9b980f8a05643 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1155,6 +1155,8 @@ decl_error! { TooManyTargets, /// A nomination target was supplied that was blocked or otherwise not a validator. BadTarget, + /// Validator count cannot be greater than the configured `MaxValidators`. + TooManyValidators, } } @@ -1627,6 +1629,7 @@ decl_module! { #[weight = T::WeightInfo::set_validator_count()] fn set_validator_count(origin, #[compact] new: u32) { ensure_root(origin)?; + ensure!(new <= T::MaxValidators::get(), Error::::TooManyValidators); ValidatorCount::put(new); } @@ -1640,7 +1643,11 @@ decl_module! { #[weight = T::WeightInfo::set_validator_count()] fn increase_validator_count(origin, #[compact] additional: u32) { ensure_root(origin)?; - ValidatorCount::mutate(|n| *n += additional); + ValidatorCount::try_mutate(|n| -> DispatchResult { + *n += additional; + ensure!(*n <= T::MaxValidators::get(), Error::::TooManyValidators); + Ok(()) + })?; } /// Scale up the ideal number of validators by a factor. @@ -1653,7 +1660,11 @@ decl_module! { #[weight = T::WeightInfo::set_validator_count()] fn scale_validator_count(origin, factor: Percent) { ensure_root(origin)?; - ValidatorCount::mutate(|n| *n += factor * *n); + ValidatorCount::try_mutate(|n| -> DispatchResult { + *n += factor * *n; + ensure!(*n <= T::MaxValidators::get(), Error::::TooManyValidators); + Ok(()) + })?; } /// Force there to be no new eras indefinitely. From b7228bbe4fbc4382e6f5f3f53835b0ad88b362ae Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 17:02:33 -0400 Subject: [PATCH 22/32] add serde to boundedvec, bound invulnerables --- frame/staking/src/lib.rs | 10 ++++++---- frame/staking/src/mock.rs | 2 +- frame/support/src/storage/bounded_vec.rs | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 9b980f8a05643..2a3646d948805 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -284,11 +284,11 @@ use sp_std::{ result, prelude::*, collections::btree_map::BTreeMap, - convert::From, + convert::{From, TryInto}, }; use codec::{HasCompact, Encode, Decode}; use frame_support::{ - decl_module, decl_event, decl_storage, ensure, decl_error, + decl_module, decl_event, decl_storage, ensure, decl_error, BoundedVec, weights::{ Weight, WithPostDispatchInfo, constants::{WEIGHT_PER_MICROS, WEIGHT_PER_NANOS}, @@ -854,7 +854,7 @@ decl_storage! { /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're /// easy to initialize and the performance hit is minimal (we expect no more than four /// invulnerables) and restricted to testnets. - pub Invulnerables get(fn invulnerables) config(): Vec; + pub Invulnerables get(fn invulnerables) config(): BoundedVec; /// Map from all locked "stash" accounts to the controller account. pub Bonded get(fn bonded): map hasher(twox_64_concat) T::AccountId => Option; @@ -1709,7 +1709,9 @@ decl_module! { #[weight = T::WeightInfo::set_invulnerables(invulnerables.len() as u32)] fn set_invulnerables(origin, invulnerables: Vec) { ensure_root(origin)?; - >::put(invulnerables); + let bounded_invulnerables: BoundedVec + = invulnerables.try_into().map_err(|_| Error::::TooManyValidators)?; + >::put(bounded_invulnerables); } /// Force a current staker to become completely unstaked, immediately. diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index df1e1949a1049..e04cf50663378 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -436,7 +436,7 @@ impl ExtBuilder { stakers: stakers, validator_count: self.validator_count, minimum_validator_count: self.minimum_validator_count, - invulnerables: self.invulnerables, + invulnerables: self.invulnerables.try_into().unwrap(), slash_reward_fraction: Perbill::from_percent(10), ..Default::default() } diff --git a/frame/support/src/storage/bounded_vec.rs b/frame/support/src/storage/bounded_vec.rs index 17e79b9f747f3..6379d49e798e8 100644 --- a/frame/support/src/storage/bounded_vec.rs +++ b/frame/support/src/storage/bounded_vec.rs @@ -20,6 +20,7 @@ use sp_std::prelude::*; use sp_std::{convert::TryFrom, marker::PhantomData}; +use serde::{Serialize, Deserialize}; use codec::{FullCodec, Encode, EncodeLike, Decode}; use crate::{ traits::Get, @@ -38,6 +39,7 @@ impl BoundedVecValue for T {} /// As the name suggests, the length of the queue is always bounded. All internal operations ensure /// this bound is respected. #[derive(Encode, Decode, crate::DefaultNoBound, crate::CloneNoBound, crate::DebugNoBound)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct BoundedVec>(Vec, PhantomData); // NOTE: we could also implement this as: From 58756f59ab1f5a3bac959f1b02a9f5cffe81d673 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 17:03:52 -0400 Subject: [PATCH 23/32] Update lib.rs --- frame/staking/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 2a3646d948805..0fb55b04baef5 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -958,6 +958,7 @@ decl_storage! { pub CanceledSlashPayout get(fn canceled_payout) config(): BalanceOf; /// All unapplied slashes that are queued for later. + // TODO: BOUND THIS VEC pub UnappliedSlashes: map hasher(twox_64_concat) EraIndex => Vec>>; From 3ac6283d017fc7affafd07cee2be1a70b106d677 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 19:15:28 -0400 Subject: [PATCH 24/32] bound session --- frame/session/src/historical/mod.rs | 2 +- frame/session/src/lib.rs | 57 +++++++++++++++++++++-------- frame/session/src/tests.rs | 22 +++++------ 3 files changed, 54 insertions(+), 27 deletions(-) diff --git a/frame/session/src/historical/mod.rs b/frame/session/src/historical/mod.rs index 8902ebe551f6c..d37e169df289f 100644 --- a/frame/session/src/historical/mod.rs +++ b/frame/session/src/historical/mod.rs @@ -113,7 +113,7 @@ impl ValidatorSet for Module { } fn validators() -> Vec { - super::Module::::validators() + super::Module::::validators().to_vec() } } diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 4f38ced82cce0..5050efebe9b50 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -95,7 +95,7 @@ //! use pallet_session as session; //! //! fn validators() -> Vec<::ValidatorId> { -//! >::validators() +//! >::validators().to_vec() //! } //! # fn main(){} //! ``` @@ -114,7 +114,7 @@ mod tests; pub mod historical; pub mod weights; -use sp_std::{prelude::*, marker::PhantomData, ops::{Sub, Rem}}; +use sp_std::{prelude::*, marker::PhantomData, ops::{Sub, Rem}, convert::TryInto}; use codec::Decode; use sp_runtime::{ traits::{AtLeast32BitUnsigned, Convert, Member, One, OpaqueKeys, Zero}, @@ -122,7 +122,8 @@ use sp_runtime::{ }; use sp_staking::SessionIndex; use frame_support::{ - ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId, Parameter, + ensure, decl_module, decl_event, decl_storage, decl_error, + ConsensusEngineId, Parameter, BoundedVec, traits::{ Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession, OneSessionHandler, ValidatorSet, @@ -401,7 +402,7 @@ pub trait Config: frame_system::Config { decl_storage! { trait Store for Module as Session { /// The current set of validators. - Validators get(fn validators): Vec; + Validators get(fn validators): BoundedVec; /// Current index of the session. CurrentIndex get(fn current_index): SessionIndex; @@ -412,7 +413,7 @@ decl_storage! { /// 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)>; + QueuedKeys get(fn queued_keys): BoundedVec<(T::ValidatorId, T::Keys), T::MaxValidators>; /// Indices of disabled validators. /// @@ -458,10 +459,12 @@ decl_storage! { session config keys to generate initial validator set."); config.keys.iter().map(|x| x.1.clone()).collect() }); - assert!(!initial_validators_0.is_empty(), "Empty validator set for session 0 in genesis block!"); + let bounded_initial_validators_0: BoundedVec + = initial_validators_0.clone().try_into().expect("Too many initial validators!"); + assert!(!bounded_initial_validators_0.is_empty(), "Empty validator set for session 0 in genesis block!"); let initial_validators_1 = T::SessionManager::new_session(1) - .unwrap_or_else(|| initial_validators_0.clone()); + .unwrap_or_else(|| initial_validators_0); assert!(!initial_validators_1.is_empty(), "Empty validator set for session 1 in genesis block!"); let queued_keys: Vec<_> = initial_validators_1 @@ -472,12 +475,13 @@ decl_storage! { >::load_keys(&v).unwrap_or_default(), )) .collect(); - + let bounded_queued_keys: BoundedVec<(T::ValidatorId, T::Keys), T::MaxValidators> + = queued_keys.try_into().expect("Too many queued keys!"); // Tell everyone about the genesis session keys - T::SessionHandler::on_genesis_session::(&queued_keys); + T::SessionHandler::on_genesis_session::(&bounded_queued_keys); - >::put(initial_validators_0); - >::put(queued_keys); + >::put(bounded_initial_validators_0); + >::put(bounded_queued_keys); T::SessionManager::start_session(0); }); @@ -592,6 +596,12 @@ impl Module { let validators = session_keys.iter() .map(|(validator, _)| validator.clone()) .collect::>(); + // Note this should never truncate because queued keys is also bounded to `MaxValidators`, + // but we do so defensively. + let validators = BoundedVec::::truncating_from( + validators, + Some("Session Rotate Session"), + ); >::put(&validators); if changed { @@ -610,6 +620,10 @@ impl Module { let (next_validators, next_identities_changed) = if let Some(validators) = maybe_next_validators { + let validators = BoundedVec::::truncating_from( + validators, + Some("Session Rotate Session Maybe Next Validators"), + ); // NOTE: as per the documentation on `OnSessionEnding`, we consider // the validator set as having changed even if the validators are the // same as before, as underlying economic conditions may have changed. @@ -644,6 +658,12 @@ impl Module { (a, k) }) .collect::>(); + // Should never truncate since next_validators should already be the right length, + // but we do so defensively. + let queued_amalgamated = BoundedVec::<(T::ValidatorId, T::Keys), T::MaxValidators>::truncating_from( + queued_amalgamated, + Some("Session Rotate Session"), + ); (queued_amalgamated, changed) }; @@ -738,9 +758,16 @@ impl Module { let _ = >::translate::, _>( |k| { - k.map(|k| k.into_iter() - .map(|(val, old_keys)| (val.clone(), upgrade(val, old_keys))) - .collect::>()) + k.map(|k| { + let keys = k.into_iter() + .map(|(val, old_keys)| (val.clone(), upgrade(val, old_keys))) + .collect::>(); + // Should never truncate since queued keys is already bounded. + BoundedVec::<(T::ValidatorId, T::Keys), T::MaxValidators>::truncating_from( + keys, + Some("Session Upgrade Keys"), + ) + }) } ); } @@ -849,7 +876,7 @@ impl ValidatorSet for Module { } fn validators() -> Vec { - Module::::validators() + Module::::validators().to_vec() } } diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index f48388b5a002c..767d594351939 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -40,7 +40,7 @@ fn initialize_block(block: u64) { fn simple_setup_should_work() { new_test_ext().execute_with(|| { assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); }); } @@ -56,7 +56,7 @@ fn put_get_keys() { fn keys_cleared_on_kill() { let mut ext = new_test_ext(); ext.execute_with(|| { - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); assert_eq!(Session::load_keys(&1), Some(UintAuthorityId(1).into())); let id = DUMMY; @@ -79,22 +79,22 @@ fn authorities_should_track_validators() { set_next_validators(vec![1, 2]); force_new_session(); initialize_block(1); - assert_eq!(Session::queued_keys(), vec![ + assert_eq!(Session::queued_keys().to_vec(), vec![ (1, UintAuthorityId(1).into()), (2, UintAuthorityId(2).into()), ]); - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); assert!(before_session_end_called()); reset_before_session_end_called(); force_new_session(); initialize_block(2); - assert_eq!(Session::queued_keys(), vec![ + assert_eq!(Session::queued_keys().to_vec(), vec![ (1, UintAuthorityId(1).into()), (2, UintAuthorityId(2).into()), ]); - assert_eq!(Session::validators(), vec![1, 2]); + assert_eq!(Session::validators().to_vec(), vec![1, 2]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2)]); assert!(before_session_end_called()); reset_before_session_end_called(); @@ -103,23 +103,23 @@ fn authorities_should_track_validators() { assert_ok!(Session::set_keys(Origin::signed(4), UintAuthorityId(4).into(), vec![])); force_new_session(); initialize_block(3); - assert_eq!(Session::queued_keys(), vec![ + assert_eq!(Session::queued_keys().to_vec(), vec![ (1, UintAuthorityId(1).into()), (2, UintAuthorityId(2).into()), (4, UintAuthorityId(4).into()), ]); - assert_eq!(Session::validators(), vec![1, 2]); + assert_eq!(Session::validators().to_vec(), vec![1, 2]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2)]); assert!(before_session_end_called()); force_new_session(); initialize_block(4); - assert_eq!(Session::queued_keys(), vec![ + assert_eq!(Session::queued_keys().to_vec(), vec![ (1, UintAuthorityId(1).into()), (2, UintAuthorityId(2).into()), (4, UintAuthorityId(4).into()), ]); - assert_eq!(Session::validators(), vec![1, 2, 4]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 4]); assert_eq!(authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(4)]); }); } @@ -437,7 +437,7 @@ fn upgrade_keys() { // Check queued keys. assert_eq!( - Session::queued_keys(), + Session::queued_keys().to_vec(), vec![ (1, mock_keys_for(1)), (2, mock_keys_for(2)), From c32d358cd29cc9a8f4fdba4ebb68f87462e14247 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 21:39:44 -0400 Subject: [PATCH 25/32] fix im-online tests --- frame/im-online/src/tests.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index f447a2ade5481..548ad0e89b454 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -89,7 +89,7 @@ fn should_report_offline_validators() { // should not report when heartbeat is sent for (idx, v) in validators.into_iter().take(4).enumerate() { - let _ = heartbeat(block, 3, idx as u32, v.into(), Session::validators()).unwrap(); + let _ = heartbeat(block, 3, idx as u32, v.into(), Session::validators().to_vec()).unwrap(); } advance_session(); @@ -148,19 +148,19 @@ fn should_mark_online_validator_when_heartbeat_is_received() { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); - assert_eq!(Session::validators(), Vec::::new()); + assert_eq!(Session::validators().to_vec(), Vec::::new()); // enact the change and buffer another one advance_session(); assert_eq!(Session::current_index(), 2); - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); assert!(!ImOnline::is_online(0)); assert!(!ImOnline::is_online(1)); assert!(!ImOnline::is_online(2)); // when - let _ = heartbeat(1, 2, 0, 1.into(), Session::validators()).unwrap(); + let _ = heartbeat(1, 2, 0, 1.into(), Session::validators().to_vec()).unwrap(); // then assert!(ImOnline::is_online(0)); @@ -168,7 +168,7 @@ fn should_mark_online_validator_when_heartbeat_is_received() { assert!(!ImOnline::is_online(2)); // and when - let _ = heartbeat(1, 2, 2, 3.into(), Session::validators()).unwrap(); + let _ = heartbeat(1, 2, 2, 3.into(), Session::validators().to_vec()).unwrap(); // then assert!(ImOnline::is_online(0)); @@ -183,16 +183,16 @@ fn late_heartbeat_and_invalid_keys_len_should_fail() { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); - assert_eq!(Session::validators(), Vec::::new()); + assert_eq!(Session::validators().to_vec(), Vec::::new()); // enact the change and buffer another one advance_session(); assert_eq!(Session::current_index(), 2); - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); // when - assert_noop!(heartbeat(1, 3, 0, 1.into(), Session::validators()), "Transaction is outdated"); - assert_noop!(heartbeat(1, 1, 0, 1.into(), Session::validators()), "Transaction is outdated"); + assert_noop!(heartbeat(1, 3, 0, 1.into(), Session::validators().to_vec()), "Transaction is outdated"); + assert_noop!(heartbeat(1, 1, 0, 1.into(), Session::validators().to_vec()), "Transaction is outdated"); // invalid validators_len assert_noop!(heartbeat(1, 2, 0, 1.into(), vec![]), "invalid validators len"); @@ -252,16 +252,16 @@ fn should_cleanup_received_heartbeats_on_session_end() { advance_session(); VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3])); - assert_eq!(Session::validators(), Vec::::new()); + assert_eq!(Session::validators().to_vec(), Vec::::new()); // enact the change and buffer another one advance_session(); assert_eq!(Session::current_index(), 2); - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); // send an heartbeat from authority id 0 at session 2 - let _ = heartbeat(1, 2, 0, 1.into(), Session::validators()).unwrap(); + let _ = heartbeat(1, 2, 0, 1.into(), Session::validators().to_vec()).unwrap(); // the heartbeat is stored assert!(!ImOnline::received_heartbeats(&2, &0).is_none()); @@ -283,12 +283,12 @@ fn should_mark_online_validator_when_block_is_authored() { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); - assert_eq!(Session::validators(), Vec::::new()); + assert_eq!(Session::validators().to_vec(), Vec::::new()); // enact the change and buffer another one advance_session(); assert_eq!(Session::current_index(), 2); - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); for i in 0..3 { assert!(!ImOnline::is_online(i)); @@ -320,11 +320,11 @@ fn should_not_send_a_report_if_already_online() { advance_session(); // given VALIDATORS.with(|l| *l.borrow_mut() = Some(vec![1, 2, 3, 4, 5, 6])); - assert_eq!(Session::validators(), Vec::::new()); + assert_eq!(Session::validators().to_vec(), Vec::::new()); // enact the change and buffer another one advance_session(); assert_eq!(Session::current_index(), 2); - assert_eq!(Session::validators(), vec![1, 2, 3]); + assert_eq!(Session::validators().to_vec(), vec![1, 2, 3]); ImOnline::note_author(2); ImOnline::note_uncle(3, 0); From 2ffa6207b42ec9aae0f8ddcf9a9e58115440c744 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 22:15:58 -0400 Subject: [PATCH 26/32] fix staking tests --- frame/staking/src/lib.rs | 2 +- frame/staking/src/mock.rs | 2 +- frame/staking/src/tests.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 0fb55b04baef5..304ddba523546 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -661,7 +661,7 @@ impl SessionInterface<::AccountId> for T w } fn validators() -> Vec<::AccountId> { - >::validators() + >::validators().to_vec() } fn prune_historical_up_to(up_to: SessionIndex) { diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index e04cf50663378..90f2dc3eca6aa 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -452,7 +452,7 @@ impl ExtBuilder { let mut ext = sp_io::TestExternalities::from(storage); ext.execute_with(|| { - let validators = Session::validators(); + let validators = Session::validators().to_vec(); SESSION.with(|x| *x.borrow_mut() = (validators.clone(), HashSet::new())); }); diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 05eb6fdc5e028..06507007987cf 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -3099,7 +3099,7 @@ fn six_session_delay() { ExtBuilder::default().initialize_first_session(false).build_and_execute(|| { use pallet_session::SessionManager; - let val_set = Session::validators(); + let val_set = Session::validators().to_vec(); let init_session = Session::current_index(); let init_active_era = Staking::active_era().unwrap().index; From 5e6a8148f4566b17ec7c06a10e363a81491aa921 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 22:48:41 -0400 Subject: [PATCH 27/32] fix more tests --- frame/babe/src/mock.rs | 2 +- frame/babe/src/tests.rs | 2 +- frame/grandpa/src/mock.rs | 2 +- frame/grandpa/src/tests.rs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 0e0aaf684adfa..08bae3a3e6d78 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -437,7 +437,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec) -> sp_io::Tes validator_count: 8, force_era: pallet_staking::Forcing::ForceNew, minimum_validator_count: 0, - invulnerables: vec![], + invulnerables: Default::default(), ..Default::default() }; diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 75b6189518817..999fa0b9146b2 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -413,7 +413,7 @@ fn report_equivocation_current_session_works() { start_era(1); let authorities = Babe::authorities(); - let validators = Session::validators(); + let validators = Session::validators().to_vec(); // make sure that all authorities have the same balance for validator in &validators { diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index f51887f31c6b8..77aa055827158 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -332,7 +332,7 @@ pub fn new_test_ext_raw_authorities(authorities: AuthorityList) -> sp_io::TestEx validator_count: 8, force_era: pallet_staking::Forcing::ForceNew, minimum_validator_count: 0, - invulnerables: vec![], + invulnerables: Default::default(), ..Default::default() }; diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 92d2c6c751a24..7763764548beb 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -364,7 +364,7 @@ fn report_equivocation_current_set_works() { start_era(1); let authorities = Grandpa::grandpa_authorities(); - let validators = Session::validators(); + let validators = Session::validators().to_vec(); // make sure that all validators have the same balance for validator in &validators { @@ -453,7 +453,7 @@ fn report_equivocation_old_set_works() { start_era(1); let authorities = Grandpa::grandpa_authorities(); - let validators = Session::validators(); + let validators = Session::validators().to_vec(); let equivocation_authority_index = 0; let equivocation_key = &authorities[equivocation_authority_index].0; From 28ca319f4df1a075dab0a10690880b5f6b4c9b2b Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 23:32:51 -0400 Subject: [PATCH 28/32] std serde --- frame/support/src/storage/bounded_vec.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/support/src/storage/bounded_vec.rs b/frame/support/src/storage/bounded_vec.rs index 6379d49e798e8..b4e8cf3420e88 100644 --- a/frame/support/src/storage/bounded_vec.rs +++ b/frame/support/src/storage/bounded_vec.rs @@ -20,6 +20,7 @@ use sp_std::prelude::*; use sp_std::{convert::TryFrom, marker::PhantomData}; +#[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use codec::{FullCodec, Encode, EncodeLike, Decode}; use crate::{ From b99849b63aac9584c12d48b1228234cbe856448e Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 23:47:45 -0400 Subject: [PATCH 29/32] fix genesis --- frame/staking/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 304ddba523546..ffc310fdd0f62 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -854,7 +854,7 @@ decl_storage! { /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're /// easy to initialize and the performance hit is minimal (we expect no more than four /// invulnerables) and restricted to testnets. - pub Invulnerables get(fn invulnerables) config(): BoundedVec; + pub Invulnerables get(fn invulnerables): BoundedVec; /// Map from all locked "stash" accounts to the controller account. pub Bonded get(fn bonded): map hasher(twox_64_concat) T::AccountId => Option; @@ -1005,7 +1005,11 @@ decl_storage! { add_extra_genesis { config(stakers): Vec<(T::AccountId, T::AccountId, BalanceOf, StakerStatus)>; + config(invulnerables): Vec; build(|config: &GenesisConfig| { + let bounded_invulnerables: BoundedVec + = config.invulnerables.clone().try_into().expect("Too many invulnerables!"); + Invulnerables::::put(bounded_invulnerables); for &(ref stash, ref controller, balance, ref status) in &config.stakers { assert!( T::Currency::free_balance(&stash) >= balance, From 92083f3e4696c2059758d9bf2e63d6c2d7471d07 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 21 Apr 2021 23:56:00 -0400 Subject: [PATCH 30/32] undo invulnerables set --- frame/babe/src/mock.rs | 2 +- frame/grandpa/src/mock.rs | 2 +- frame/staking/src/mock.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 08bae3a3e6d78..0e0aaf684adfa 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -437,7 +437,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec) -> sp_io::Tes validator_count: 8, force_era: pallet_staking::Forcing::ForceNew, minimum_validator_count: 0, - invulnerables: Default::default(), + invulnerables: vec![], ..Default::default() }; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 77aa055827158..f51887f31c6b8 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -332,7 +332,7 @@ pub fn new_test_ext_raw_authorities(authorities: AuthorityList) -> sp_io::TestEx validator_count: 8, force_era: pallet_staking::Forcing::ForceNew, minimum_validator_count: 0, - invulnerables: Default::default(), + invulnerables: vec![], ..Default::default() }; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 90f2dc3eca6aa..fa1cabb001900 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -436,7 +436,7 @@ impl ExtBuilder { stakers: stakers, validator_count: self.validator_count, minimum_validator_count: self.minimum_validator_count, - invulnerables: self.invulnerables.try_into().unwrap(), + invulnerables: self.invulnerables, slash_reward_fraction: Perbill::from_percent(10), ..Default::default() } From 575294f0e0651c5cda7f2a9f3bc92d11b37cdbe7 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Thu, 22 Apr 2021 05:22:29 -0400 Subject: [PATCH 31/32] Update frame/session/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/session/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 5050efebe9b50..06ea13f80fb5c 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -762,7 +762,7 @@ impl Module { let keys = k.into_iter() .map(|(val, old_keys)| (val.clone(), upgrade(val, old_keys))) .collect::>(); - // Should never truncate since queued keys is already bounded. + // Should never truncate since queued keys is already bounded. BoundedVec::<(T::ValidatorId, T::Keys), T::MaxValidators>::truncating_from( keys, Some("Session Upgrade Keys"), From dadc74625e7003200df952f08f2ad9103b546a7d Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Thu, 22 Apr 2021 06:43:53 -0400 Subject: [PATCH 32/32] little doc --- bin/node/runtime/src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index b5ef6a1dde0cb..cb59c8c5961cd 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -332,9 +332,14 @@ parameter_types! { pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK; pub const ReportLongevity: u64 = BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get(); + // The maximum number of authorities / validators for this runtime system. + // This is should be shared across all pallets using session handlers. pub const MaxAuthorities: u32 = 100; } +// Just a convenient rename... +type MaxValidators = MaxAuthorities; + impl pallet_babe::Config for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; @@ -449,7 +454,7 @@ impl pallet_session::Config for Runtime { type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; - type MaxValidators = MaxAuthorities; + type MaxValidators = MaxValidators; type WeightInfo = pallet_session::weights::SubstrateWeight; } @@ -500,7 +505,7 @@ impl pallet_staking::Config for Runtime { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type ElectionProvider = ElectionProviderMultiPhase; - type MaxValidators = MaxAuthorities; + type MaxValidators = MaxValidators; type WeightInfo = pallet_staking::weights::SubstrateWeight; }