From db987029eaa94355b27244ccfaec972bc7ca525b Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Thu, 6 Aug 2020 13:11:43 +0200 Subject: [PATCH 1/2] Support staking payout to any account --- frame/staking/src/lib.rs | 15 ++++++++++----- frame/staking/src/tests.rs | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 60943be82f1dc..1fb8a1d8d2a50 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -427,16 +427,18 @@ pub enum StakerStatus { /// A destination account for payment. #[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, RuntimeDebug)] -pub enum RewardDestination { +pub enum RewardDestination { /// Pay into the stash account, increasing the amount at stake accordingly. Staked, /// Pay into the stash account, not increasing the amount at stake. Stash, /// Pay into the controller account. Controller, + /// Pay into a specified account. + Account(AccountId), } -impl Default for RewardDestination { +impl Default for RewardDestination { fn default() -> Self { RewardDestination::Staked } @@ -1049,7 +1051,7 @@ decl_storage! { => Option>>; /// Where the reward payment should be made. Keyed by stash. - pub Payee get(fn payee): map hasher(twox_64_concat) T::AccountId => RewardDestination; + pub Payee get(fn payee): map hasher(twox_64_concat) T::AccountId => RewardDestination; /// The map from (wannabe) validator stash key to the preferences of that validator. pub Validators get(fn validators): @@ -1496,7 +1498,7 @@ decl_module! { pub fn bond(origin, controller: ::Source, #[compact] value: BalanceOf, - payee: RewardDestination, + payee: RewardDestination, ) { let stash = ensure_signed(origin)?; @@ -1830,7 +1832,7 @@ decl_module! { /// - Write: Payee /// # #[weight = 11 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 1)] - fn set_payee(origin, payee: RewardDestination) { + fn set_payee(origin, payee: RewardDestination) { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; let stash = &ledger.stash; @@ -2488,6 +2490,9 @@ impl Module { Self::update_ledger(&controller, &l); r }), + RewardDestination::Account(dest_account) => { + Some(T::Currency::deposit_creating(&dest_account, amount)) + } } } diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index e5015cbdc9283..59bf8c5b54c31 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -4359,7 +4359,7 @@ fn test_payout_stakers() { // We also test that `payout_extra_nominators` works. ExtBuilder::default().has_stakers(false).build_and_execute(|| { let balance = 1000; - // Create three validators: + // Create a validator: bond_validator(11, 10, balance); // Default(64) // Create nominators, targeting stash of validators @@ -4597,15 +4597,12 @@ fn on_initialize_weight_is_correct() { }); } - #[test] fn payout_creates_controller() { - // Here we will test validator can set `max_nominators_payout` and it works. - // We also test that `payout_extra_nominators` works. ExtBuilder::default().has_stakers(false).build_and_execute(|| { let balance = 1000; - // Create three validators: - bond_validator(11, 10, balance); // Default(64) + // Create a validator: + bond_validator(11, 10, balance); // Create a stash/controller pair bond_nominator(1234, 1337, 100, vec![11]); @@ -4626,3 +4623,32 @@ fn payout_creates_controller() { assert!(Balances::free_balance(1337) > 0); }) } + +#[test] +fn payout_to_any_account_works() { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + let balance = 1000; + // Create a validator: + bond_validator(11, 10, balance); // Default(64) + + // Create a stash/controller pair + bond_nominator(1234, 1337, 100, vec![11]); + + // Update payout location + assert_ok!(Staking::set_payee(Origin::signed(1337), RewardDestination::Account(42))); + + // Reward Destination account doesn't exist + assert_eq!(Balances::free_balance(42), 0); + + mock::start_era(1); + Staking::reward_by_ids(vec![(11, 1)]); + // Compute total payout now for whole duration as other parameter won't change + let total_payout_0 = current_total_payout_for_duration(3 * 1000); + assert!(total_payout_0 > 100); // Test is meaningful if reward something + mock::start_era(2); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1)); + + // Payment is successful + assert!(Balances::free_balance(42) > 0); + }) +} From b967afb81b7a409e87618509bfef8f90c26685b2 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Thu, 6 Aug 2020 13:29:43 +0200 Subject: [PATCH 2/2] fix offences benchmarks --- frame/offences/benchmarking/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index 1aa9fed85b127..e35050992368a 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -125,7 +125,7 @@ fn create_offender(n: u32, nominators: u32) -> Result, &'s RawOrigin::Signed(nominator_stash.clone()).into(), nominator_controller_lookup.clone(), amount.clone(), - reward_destination, + reward_destination.clone(), )?; let selected_validators: Vec> = vec![controller_lookup.clone()];