From a76b751a32368b76e804b5be89ab52e74abe5aa6 Mon Sep 17 00:00:00 2001 From: Ross Bulat Date: Mon, 18 Sep 2023 18:32:30 +0100 Subject: [PATCH] Staking: Add `dest` to `Rewarded` to aid in reward calculations (#1602) Addresses https://github.com/paritytech/polkadot-sdk/issues/129. Returns `Self:payee()` from `make_payout` in a tuple alongside an imbalance & adds it to `Rewarded` event. --- substrate/frame/staking/src/pallet/impls.rs | 23 ++++++++++++++------- substrate/frame/staking/src/pallet/mod.rs | 8 +++++-- substrate/frame/staking/src/tests.rs | 10 +++++++++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index e0f5c95587818..3d9b1157ca87a 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -236,11 +236,12 @@ impl Pallet { let mut total_imbalance = PositiveImbalanceOf::::zero(); // We can now make total validator payout: - if let Some(imbalance) = + if let Some((imbalance, dest)) = Self::make_payout(&ledger.stash, validator_staking_payout + validator_commission_payout) { Self::deposit_event(Event::::Rewarded { stash: ledger.stash, + dest, amount: imbalance.peek(), }); total_imbalance.subsume(imbalance); @@ -259,11 +260,14 @@ impl Pallet { let nominator_reward: BalanceOf = nominator_exposure_part * validator_leftover_payout; // We can now make nominator payout: - if let Some(imbalance) = Self::make_payout(&nominator.who, nominator_reward) { + if let Some((imbalance, dest)) = Self::make_payout(&nominator.who, nominator_reward) { // Note: this logic does not count payouts for `RewardDestination::None`. nominator_payout_count += 1; - let e = - Event::::Rewarded { stash: nominator.who.clone(), amount: imbalance.peek() }; + let e = Event::::Rewarded { + stash: nominator.who.clone(), + dest, + amount: imbalance.peek(), + }; Self::deposit_event(e); total_imbalance.subsume(imbalance); } @@ -293,9 +297,11 @@ impl Pallet { /// Actually make a payment to a staker. This uses the currency's reward function /// to pay the right payee for the given staker account. - fn make_payout(stash: &T::AccountId, amount: BalanceOf) -> Option> { - let dest = Self::payee(stash); - match dest { + fn make_payout( + stash: &T::AccountId, + amount: BalanceOf, + ) -> Option<(PositiveImbalanceOf, RewardDestination)> { + let maybe_imbalance = match Self::payee(stash) { RewardDestination::Controller => Self::bonded(stash) .map(|controller| T::Currency::deposit_creating(&controller, amount)), RewardDestination::Stash => T::Currency::deposit_into_existing(stash, amount).ok(), @@ -311,7 +317,8 @@ impl Pallet { RewardDestination::Account(dest_account) => Some(T::Currency::deposit_creating(&dest_account, amount)), RewardDestination::None => None, - } + }; + maybe_imbalance.map(|imbalance| (imbalance, Self::payee(stash))) } /// Plan a new session potentially trigger a new era. diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index c6c75326b80cd..0bcf932d90b44 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -664,8 +664,12 @@ pub mod pallet { /// The era payout has been set; the first balance is the validator-payout; the second is /// the remainder from the maximum amount of reward. EraPaid { era_index: EraIndex, validator_payout: BalanceOf, remainder: BalanceOf }, - /// The nominator has been rewarded by this amount. - Rewarded { stash: T::AccountId, amount: BalanceOf }, + /// The nominator has been rewarded by this amount to this destination. + Rewarded { + stash: T::AccountId, + dest: RewardDestination, + amount: BalanceOf, + }, /// A staker (validator or nominator) has been slashed by the given amount. Slashed { staker: T::AccountId, amount: BalanceOf }, /// A slash for the given validator, for the given percentage of their stake, at the given diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index fd7dabac74d8d..78183cfde9296 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -3759,6 +3759,16 @@ fn test_payout_stakers() { ); assert!(RewardOnUnbalanceWasCalled::get()); + // `Rewarded` events are being executed. + assert!(matches!( + staking_events_since_last_call().as_slice(), + &[ + .., + Event::Rewarded { stash: 1037, dest: RewardDestination::Controller, amount: 108 }, + Event::Rewarded { stash: 1036, dest: RewardDestination::Controller, amount: 108 } + ] + )); + // Top 64 nominators of validator 11 automatically paid out, including the validator // Validator payout goes to controller. assert!(Balances::free_balance(&11) > balance);