Skip to content
Closed
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
6 changes: 3 additions & 3 deletions substrate/frame/fast-unstake/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use frame_support::{
};
use sp_runtime::{
traits::{Convert, IdentityLookup},
BuildStorage,
BuildStorage, Perbill,
};

use pallet_staking::{Exposure, IndividualExposure, StakerStatus};
Expand Down Expand Up @@ -336,7 +336,7 @@ pub(crate) fn next_block(on_idle: bool) {

pub fn assert_unstaked(stash: &AccountId) {
assert!(!pallet_staking::Bonded::<T>::contains_key(stash));
assert!(!pallet_staking::Payee::<T>::contains_key(stash));
assert!(!pallet_staking::Payees::<T>::contains_key(stash));
assert!(!pallet_staking::Validators::<T>::contains_key(stash));
assert!(!pallet_staking::Nominators::<T>::contains_key(stash));
}
Expand All @@ -350,7 +350,7 @@ pub fn create_exposed_nominator(exposed: AccountId, era: u32) {
assert_ok!(Staking::bond(
RuntimeOrigin::signed(exposed),
10,
pallet_staking::RewardDestination::Staked
pallet_staking::PayoutDestination::Split((Perbill::from_percent(50), exposed))
));
assert_ok!(Staking::nominate(RuntimeOrigin::signed(exposed), vec![exposed]));
// register the exposed one.
Expand Down
11 changes: 8 additions & 3 deletions substrate/frame/nomination-pools/test-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ use pallet_nomination_pools::{
BondedPools, Error as PoolsError, Event as PoolsEvent, LastPoolId, PoolMember, PoolMembers,
PoolState,
};
use pallet_staking::{CurrentEra, Event as StakingEvent, Payee, RewardDestination};
use pallet_staking::{
CheckedPayoutDestination, CurrentEra, Event as StakingEvent, Payees, PayoutDestination,
};
use sp_runtime::{bounded_btree_map, traits::Zero};

#[test]
Expand Down Expand Up @@ -214,8 +216,11 @@ fn pool_slash_e2e() {
]
);

assert_eq!(Payee::<Runtime>::get(POOL1_BONDED), RewardDestination::Account(POOL1_REWARD));

assert_eq!(
Payees::<Runtime>::get(POOL1_BONDED),
CheckedPayoutDestination(PayoutDestination::Deposit(POOL1_REWARD))
);

// have two members join
assert_ok!(Pools::join(RuntimeOrigin::signed(20), 20, 1));
assert_ok!(Pools::join(RuntimeOrigin::signed(21), 20, 1));
Expand Down
76 changes: 53 additions & 23 deletions substrate/frame/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn create_validator_with_nominators<T: Config>(
upper_bound: u32,
dead_controller: bool,
unique_controller: bool,
destination: RewardDestination<T::AccountId>,
destination: PayoutRoute<T::AccountId>,
) -> Result<(T::AccountId, Vec<(T::AccountId, T::AccountId)>), &'static str> {
// Clean up any existing state.
clear_validators_and_nominators::<T>();
Expand Down Expand Up @@ -175,7 +175,7 @@ impl<T: Config> ListScenario<T> {
let (origin_stash1, origin_controller1) = create_stash_controller_with_balance::<T>(
USER_SEED + 2,
origin_weight,
Default::default(),
PayoutDestination::Stake,
)?;
Staking::<T>::nominate(
RawOrigin::Signed(origin_controller1.clone()).into(),
Expand All @@ -186,7 +186,7 @@ impl<T: Config> ListScenario<T> {
let (_origin_stash2, origin_controller2) = create_stash_controller_with_balance::<T>(
USER_SEED + 3,
origin_weight,
Default::default(),
PayoutDestination::Stake,
)?;
Staking::<T>::nominate(
RawOrigin::Signed(origin_controller2).into(),
Expand All @@ -206,7 +206,7 @@ impl<T: Config> ListScenario<T> {
let (_dest_stash1, dest_controller1) = create_stash_controller_with_balance::<T>(
USER_SEED + 1,
dest_weight,
Default::default(),
PayoutDestination::Stake,
)?;
Staking::<T>::nominate(
RawOrigin::Signed(dest_controller1).into(),
Expand All @@ -222,10 +222,10 @@ const USER_SEED: u32 = 999666;
benchmarks! {
bond {
let stash = create_funded_user::<T>("stash", USER_SEED, 100);
let reward_destination = RewardDestination::Staked;
let payout_destination = PayoutDestination::Split((Perbill::from_percent(50), stash.clone()));
let amount = T::Currency::minimum_balance() * 10u32.into();
whitelist_account!(stash);
}: _(RawOrigin::Signed(stash.clone()), amount, reward_destination)
}: _(RawOrigin::Signed(stash.clone()), amount, payout_destination)
verify {
assert!(Bonded::<T>::contains_key(stash.clone()));
assert!(Ledger::<T>::contains_key(stash));
Expand Down Expand Up @@ -290,7 +290,9 @@ benchmarks! {
withdraw_unbonded_update {
// Slashing Spans
let s in 0 .. MAX_SPANS;
let (stash, controller) = create_stash_controller::<T>(0, 100, Default::default())?;
let (stash, controller) = create_stash_controller::<T>(
0, 100, PayoutRoute::Direct(PayoutDestination::Stake)
)?;
add_slashing_spans::<T>(&stash, s);
let amount = T::Currency::minimum_balance() * 5u32.into(); // Half of total
Staking::<T>::unbond(RawOrigin::Signed(controller.clone()).into(), amount)?;
Expand Down Expand Up @@ -339,7 +341,7 @@ benchmarks! {
let (stash, controller) = create_stash_controller::<T>(
MaxNominationsOf::<T>::get() - 1,
100,
Default::default(),
PayoutRoute::Direct(PayoutDestination::Stake),
)?;
// because it is chilled.
assert!(!T::VoterList::contains(&stash));
Expand Down Expand Up @@ -367,7 +369,7 @@ benchmarks! {
let (stash, controller) = create_stash_controller::<T>(
MaxNominationsOf::<T>::get() - 1,
100,
Default::default(),
PayoutRoute::Direct(PayoutDestination::Stake),
)?;
let stash_lookup = T::Lookup::unlookup(stash.clone());

Expand All @@ -382,7 +384,7 @@ benchmarks! {
let (n_stash, n_controller) = create_stash_controller::<T>(
MaxNominationsOf::<T>::get() + i,
100,
Default::default(),
PayoutRoute::Direct(PayoutDestination::Stake),
)?;

// bake the nominations; we first clone them from the rest of the validators.
Expand Down Expand Up @@ -430,7 +432,7 @@ benchmarks! {
let (stash, controller) = create_stash_controller_with_balance::<T>(
SEED + MaxNominationsOf::<T>::get() + 1, // make sure the account does not conflict with others
origin_weight,
Default::default(),
PayoutDestination::Stake,
).unwrap();

assert!(!Nominators::<T>::contains_key(&stash));
Expand Down Expand Up @@ -464,16 +466,38 @@ benchmarks! {
}

set_payee {
let (stash, controller) = create_stash_controller::<T>(USER_SEED, 100, Default::default())?;
assert_eq!(Payee::<T>::get(&stash), RewardDestination::Staked);
let (stash, controller) = create_stash_controller::<T>(
USER_SEED, 100, PayoutRoute::Direct(PayoutDestination::Stake)
)?;
assert_eq!(Payees::<T>::get(&stash), CheckedPayoutDestination(PayoutDestination::Stake));

// Payee should exist to be migrated on `update_payee`.
DeprecatedPayee::<T>::insert(&stash,RewardDestination::Staked);
whitelist_account!(controller);
}: _(RawOrigin::Signed(controller.clone()), PayoutDestination::Split((Perbill::from_percent(50), controller.clone())))
verify {
assert!(!DeprecatedPayee::<T>::contains_key(&stash));
assert_eq!(Payees::<T>::get(&stash), CheckedPayoutDestination(PayoutDestination::Split((Perbill::from_percent(50), controller.clone()))));
}

update_payee {
let (stash, controller) = create_stash_controller::<T>(
USER_SEED, 100, PayoutRoute::Direct(PayoutDestination::Stake)
)?;
// DeprecatedPayee should exist to be migrated on `update_payee`.
DeprecatedPayee::<T>::insert(&stash,RewardDestination::Staked);
Payees::<T>::remove(&stash);
assert!(!Payees::<T>::contains_key(&stash));
whitelist_account!(controller);
}: _(RawOrigin::Signed(controller), RewardDestination::Controller)
}: _(RawOrigin::Signed(stash.clone()), controller)
verify {
assert_eq!(Payee::<T>::get(&stash), RewardDestination::Controller);
assert_eq!(Payees::<T>::get(&stash), CheckedPayoutDestination(PayoutDestination::Stake));
}

set_controller {
let (stash, ctlr) = create_unique_stash_controller::<T>(9000, 100, Default::default(), false)?;
let (stash, ctlr) = create_unique_stash_controller::<T>(
9000, 100, PayoutRoute::Direct(PayoutDestination::Stake), false
)?;
// ensure `ctlr` is the currently stored controller.
assert!(!Ledger::<T>::contains_key(&stash));
assert!(Ledger::<T>::contains_key(&ctlr));
Expand Down Expand Up @@ -558,15 +582,17 @@ benchmarks! {
T::MaxExposurePageSize::get() as u32,
true,
true,
RewardDestination::Controller,
PayoutRoute::Alias(
PayoutDestinationAlias::Split((Perbill::from_percent(50), PayoutSplitOpt::Controller))
),
)?;

let validator_controller = <Bonded<T>>::get(&validator).unwrap();
let current_era = CurrentEra::<T>::get().unwrap();
// set the commission for this particular era as well.
<ErasValidatorPrefs<T>>::insert(current_era, validator.clone(), <Staking<T>>::validators(&validator));

let caller = whitelisted_caller();
let validator_controller = <Bonded<T>>::get(&validator).unwrap();
let balance_before = T::Currency::free_balance(&validator_controller);
for (_, controller) in &nominators {
let balance = T::Currency::free_balance(controller);
Expand All @@ -592,7 +618,9 @@ benchmarks! {
T::MaxExposurePageSize::get() as u32,
false,
true,
RewardDestination::Staked,
PayoutRoute::Alias(
PayoutDestinationAlias::Split((Perbill::from_percent(50), PayoutSplitOpt::Stash))
),
)?;

let current_era = CurrentEra::<T>::get().unwrap();
Expand Down Expand Up @@ -772,7 +800,9 @@ benchmarks! {
#[extra]
do_slash {
let l in 1 .. T::MaxUnlockingChunks::get() as u32;
let (stash, controller) = create_stash_controller::<T>(0, 100, Default::default())?;
let (stash, controller) = create_stash_controller::<T>(
0, 100, PayoutRoute::Direct(PayoutDestination::Stake)
)?;
let mut staking_ledger = Ledger::<T>::get(controller.clone()).unwrap();
let unlock_chunk = UnlockChunk::<BalanceOf<T>> {
value: 1u32.into(),
Expand Down Expand Up @@ -906,7 +936,7 @@ benchmarks! {

// Create a validator with a commission of 50%
let (stash, controller) =
create_stash_controller::<T>(1, 1, RewardDestination::Staked)?;
create_stash_controller::<T>(1, 1, PayoutRoute::Direct(PayoutDestination::Stake))?;
let validator_prefs =
ValidatorPrefs { commission: Perbill::from_percent(50), ..Default::default() };
Staking::<T>::validate(RawOrigin::Signed(controller).into(), validator_prefs)?;
Expand Down Expand Up @@ -986,7 +1016,7 @@ mod tests {
<<Test as Config>::MaxExposurePageSize as Get<_>>::get(),
false,
false,
RewardDestination::Staked,
PayoutRoute::Direct(PayoutDestination::Stake),
)
.unwrap();

Expand Down Expand Up @@ -1017,7 +1047,7 @@ mod tests {
<<Test as Config>::MaxExposurePageSize as Get<_>>::get(),
false,
false,
RewardDestination::Staked,
PayoutRoute::Direct(PayoutDestination::Stake),
)
.unwrap();

Expand Down
45 changes: 31 additions & 14 deletions substrate/frame/staking/src/ledger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ use sp_staking::StakingAccount;
use sp_std::prelude::*;

use crate::{
BalanceOf, Bonded, Config, Error, Ledger, Payee, RewardDestination, StakingLedger, STAKING_ID,
BalanceOf, Bonded, CheckedPayoutDestination, Config, DeprecatedPayee, Error, Ledger, Payees,
StakingLedger, STAKING_ID,
};

#[cfg(any(feature = "runtime-benchmarks", test))]
Expand Down Expand Up @@ -120,24 +121,24 @@ impl<T: Config> StakingLedger<T> {
.ok_or(Error::<T>::NotController)
}

/// Returns the reward destination of a staking ledger, stored in [`Payee`].
/// Returns the payout destination of a staking ledger, stored in [`Payees`].
///
/// Note: if the stash is not bonded and/or does not have an entry in [`Payee`], it returns the
/// default reward destination.
/// Note: if the stash is not bonded and/or does not have an entry in [`Payees`], it returns the
/// default payout destination.
pub(crate) fn reward_destination(
account: StakingAccount<T::AccountId>,
) -> RewardDestination<T::AccountId> {
) -> CheckedPayoutDestination<T::AccountId> {
let stash = match account {
StakingAccount::Stash(stash) => Some(stash),
StakingAccount::Controller(controller) =>
Self::paired_account(StakingAccount::Controller(controller)),
};

if let Some(stash) = stash {
<Payee<T>>::get(stash)
<Payees<T>>::get(stash)
} else {
defensive!("fetched reward destination from unbonded stash {}", stash);
RewardDestination::default()
defensive!("fetched payout destination from unbonded stash {}", stash);
CheckedPayoutDestination::default()
}
}

Expand Down Expand Up @@ -181,22 +182,33 @@ impl<T: Config> StakingLedger<T> {
/// Bonds a ledger.
///
/// It sets the reward preferences for the bonded stash.
pub(crate) fn bond(self, payee: RewardDestination<T::AccountId>) -> Result<(), Error<T>> {
pub(crate) fn bond(
self,
payee: CheckedPayoutDestination<T::AccountId>,
) -> Result<(), Error<T>> {
if <Bonded<T>>::contains_key(&self.stash) {
Err(Error::<T>::AlreadyBonded)
} else {
<Payee<T>>::insert(&self.stash, payee);
<Payees<T>>::insert(&self.stash, payee);
<Bonded<T>>::insert(&self.stash, &self.stash);
self.update()
}
}

/// Sets the ledger Payee.
pub(crate) fn set_payee(self, payee: RewardDestination<T::AccountId>) -> Result<(), Error<T>> {
pub(crate) fn set_payee(
self,
payee: CheckedPayoutDestination<T::AccountId>,
) -> Result<(), Error<T>> {
if !<Bonded<T>>::contains_key(&self.stash) {
Err(Error::<T>::NotStash)
} else {
<Payee<T>>::insert(&self.stash, payee);
<Payees<T>>::insert(&self.stash, payee);
// In-progress lazy migration to `Payees` storage item.
// NOTE: To be removed in next runtime upgrade once migration is completed.
if DeprecatedPayee::<T>::contains_key(&self.stash) {
DeprecatedPayee::<T>::remove(self.stash);
}
Ok(())
}
}
Expand All @@ -209,9 +221,14 @@ impl<T: Config> StakingLedger<T> {
<Ledger<T>>::get(&controller).ok_or(Error::<T>::NotController).map(|ledger| {
T::Currency::remove_lock(STAKING_ID, &ledger.stash);
Ledger::<T>::remove(controller);

<Bonded<T>>::remove(&stash);
<Payee<T>>::remove(&stash);
// NOTE: Checks both `Payees` and `Payee` records during migration period.
// Tracking issue: <https://github.com/paritytech/polkadot-sdk/issues/1195>
if <Payees<T>>::contains_key(&stash) {
<Payees<T>>::remove(stash);
} else {
<DeprecatedPayee<T>>::remove(stash);
}

Ok(())
})?
Expand Down
Loading