Removes the Default implementation for RewardDestination (#2402)

This PR removes current default for `RewardDestination`, which may cause
confusion since a ledger should not have a default reward destination:
either it has a reward destination, or something is wrong. It also
changes the `Payee`'s reward destination in storage from `ValueQuery` to
`OptionQuery`.

In addition, it adds a `try_state` check to make sure each bonded ledger
have a valid reward destination.

Closes https://github.com/paritytech/polkadot-sdk/issues/2063

---------

Co-authored-by: command-bot <>
Co-authored-by: Ross Bulat <ross@parity.io>
This commit is contained in:
Gonçalo Pestana
2024-01-27 16:58:24 +01:00
committed by GitHub
parent 25eaa95fbf
commit a9992dbb31
8 changed files with 100 additions and 53 deletions
+44 -21
View File
@@ -771,12 +771,12 @@ fn double_staking_should_fail() {
// * an account already bonded as stash cannot be be stashed again.
// * an account already bonded as stash cannot nominate.
// * an account already bonded as controller can nominate.
ExtBuilder::default().build_and_execute(|| {
ExtBuilder::default().try_state(false).build_and_execute(|| {
let arbitrary_value = 5;
let (stash, controller) = testing_utils::create_unique_stash_controller::<Test>(
0,
arbitrary_value,
RewardDestination::default(),
RewardDestination::Staked,
false,
)
.unwrap();
@@ -786,7 +786,7 @@ fn double_staking_should_fail() {
Staking::bond(
RuntimeOrigin::signed(stash),
arbitrary_value.into(),
RewardDestination::default()
RewardDestination::Staked,
),
Error::<Test>::AlreadyBonded,
);
@@ -805,12 +805,12 @@ fn double_controlling_attempt_should_fail() {
// should test (in the same order):
// * an account already bonded as controller CANNOT be reused as the controller of another
// account.
ExtBuilder::default().build_and_execute(|| {
ExtBuilder::default().try_state(false).build_and_execute(|| {
let arbitrary_value = 5;
let (stash, _) = testing_utils::create_unique_stash_controller::<Test>(
0,
arbitrary_value,
RewardDestination::default(),
RewardDestination::Staked,
false,
)
.unwrap();
@@ -820,7 +820,7 @@ fn double_controlling_attempt_should_fail() {
Staking::bond(
RuntimeOrigin::signed(stash),
arbitrary_value.into(),
RewardDestination::default()
RewardDestination::Staked,
),
Error::<Test>::AlreadyBonded,
);
@@ -1068,8 +1068,8 @@ fn reward_destination_works() {
mock::start_active_era(1);
mock::make_all_reward_payment(0);
// Check that RewardDestination is Staked (default)
assert_eq!(Staking::payee(11.into()), RewardDestination::Staked);
// Check that RewardDestination is Staked
assert_eq!(Staking::payee(11.into()), Some(RewardDestination::Staked));
// Check that reward went to the stash account of validator
assert_eq!(Balances::free_balance(11), 1000 + total_payout_0);
// Check that amount at stake increased accordingly
@@ -1098,7 +1098,7 @@ fn reward_destination_works() {
mock::make_all_reward_payment(1);
// Check that RewardDestination is Stash
assert_eq!(Staking::payee(11.into()), RewardDestination::Stash);
assert_eq!(Staking::payee(11.into()), Some(RewardDestination::Stash));
// Check that reward went to the stash account
assert_eq!(Balances::free_balance(11), 1000 + total_payout_0 + total_payout_1);
// Record this value
@@ -1132,7 +1132,7 @@ fn reward_destination_works() {
mock::make_all_reward_payment(2);
// Check that RewardDestination is Account(11)
assert_eq!(Staking::payee(11.into()), RewardDestination::Account(11));
assert_eq!(Staking::payee(11.into()), Some(RewardDestination::Account(11)));
// Check that reward went to the controller account
assert_eq!(Balances::free_balance(11), recorded_stash_balance + total_payout_2);
// Check that amount at stake is NOT increased
@@ -1746,6 +1746,7 @@ fn reward_to_stake_works() {
.set_status(31, StakerStatus::Idle)
.set_status(41, StakerStatus::Idle)
.set_stake(21, 2000)
.try_state(false)
.build_and_execute(|| {
assert_eq!(Staking::validator_count(), 2);
// Confirm account 10 and 20 are validators
@@ -2200,7 +2201,7 @@ fn reward_validator_slashing_validator_does_not_overflow() {
let _ = Balances::make_free_balance_be(&2, stake);
// only slashes out of bonded stake are applied. without this line, it is 0.
Staking::bond(RuntimeOrigin::signed(2), stake - 1, RewardDestination::default()).unwrap();
Staking::bond(RuntimeOrigin::signed(2), stake - 1, RewardDestination::Staked).unwrap();
// Override exposure of 11
EraInfo::<Test>::set_exposure(
0,
@@ -5016,7 +5017,7 @@ mod election_data_provider {
assert_eq!(MinNominatorBond::<Test>::get(), 1);
assert_eq!(<Test as Config>::VoterList::count(), 4);
assert_ok!(Staking::bond(RuntimeOrigin::signed(4), 5, Default::default(),));
assert_ok!(Staking::bond(RuntimeOrigin::signed(4), 5, RewardDestination::Staked,));
assert_ok!(Staking::nominate(RuntimeOrigin::signed(4), vec![1]));
assert_eq!(<Test as Config>::VoterList::count(), 5);
@@ -5415,6 +5416,28 @@ fn count_check_works() {
})
}
#[test]
#[should_panic = "called `Result::unwrap()` on an `Err` value: Other(\"number of entries in payee storage items does not match the number of bonded ledgers\")"]
fn check_payee_invariant1_works() {
// A bonded ledger should always have an assigned `Payee` This test should panic as we verify
// that a bad state will panic due to the `try_state` checks in the `post_checks` in `mock`.
ExtBuilder::default().build_and_execute(|| {
let rogue_ledger = StakingLedger::<Test>::new(123456, 20);
Ledger::<Test>::insert(123456, rogue_ledger);
})
}
#[test]
#[should_panic = "called `Result::unwrap()` on an `Err` value: Other(\"number of entries in payee storage items does not match the number of bonded ledgers\")"]
fn check_payee_invariant2_works() {
// The number of entries in both `Payee` and of bonded staking ledgers should match. This test
// should panic as we verify that a bad state will panic due to the `try_state` checks in the
// `post_checks` in `mock`.
ExtBuilder::default().build_and_execute(|| {
Payee::<Test>::insert(1111, RewardDestination::Staked);
})
}
#[test]
fn min_bond_checks_work() {
ExtBuilder::default()
@@ -6734,7 +6757,7 @@ mod ledger {
#[test]
fn paired_account_works() {
ExtBuilder::default().build_and_execute(|| {
ExtBuilder::default().try_state(false).build_and_execute(|| {
assert_ok!(Staking::bond(
RuntimeOrigin::signed(10),
100,
@@ -6769,7 +6792,7 @@ mod ledger {
#[test]
fn get_ledger_works() {
ExtBuilder::default().build_and_execute(|| {
ExtBuilder::default().try_state(false).build_and_execute(|| {
// stash does not exist
assert!(StakingLedger::<Test>::get(StakingAccount::Stash(42)).is_err());
@@ -6819,7 +6842,7 @@ mod ledger {
assert_ok!(ledger.clone().bond(reward_dest));
assert!(StakingLedger::<Test>::is_bonded(StakingAccount::Stash(42)));
assert!(<Bonded<Test>>::get(&42).is_some());
assert_eq!(<Payee<Test>>::get(&42), reward_dest);
assert_eq!(<Payee<Test>>::get(&42), Some(reward_dest));
// cannot bond again.
assert!(ledger.clone().bond(reward_dest).is_err());
@@ -6857,7 +6880,7 @@ mod ledger {
Staking::set_payee(RuntimeOrigin::signed(11), RewardDestination::Controller),
Error::<Test>::ControllerDeprecated
);
assert_eq!(Payee::<Test>::get(&11), RewardDestination::Staked);
assert_eq!(Payee::<Test>::get(&11), Some(RewardDestination::Staked));
})
}
@@ -6867,18 +6890,18 @@ mod ledger {
ExtBuilder::default().build_and_execute(|| {
// migrate a `Controller` variant to `Account` variant.
Payee::<Test>::insert(11, RewardDestination::Controller);
assert_eq!(Payee::<Test>::get(&11), RewardDestination::Controller);
assert_eq!(Payee::<Test>::get(&11), Some(RewardDestination::Controller));
assert_ok!(Staking::update_payee(RuntimeOrigin::signed(11), 11));
assert_eq!(Payee::<Test>::get(&11), RewardDestination::Account(11));
assert_eq!(Payee::<Test>::get(&11), Some(RewardDestination::Account(11)));
// Do not migrate a variant if not `Controller`.
Payee::<Test>::insert(21, RewardDestination::Stash);
assert_eq!(Payee::<Test>::get(&21), RewardDestination::Stash);
assert_eq!(Payee::<Test>::get(&21), Some(RewardDestination::Stash));
assert_noop!(
Staking::update_payee(RuntimeOrigin::signed(11), 21),
Error::<Test>::NotController
);
assert_eq!(Payee::<Test>::get(&21), RewardDestination::Stash);
assert_eq!(Payee::<Test>::get(&21), Some(RewardDestination::Stash));
})
}
@@ -7016,7 +7039,7 @@ mod ledger {
#[test]
fn deprecate_controller_batch_skips_unmigrated_controller_payees() {
ExtBuilder::default().build_and_execute(|| {
ExtBuilder::default().try_state(false).build_and_execute(|| {
// Given:
let stash: u64 = 1000;