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.
This commit is contained in:
Ross Bulat
2023-09-18 18:32:30 +01:00
committed by GitHub
parent a181ced46b
commit ffe5db0f76
3 changed files with 31 additions and 10 deletions
+15 -8
View File
@@ -236,11 +236,12 @@ impl<T: Config> Pallet<T> {
let mut total_imbalance = PositiveImbalanceOf::<T>::zero(); let mut total_imbalance = PositiveImbalanceOf::<T>::zero();
// We can now make total validator payout: // 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::make_payout(&ledger.stash, validator_staking_payout + validator_commission_payout)
{ {
Self::deposit_event(Event::<T>::Rewarded { Self::deposit_event(Event::<T>::Rewarded {
stash: ledger.stash, stash: ledger.stash,
dest,
amount: imbalance.peek(), amount: imbalance.peek(),
}); });
total_imbalance.subsume(imbalance); total_imbalance.subsume(imbalance);
@@ -259,11 +260,14 @@ impl<T: Config> Pallet<T> {
let nominator_reward: BalanceOf<T> = let nominator_reward: BalanceOf<T> =
nominator_exposure_part * validator_leftover_payout; nominator_exposure_part * validator_leftover_payout;
// We can now make nominator 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`. // Note: this logic does not count payouts for `RewardDestination::None`.
nominator_payout_count += 1; nominator_payout_count += 1;
let e = let e = Event::<T>::Rewarded {
Event::<T>::Rewarded { stash: nominator.who.clone(), amount: imbalance.peek() }; stash: nominator.who.clone(),
dest,
amount: imbalance.peek(),
};
Self::deposit_event(e); Self::deposit_event(e);
total_imbalance.subsume(imbalance); total_imbalance.subsume(imbalance);
} }
@@ -293,9 +297,11 @@ impl<T: Config> Pallet<T> {
/// Actually make a payment to a staker. This uses the currency's reward function /// Actually make a payment to a staker. This uses the currency's reward function
/// to pay the right payee for the given staker account. /// to pay the right payee for the given staker account.
fn make_payout(stash: &T::AccountId, amount: BalanceOf<T>) -> Option<PositiveImbalanceOf<T>> { fn make_payout(
let dest = Self::payee(stash); stash: &T::AccountId,
match dest { amount: BalanceOf<T>,
) -> Option<(PositiveImbalanceOf<T>, RewardDestination<T::AccountId>)> {
let maybe_imbalance = match Self::payee(stash) {
RewardDestination::Controller => Self::bonded(stash) RewardDestination::Controller => Self::bonded(stash)
.map(|controller| T::Currency::deposit_creating(&controller, amount)), .map(|controller| T::Currency::deposit_creating(&controller, amount)),
RewardDestination::Stash => T::Currency::deposit_into_existing(stash, amount).ok(), RewardDestination::Stash => T::Currency::deposit_into_existing(stash, amount).ok(),
@@ -311,7 +317,8 @@ impl<T: Config> Pallet<T> {
RewardDestination::Account(dest_account) => RewardDestination::Account(dest_account) =>
Some(T::Currency::deposit_creating(&dest_account, amount)), Some(T::Currency::deposit_creating(&dest_account, amount)),
RewardDestination::None => None, RewardDestination::None => None,
} };
maybe_imbalance.map(|imbalance| (imbalance, Self::payee(stash)))
} }
/// Plan a new session potentially trigger a new era. /// Plan a new session potentially trigger a new era.
+6 -2
View File
@@ -664,8 +664,12 @@ pub mod pallet {
/// The era payout has been set; the first balance is the validator-payout; the second is /// The era payout has been set; the first balance is the validator-payout; the second is
/// the remainder from the maximum amount of reward. /// the remainder from the maximum amount of reward.
EraPaid { era_index: EraIndex, validator_payout: BalanceOf<T>, remainder: BalanceOf<T> }, EraPaid { era_index: EraIndex, validator_payout: BalanceOf<T>, remainder: BalanceOf<T> },
/// The nominator has been rewarded by this amount. /// The nominator has been rewarded by this amount to this destination.
Rewarded { stash: T::AccountId, amount: BalanceOf<T> }, Rewarded {
stash: T::AccountId,
dest: RewardDestination<T::AccountId>,
amount: BalanceOf<T>,
},
/// A staker (validator or nominator) has been slashed by the given amount. /// A staker (validator or nominator) has been slashed by the given amount.
Slashed { staker: T::AccountId, amount: BalanceOf<T> }, Slashed { staker: T::AccountId, amount: BalanceOf<T> },
/// A slash for the given validator, for the given percentage of their stake, at the given /// A slash for the given validator, for the given percentage of their stake, at the given
+10
View File
@@ -3759,6 +3759,16 @@ fn test_payout_stakers() {
); );
assert!(RewardOnUnbalanceWasCalled::get()); 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 // Top 64 nominators of validator 11 automatically paid out, including the validator
// Validator payout goes to controller. // Validator payout goes to controller.
assert!(Balances::free_balance(&11) > balance); assert!(Balances::free_balance(&11) > balance);