Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions frame/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! Staking pallet benchmarking.

use super::*;
use crate::Pallet as Staking;
use crate::{ConfigOp, Pallet as Staking};
use testing_utils::*;

use codec::Decode;
Expand Down Expand Up @@ -852,16 +852,15 @@ benchmarks! {
assert_eq!(targets.len() as u32, v);
}

set_staking_configs {
// This function always does the same thing... just write to 4 storage items.
}: _(
set_staking_configs_all_set {
}: set_staking_configs(
RawOrigin::Root,
BalanceOf::<T>::max_value(),
BalanceOf::<T>::max_value(),
Some(u32::MAX),
Some(u32::MAX),
Some(Percent::max_value()),
Perbill::max_value()
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())
) verify {
assert_eq!(MinNominatorBond::<T>::get(), BalanceOf::<T>::max_value());
assert_eq!(MinValidatorBond::<T>::get(), BalanceOf::<T>::max_value());
Expand All @@ -871,6 +870,24 @@ benchmarks! {
assert_eq!(MinCommission::<T>::get(), Perbill::from_percent(100));
}

set_staking_configs_all_remove {
}: set_staking_configs(
RawOrigin::Root,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove
) verify {
assert!(!MinNominatorBond::<T>::exists());
assert!(!MinValidatorBond::<T>::exists());
assert!(!MaxNominatorsCount::<T>::exists());
assert!(!MaxValidatorsCount::<T>::exists());
assert!(!ChillThreshold::<T>::exists());
assert!(!MinCommission::<T>::exists());
}

chill_other {
// clean up any existing state.
clear_validators_and_nominators::<T>();
Expand All @@ -886,12 +903,12 @@ benchmarks! {

Staking::<T>::set_staking_configs(
RawOrigin::Root.into(),
BalanceOf::<T>::max_value(),
BalanceOf::<T>::max_value(),
Some(0),
Some(0),
Some(Percent::from_percent(0)),
Zero::zero(),
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()),
)?;

let caller = whitelisted_caller();
Expand Down
56 changes: 42 additions & 14 deletions frame/staking/src/pallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

use frame_election_provider_support::SortedListProvider;
use frame_support::{
dispatch::Codec,
pallet_prelude::*,
traits::{
Currency, CurrencyToVote, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get,
Expand All @@ -32,7 +33,7 @@ use sp_runtime::{
DispatchError, Perbill, Percent,
};
use sp_staking::{EraIndex, SessionIndex};
use sp_std::{convert::From, prelude::*};
use sp_std::{cmp::max, convert::From, prelude::*};

mod impls;

Expand Down Expand Up @@ -60,6 +61,17 @@ pub mod pallet {
#[pallet::without_storage_info]
pub struct Pallet<T>(_);

/// Possible operations on the configuration values of this pallet.
#[derive(TypeInfo, Debug, Clone, Encode, Decode, PartialEq)]
pub enum ConfigOp<T: Default + Codec> {
/// Don't change.
Noop,
/// Set the given value.
Set(T),
/// Remove from storage.
Remove,
}

#[pallet::config]
pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
/// The staking balance.
Expand Down Expand Up @@ -1532,23 +1544,39 @@ pub mod pallet {
///
/// NOTE: Existing nominators and validators will not be affected by this update.
/// to kick people under the new limits, `chill_other` should be called.
#[pallet::weight(T::WeightInfo::set_staking_configs())]
// We assume the worst case for this call is either: all items are set or all items are
// removed.
#[pallet::weight(max(
T::WeightInfo::set_staking_configs_all_set(),
T::WeightInfo::set_staking_configs_all_remove()
))]
pub fn set_staking_configs(
origin: OriginFor<T>,
min_nominator_bond: BalanceOf<T>,
min_validator_bond: BalanceOf<T>,
max_nominator_count: Option<u32>,
max_validator_count: Option<u32>,
chill_threshold: Option<Percent>,
min_commission: Perbill,
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>,
) -> DispatchResult {
ensure_root(origin)?;
MinNominatorBond::<T>::set(min_nominator_bond);
MinValidatorBond::<T>::set(min_validator_bond);
MaxNominatorsCount::<T>::set(max_nominator_count);
MaxValidatorsCount::<T>::set(max_validator_count);
ChillThreshold::<T>::set(chill_threshold);
MinCommission::<T>::set(min_commission);

macro_rules! config_op_exp {
($storage:ty, $op:ident) => {
match $op {
ConfigOp::Noop => (),
ConfigOp::Set(v) => <$storage>::put(v),
ConfigOp::Remove => <$storage>::kill(),
}
};
}

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);
Ok(())
}

Expand Down
138 changes: 94 additions & 44 deletions frame/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

//! Tests for the module.

use super::{Event, MaxUnlockingChunks, *};
use super::{ConfigOp, Event, MaxUnlockingChunks, *};
use frame_election_provider_support::{ElectionProvider, SortedListProvider, Support};
use frame_support::{
assert_noop, assert_ok, bounded_vec,
assert_noop, assert_ok, assert_storage_noop, bounded_vec,
dispatch::WithPostDispatchInfo,
pallet_prelude::*,
traits::{Currency, Get, ReservableCurrency},
Expand All @@ -40,6 +40,56 @@ use sp_staking::{
use sp_std::prelude::*;
use substrate_test_utils::assert_eq_uvec;

#[test]
fn set_staking_configs_works() {
ExtBuilder::default().build_and_execute(|| {
// setting works
assert_ok!(Staking::set_staking_configs(
Origin::root(),
ConfigOp::Set(1_500),
ConfigOp::Set(2_000),
ConfigOp::Set(10),
ConfigOp::Set(20),
ConfigOp::Set(Percent::from_percent(75)),
ConfigOp::Set(Zero::zero())
));
assert_eq!(MinNominatorBond::<Test>::get(), 1_500);
assert_eq!(MinValidatorBond::<Test>::get(), 2_000);
assert_eq!(MaxNominatorsCount::<Test>::get(), Some(10));
assert_eq!(MaxValidatorsCount::<Test>::get(), Some(20));
assert_eq!(ChillThreshold::<Test>::get(), Some(Percent::from_percent(75)));
assert_eq!(MinCommission::<Test>::get(), Perbill::from_percent(0));

// noop does nothing
assert_storage_noop!(assert_ok!(Staking::set_staking_configs(
Origin::root(),
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Noop
)));

// removing works
assert_ok!(Staking::set_staking_configs(
Origin::root(),
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove
));
assert_eq!(MinNominatorBond::<Test>::get(), 0);
assert_eq!(MinValidatorBond::<Test>::get(), 0);
assert_eq!(MaxNominatorsCount::<Test>::get(), None);
assert_eq!(MaxValidatorsCount::<Test>::get(), None);
assert_eq!(ChillThreshold::<Test>::get(), None);
assert_eq!(MinCommission::<Test>::get(), Perbill::from_percent(0));
});
}

#[test]
fn force_unstake_works() {
ExtBuilder::default().build_and_execute(|| {
Expand Down Expand Up @@ -4368,12 +4418,12 @@ fn chill_other_works() {
// Change the minimum bond... but no limits.
assert_ok!(Staking::set_staking_configs(
Origin::root(),
1_500,
2_000,
None,
None,
None,
Zero::zero()
ConfigOp::Set(1_500),
ConfigOp::Set(2_000),
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove
));

// Still can't chill these users
Expand All @@ -4389,12 +4439,12 @@ fn chill_other_works() {
// Add limits, but no threshold
assert_ok!(Staking::set_staking_configs(
Origin::root(),
1_500,
2_000,
Some(10),
Some(10),
None,
Zero::zero()
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Set(10),
ConfigOp::Set(10),
ConfigOp::Noop,
ConfigOp::Noop
));

// Still can't chill these users
Expand All @@ -4410,12 +4460,12 @@ fn chill_other_works() {
// Add threshold, but no limits
assert_ok!(Staking::set_staking_configs(
Origin::root(),
1_500,
2_000,
None,
None,
Some(Percent::from_percent(0)),
Zero::zero()
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Noop,
ConfigOp::Noop
));

// Still can't chill these users
Expand All @@ -4431,12 +4481,12 @@ fn chill_other_works() {
// Add threshold and limits
assert_ok!(Staking::set_staking_configs(
Origin::root(),
1_500,
2_000,
Some(10),
Some(10),
Some(Percent::from_percent(75)),
Zero::zero()
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Set(10),
ConfigOp::Set(10),
ConfigOp::Set(Percent::from_percent(75)),
ConfigOp::Noop
));

// 16 people total because tests start with 2 active one
Expand Down Expand Up @@ -4476,12 +4526,12 @@ fn capped_stakers_works() {
let max = 10;
assert_ok!(Staking::set_staking_configs(
Origin::root(),
10,
10,
Some(max),
Some(max),
Some(Percent::from_percent(0)),
Zero::zero(),
ConfigOp::Set(10),
ConfigOp::Set(10),
ConfigOp::Set(max),
ConfigOp::Set(max),
ConfigOp::Remove,
ConfigOp::Remove,
));

// can create `max - validator_count` validators
Expand Down Expand Up @@ -4546,12 +4596,12 @@ fn capped_stakers_works() {
// No problem when we set to `None` again
assert_ok!(Staking::set_staking_configs(
Origin::root(),
10,
10,
None,
None,
None,
Zero::zero(),
ConfigOp::Noop,
ConfigOp::Noop,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Noop,
ConfigOp::Noop,
));
assert_ok!(Staking::nominate(Origin::signed(last_nominator), vec![1]));
assert_ok!(Staking::validate(Origin::signed(last_validator), ValidatorPrefs::default()));
Expand All @@ -4568,12 +4618,12 @@ fn min_commission_works() {

assert_ok!(Staking::set_staking_configs(
Origin::root(),
0,
0,
None,
None,
None,
Perbill::from_percent(10),
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Remove,
ConfigOp::Set(Perbill::from_percent(10)),
));

// can't make it less than 10 now
Expand Down
Loading