mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
staking: Fix Reward usage (#10887)
* staking: Fix `Reward` usage
* Some small fixes
* Check on_unbalanced was called
* Improve tests
* Add not for Reward; FMT
* 🤦
Co-authored-by: parity-processbot <>
This commit is contained in:
@@ -237,6 +237,7 @@ const THRESHOLDS: [sp_npos_elections::VoteWeight; 9] =
|
||||
parameter_types! {
|
||||
pub static BagThresholds: &'static [sp_npos_elections::VoteWeight] = &THRESHOLDS;
|
||||
pub static MaxNominations: u32 = 16;
|
||||
pub static RewardOnUnbalanceWasCalled: bool = false;
|
||||
}
|
||||
|
||||
impl pallet_bags_list::Config for Test {
|
||||
@@ -255,6 +256,13 @@ impl onchain::Config for OnChainSeqPhragmen {
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
pub struct MockReward {}
|
||||
impl OnUnbalanced<PositiveImbalanceOf<Test>> for MockReward {
|
||||
fn on_unbalanced(_: PositiveImbalanceOf<Test>) {
|
||||
RewardOnUnbalanceWasCalled::set(true);
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::pallet::pallet::Config for Test {
|
||||
type MaxNominations = MaxNominations;
|
||||
type Currency = Balances;
|
||||
@@ -263,7 +271,7 @@ impl crate::pallet::pallet::Config for Test {
|
||||
type RewardRemainder = RewardRemainderMock;
|
||||
type Event = Event;
|
||||
type Slash = ();
|
||||
type Reward = ();
|
||||
type Reward = MockReward;
|
||||
type SessionsPerEra = SessionsPerEra;
|
||||
type SlashDeferDuration = SlashDeferDuration;
|
||||
type SlashCancelOrigin = frame_system::EnsureRoot<Self::AccountId>;
|
||||
|
||||
@@ -174,11 +174,13 @@ impl<T: Config> Pallet<T> {
|
||||
|
||||
Self::deposit_event(Event::<T>::PayoutStarted(era, ledger.stash.clone()));
|
||||
|
||||
let mut total_imbalance = PositiveImbalanceOf::<T>::zero();
|
||||
// We can now make total validator payout:
|
||||
if let Some(imbalance) =
|
||||
Self::make_payout(&ledger.stash, validator_staking_payout + validator_commission_payout)
|
||||
{
|
||||
Self::deposit_event(Event::<T>::Rewarded(ledger.stash, imbalance.peek()));
|
||||
total_imbalance.subsume(imbalance);
|
||||
}
|
||||
|
||||
// Track the number of payout ops to nominators. Note:
|
||||
@@ -199,9 +201,11 @@ impl<T: Config> Pallet<T> {
|
||||
nominator_payout_count += 1;
|
||||
let e = Event::<T>::Rewarded(nominator.who.clone(), imbalance.peek());
|
||||
Self::deposit_event(e);
|
||||
total_imbalance.subsume(imbalance);
|
||||
}
|
||||
}
|
||||
|
||||
T::Reward::on_unbalanced(total_imbalance);
|
||||
debug_assert!(nominator_payout_count <= T::MaxNominatorRewardedPerValidator::get());
|
||||
Ok(Some(T::WeightInfo::payout_stakers_alive_staked(nominator_payout_count)).into())
|
||||
}
|
||||
|
||||
@@ -121,6 +121,8 @@ pub mod pallet {
|
||||
type Slash: OnUnbalanced<NegativeImbalanceOf<Self>>;
|
||||
|
||||
/// Handler for the unbalanced increment when rewarding a staker.
|
||||
/// NOTE: in most cases, the implementation of `OnUnbalanced` should modify the total
|
||||
/// issuance.
|
||||
type Reward: OnUnbalanced<PositiveImbalanceOf<Self>>;
|
||||
|
||||
/// Number of sessions per era.
|
||||
|
||||
@@ -3370,26 +3370,47 @@ fn set_history_depth_works() {
|
||||
|
||||
#[test]
|
||||
fn test_payout_stakers() {
|
||||
// Here we will test validator can set `max_nominators_payout` and it works.
|
||||
// We also test that `payout_extra_nominators` works.
|
||||
// Test that payout_stakers work in general, including that only the top
|
||||
// `T::MaxNominatorRewardedPerValidator` nominators are rewarded.
|
||||
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
|
||||
let balance = 1000;
|
||||
// Track the exposure of the validator and all nominators.
|
||||
let mut total_exposure = balance;
|
||||
// Track the exposure of the validator and the nominators that will get paid out.
|
||||
let mut payout_exposure = balance;
|
||||
// Create a validator:
|
||||
bond_validator(11, 10, balance); // Default(64)
|
||||
assert_eq!(Validators::<Test>::count(), 1);
|
||||
|
||||
// Create nominators, targeting stash of validators
|
||||
for i in 0..100 {
|
||||
bond_nominator(1000 + i, 100 + i, balance + i as Balance, vec![11]);
|
||||
let bond_amount = balance + i as Balance;
|
||||
bond_nominator(1000 + i, 100 + i, bond_amount, vec![11]);
|
||||
total_exposure += bond_amount;
|
||||
if i >= 36 {
|
||||
payout_exposure += bond_amount;
|
||||
};
|
||||
}
|
||||
let payout_exposure_part = Perbill::from_rational(payout_exposure, total_exposure);
|
||||
|
||||
mock::start_active_era(1);
|
||||
Staking::reward_by_ids(vec![(11, 1)]);
|
||||
|
||||
// compute and ensure the reward amount is greater than zero.
|
||||
let _ = current_total_payout_for_duration(reward_time_per_era());
|
||||
let payout = current_total_payout_for_duration(reward_time_per_era());
|
||||
let actual_paid_out = payout_exposure_part * payout;
|
||||
|
||||
mock::start_active_era(2);
|
||||
|
||||
let pre_payout_total_issuance = Balances::total_issuance();
|
||||
RewardOnUnbalanceWasCalled::set(false);
|
||||
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1));
|
||||
assert_eq_error_rate!(
|
||||
Balances::total_issuance(),
|
||||
pre_payout_total_issuance + actual_paid_out,
|
||||
1
|
||||
);
|
||||
assert!(RewardOnUnbalanceWasCalled::get());
|
||||
|
||||
// Top 64 nominators of validator 11 automatically paid out, including the validator
|
||||
// Validator payout goes to controller.
|
||||
@@ -3418,10 +3439,19 @@ fn test_payout_stakers() {
|
||||
Staking::reward_by_ids(vec![(11, 1)]);
|
||||
|
||||
// compute and ensure the reward amount is greater than zero.
|
||||
let _ = current_total_payout_for_duration(reward_time_per_era());
|
||||
let payout = current_total_payout_for_duration(reward_time_per_era());
|
||||
let actual_paid_out = payout_exposure_part * payout;
|
||||
let pre_payout_total_issuance = Balances::total_issuance();
|
||||
|
||||
mock::start_active_era(i);
|
||||
RewardOnUnbalanceWasCalled::set(false);
|
||||
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, i - 1));
|
||||
assert_eq_error_rate!(
|
||||
Balances::total_issuance(),
|
||||
pre_payout_total_issuance + actual_paid_out,
|
||||
1
|
||||
);
|
||||
assert!(RewardOnUnbalanceWasCalled::get());
|
||||
}
|
||||
|
||||
// We track rewards in `claimed_rewards` vec
|
||||
|
||||
Reference in New Issue
Block a user