Skip to content

Commit

Permalink
Migrate MaxValidatorsCount from storage to dynamic param + fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
re-gius committed Dec 2, 2024
1 parent ca881ac commit e986264
Show file tree
Hide file tree
Showing 14 changed files with 52 additions and 52 deletions.
1 change: 1 addition & 0 deletions polkadot/runtime/test-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ impl pallet_staking::Config for Runtime {
type DisablingStrategy = pallet_staking::UpToLimitWithReEnablingDisablingStrategy;
type MaxInvulnerables = ConstU32<20>;
type MaxRewardPagesPerValidator = ConstU32<20>;
type MaxValidatorsCount = ConstU32<300>;
}

parameter_types! {
Expand Down
12 changes: 9 additions & 3 deletions polkadot/runtime/westend/src/genesis_config_presets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use sp_consensus_grandpa::AuthorityId as GrandpaId;
use sp_core::{crypto::get_public_from_string_or_panic, sr25519};
use sp_genesis_builder::PresetId;
use sp_keyring::Sr25519Keyring;
use sp_runtime::Perbill;
use sp_runtime::{BoundedVec, Perbill};
use westend_runtime_constants::currency::UNITS as WND;

/// Helper function to generate stash, controller and session key from seed
Expand Down Expand Up @@ -201,7 +201,10 @@ fn westend_testnet_genesis(
.iter()
.map(|x| (x.0.clone(), x.0.clone(), STASH, StakerStatus::<AccountId>::Validator))
.collect::<Vec<_>>(),
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
invulnerables: BoundedVec::try_from(
initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>()
)
.unwrap(),
force_era: Forcing::NotForcing,
slash_reward_fraction: Perbill::from_percent(10),
},
Expand Down Expand Up @@ -372,7 +375,10 @@ fn westend_staging_testnet_config_genesis() -> serde_json::Value {
.iter()
.map(|x| (x.0.clone(), x.0.clone(), STASH, StakerStatus::<AccountId>::Validator))
.collect::<Vec<_>>(),
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
invulnerables: BoundedVec::try_from(
initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>()
)
.unwrap(),
force_era: Forcing::ForceNone,
slash_reward_fraction: Perbill::from_percent(10),
},
Expand Down
10 changes: 10 additions & 0 deletions polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,14 @@ pub mod dynamic_params {
#[codec(index = 4)]
pub static UseAuctionSlots: bool = false;
}

#[dynamic_pallet_params]
#[codec(index = 1)]
pub mod staking {
/// Maximum number of validators allowed.
#[codec(index = 0)]
pub static MaxValidatorsCount: u32 = 300;
}
}

#[cfg(feature = "runtime-benchmarks")]
Expand Down Expand Up @@ -319,6 +327,7 @@ impl EnsureOriginWithArg<RuntimeOrigin, RuntimeParametersKey> for DynamicParamet

match key {
Inflation(_) => frame_system::ensure_root(origin.clone()),
Staking(_) => frame_system::ensure_root(origin.clone()),
}
.map_err(|_| origin)
}
Expand Down Expand Up @@ -760,6 +769,7 @@ impl pallet_staking::Config for Runtime {
type DisablingStrategy = pallet_staking::UpToLimitWithReEnablingDisablingStrategy;
type MaxInvulnerables = frame_support::traits::ConstU32<20>;
type MaxRewardPagesPerValidator = frame_support::traits::ConstU32<20>;
type MaxValidatorsCount = dynamic_params::staking::MaxValidatorsCount;
}

impl pallet_fast_unstake::Config for Runtime {
Expand Down
1 change: 1 addition & 0 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ impl pallet_staking::Config for Runtime {
type DisablingStrategy = pallet_staking::UpToLimitWithReEnablingDisablingStrategy;
type MaxInvulnerables = ConstU32<20>;
type MaxRewardPagesPerValidator = ConstU32<20>;
type MaxValidatorsCount = ConstU32<300>;
}

impl pallet_fast_unstake::Config for Runtime {
Expand Down
4 changes: 2 additions & 2 deletions substrate/frame/babe/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use sp_runtime::{
impl_opaque_keys,
testing::{Digest, DigestItem, Header, TestXt},
traits::{Header as _, OpaqueKeys},
BuildStorage, Perbill,
BoundedVec, BuildStorage, Perbill,
};
use sp_staking::{EraIndex, SessionIndex};

Expand Down Expand Up @@ -342,7 +342,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec<AuthorityId>) -> sp_io::Tes
validator_count: 8,
force_era: pallet_staking::Forcing::ForceNew,
minimum_validator_count: 0,
invulnerables: vec![],
invulnerables: BoundedVec::new(),
..Default::default()
};

Expand Down
4 changes: 2 additions & 2 deletions substrate/frame/beefy/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use sp_runtime::{
impl_opaque_keys,
testing::TestXt,
traits::{Header as HeaderT, OpaqueKeys},
BuildStorage, Perbill,
BoundedVec, BuildStorage, Perbill,
};
use sp_staking::{EraIndex, SessionIndex};
use sp_state_machine::BasicExternalities;
Expand Down Expand Up @@ -303,7 +303,7 @@ impl ExtBuilder {
validator_count: 2,
force_era: pallet_staking::Forcing::ForceNew,
minimum_validator_count: 0,
invulnerables: vec![],
invulnerables: BoundedVec::new(),
..Default::default()
};

Expand Down
4 changes: 2 additions & 2 deletions substrate/frame/delegated-staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use frame_support::{
PalletId,
};

use sp_runtime::{traits::IdentityLookup, BuildStorage, Perbill};
use sp_runtime::{traits::IdentityLookup, BoundedVec, BuildStorage, Perbill};

use frame_election_provider_support::{
bounds::{ElectionBounds, ElectionBoundsBuilder},
Expand Down Expand Up @@ -217,7 +217,7 @@ impl ExtBuilder {
// ideal validator count
validator_count: 2,
minimum_validator_count: 1,
invulnerables: vec![],
invulnerables: BoundedVec::new(),
slash_reward_fraction: Perbill::from_percent(10),
min_nominator_bond: ExistentialDeposit::get(),
min_validator_bond: ExistentialDeposit::get(),
Expand Down
4 changes: 2 additions & 2 deletions substrate/frame/grandpa/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use sp_runtime::{
impl_opaque_keys,
testing::{TestXt, UintAuthorityId},
traits::OpaqueKeys,
BuildStorage, DigestItem, Perbill,
BoundedVec, BuildStorage, DigestItem, Perbill,
};
use sp_staking::{EraIndex, SessionIndex};

Expand Down Expand Up @@ -258,7 +258,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: BoundedVec::new(),
..Default::default()
};

Expand Down
4 changes: 2 additions & 2 deletions substrate/frame/root-offences/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl Default for ExtBuilder {
Self {
validator_count: 2,
minimum_validator_count: 0,
invulnerables: vec![],
invulnerables: BoundedVec::new(),
balance_factor: 1,
}
}
Expand Down Expand Up @@ -235,7 +235,7 @@ impl ExtBuilder {
stakers: stakers.clone(),
validator_count: self.validator_count,
minimum_validator_count: self.minimum_validator_count,
invulnerables: self.invulnerables,
invulnerables: BoundedVec::force_from(self.invulnerables),
slash_reward_fraction: Perbill::from_percent(10),
..Default::default()
}
Expand Down
5 changes: 0 additions & 5 deletions substrate/frame/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,6 @@ mod benchmarks {
ConfigOp::Set(BalanceOf::<T>::max_value()),
ConfigOp::Set(BalanceOf::<T>::max_value()),
ConfigOp::Set(u32::MAX),
ConfigOp::Set(u32::MAX),
ConfigOp::Set(Percent::max_value()),
ConfigOp::Set(Perbill::max_value()),
ConfigOp::Set(Percent::max_value()),
Expand All @@ -1030,7 +1029,6 @@ mod benchmarks {
assert_eq!(MinNominatorBond::<T>::get(), BalanceOf::<T>::max_value());
assert_eq!(MinValidatorBond::<T>::get(), BalanceOf::<T>::max_value());
assert_eq!(MaxNominatorsCount::<T>::get(), Some(u32::MAX));
assert_eq!(MaxValidatorsCount::<T>::get(), Some(u32::MAX));
assert_eq!(ChillThreshold::<T>::get(), Some(Percent::from_percent(100)));
assert_eq!(MinCommission::<T>::get(), Perbill::from_percent(100));
assert_eq!(MaxStakedRewards::<T>::get(), Some(Percent::from_percent(100)));
Expand All @@ -1047,13 +1045,11 @@ mod benchmarks {
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
);

assert!(!MinNominatorBond::<T>::exists());
assert!(!MinValidatorBond::<T>::exists());
assert!(!MaxNominatorsCount::<T>::exists());
assert!(!MaxValidatorsCount::<T>::exists());
assert!(!ChillThreshold::<T>::exists());
assert!(!MinCommission::<T>::exists());
assert!(!MaxStakedRewards::<T>::exists());
Expand All @@ -1077,7 +1073,6 @@ mod benchmarks {
ConfigOp::Set(BalanceOf::<T>::max_value()),
ConfigOp::Set(BalanceOf::<T>::max_value()),
ConfigOp::Set(0),
ConfigOp::Set(0),
ConfigOp::Set(Percent::from_percent(0)),
ConfigOp::Set(Zero::zero()),
ConfigOp::Noop,
Expand Down
5 changes: 5 additions & 0 deletions substrate/frame/staking/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ pub mod v17 {
fn on_runtime_upgrade() -> Weight {
let mut migration_errors = false;

v16::MaxValidatorsCount::<T>::kill();

let old_disabled_validators = v16::DisabledValidators::<T>::get();
// BoundedVec with MaxWinners limit, this should always work
let disabled_validators_maybe = WeakBoundedVec::try_from(old_disabled_validators);
Expand Down Expand Up @@ -249,6 +251,9 @@ pub mod v16 {
OptionQuery,
>;

#[frame_support::storage_alias]
pub(crate) type MaxValidatorsCount<T: Config> = StorageValue<Pallet<T>, u32, OptionQuery>;

pub struct VersionUncheckedMigrateV15ToV16<T>(core::marker::PhantomData<T>);
impl<T: Config> UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateV15ToV16<T> {
#[cfg(feature = "try-runtime")]
Expand Down
1 change: 1 addition & 0 deletions substrate/frame/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ impl crate::pallet::pallet::Config for Test {
pallet_staking::UpToLimitWithReEnablingDisablingStrategy<DISABLING_LIMIT_FACTOR>;
type MaxInvulnerables = ConstU32<20>;
type MaxRewardPagesPerValidator = ConstU32<20>;
type MaxValidatorsCount = ConstU32<300>;
}

pub struct WeightedNominationsQuota<const MAX: u32>;
Expand Down
38 changes: 15 additions & 23 deletions substrate/frame/staking/src/pallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ pub mod pallet {
#[pallet::no_default_bounds]
type NominationsQuota: NominationsQuota<BalanceOf<Self>>;

/// The maximum validator count before we stop allowing new validators to join.
///
/// This is a dynamic runtime parameters, so updates do not require storage migrations.
#[pallet::constant]
type MaxValidatorsCount: Get<u32>;

/// Number of eras to keep in history.
///
/// Following information is kept for eras in `[current_era -
Expand Down Expand Up @@ -361,6 +367,7 @@ pub mod pallet {
type DisablingStrategy = crate::UpToLimitDisablingStrategy;
type MaxInvulnerables = ConstU32<20>;
type MaxRewardPagesPerValidator = ConstU32<20>;
type MaxValidatorsCount = ConstU32<300>;
#[cfg(feature = "std")]
type BenchmarkingConfig = crate::TestBenchmarkingConfig;
type WeightInfo = ();
Expand Down Expand Up @@ -427,12 +434,6 @@ pub mod pallet {
pub type Validators<T: Config> =
CountedStorageMap<_, Twox64Concat, T::AccountId, ValidatorPrefs, ValueQuery>;

/// The maximum validator count before we stop allowing new validators to join.
///
/// When this value is not set, no limits are enforced.
#[pallet::storage]
pub type MaxValidatorsCount<T> = StorageValue<_, u32, OptionQuery>;

/// The map from nominator stash key to their nomination preferences, namely the validators that
/// they wish to support.
///
Expand Down Expand Up @@ -710,7 +711,6 @@ pub mod pallet {
Vec<(T::AccountId, T::AccountId, BalanceOf<T>, crate::StakerStatus<T::AccountId>)>,
pub min_nominator_bond: BalanceOf<T>,
pub min_validator_bond: BalanceOf<T>,
pub max_validator_count: Option<u32>,
pub max_nominator_count: Option<u32>,
}

Expand All @@ -729,9 +729,6 @@ pub mod pallet {
SlashRewardFraction::<T>::put(self.slash_reward_fraction);
MinNominatorBond::<T>::put(self.min_nominator_bond);
MinValidatorBond::<T>::put(self.min_validator_bond);
if let Some(x) = self.max_validator_count {
MaxValidatorsCount::<T>::put(x);
}
if let Some(x) = self.max_nominator_count {
MaxNominatorsCount::<T>::put(x);
}
Expand Down Expand Up @@ -1347,12 +1344,10 @@ pub mod pallet {
// If this error is reached, we need to adjust the `MinValidatorBond` and start
// calling `chill_other`. Until then, we explicitly block new validators to protect
// the runtime.
if let Some(max_validators) = MaxValidatorsCount::<T>::get() {
ensure!(
Validators::<T>::count() < max_validators,
Error::<T>::TooManyValidators
);
}
ensure!(
Validators::<T>::count() < T::MaxValidatorsCount::get(),
Error::<T>::TooManyValidators,
);
}

Self::do_remove_nominator(stash);
Expand Down Expand Up @@ -1911,7 +1906,6 @@ pub mod pallet {
min_nominator_bond: ConfigOp<BalanceOf<T>>,
min_validator_bond: ConfigOp<BalanceOf<T>>,
max_nominator_count: ConfigOp<u32>,
max_validator_count: ConfigOp<u32>,
chill_threshold: ConfigOp<Percent>,
min_commission: ConfigOp<Perbill>,
max_staked_rewards: ConfigOp<Percent>,
Expand All @@ -1931,7 +1925,6 @@ pub mod pallet {
config_op_exp!(MinNominatorBond<T>, min_nominator_bond);
config_op_exp!(MinValidatorBond<T>, min_validator_bond);
config_op_exp!(MaxNominatorsCount<T>, max_nominator_count);
config_op_exp!(MaxValidatorsCount<T>, max_validator_count);
config_op_exp!(ChillThreshold<T>, chill_threshold);
config_op_exp!(MinCommission<T>, min_commission);
config_op_exp!(MaxStakedRewards<T>, max_staked_rewards);
Expand All @@ -1955,8 +1948,8 @@ pub mod pallet {
///
/// * A `ChillThreshold` must be set and checked which defines how close to the max
/// nominators or validators we must reach before users can start chilling one-another.
/// * A `MaxNominatorCount` and `MaxValidatorCount` must be set which is used to determine
/// how close we are to the threshold.
/// * A `MaxNominatorCount` must be set which is used to determine how close we are to the
/// threshold.
/// * A `MinNominatorBond` and `MinValidatorBond` must be set and checked, which determines
/// if this is a person that should be chilled because they have not met the threshold
/// bond required.
Expand Down Expand Up @@ -1984,7 +1977,7 @@ pub mod pallet {
//
// * A `ChillThreshold` is set which defines how close to the max nominators or
// validators we must reach before users can start chilling one-another.
// * A `MaxNominatorCount` and `MaxValidatorCount` which is used to determine how close
// * A `MaxNominatorCount` and `MaxValidatorsCount` which is used to determine how close
// we are to the threshold.
// * A `MinNominatorBond` and `MinValidatorBond` which is the final condition checked to
// determine this is a person that should be chilled because they have not met the
Expand All @@ -2009,8 +2002,7 @@ pub mod pallet {
);
MinNominatorBond::<T>::get()
} else if Validators::<T>::contains_key(&stash) {
let max_validator_count =
MaxValidatorsCount::<T>::get().ok_or(Error::<T>::CannotChillOther)?;
let max_validator_count = T::MaxValidatorsCount::get();
let current_validator_count = Validators::<T>::count();
ensure!(
threshold * max_validator_count < current_validator_count,
Expand Down
Loading

0 comments on commit e986264

Please sign in to comment.