Newer
Older
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
// first run -- ok
assert_eq!(
offchain_election::set_check_offchain_execution_status::<Test>(12),
Ok(()),
);
assert_eq!(storage.get::<BlockNumber>().unwrap().unwrap(), 12);
// re-execute after the next. not allowed.
assert_eq!(
offchain_election::set_check_offchain_execution_status::<Test>(13),
Err("recently executed."),
);
// a fork like situation -- re-execute 10, 11, 12. But it won't go through.
assert_eq!(
offchain_election::set_check_offchain_execution_status::<Test>(10),
Err("fork."),
);
assert_eq!(
offchain_election::set_check_offchain_execution_status::<Test>(11),
Err("fork."),
);
assert_eq!(
offchain_election::set_check_offchain_execution_status::<Test>(12),
Err("recently executed."),
);
})
}
#[test]
#[should_panic]
fn offence_is_blocked_when_window_open() {
ExtBuilder::default()
.offchain_election_ext()
.validator_count(4)
.has_stakers(false)
.build()
.execute_with(|| {
run_to_block(12);
assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12));
let offender_expo = Staking::eras_stakers(Staking::active_era().unwrap().index, 10);
// panic from the impl in mock
on_offence_now(
&[OffenceDetails {
offender: (10, offender_expo.clone()),
reporters: vec![],
}],
&[Perbill::from_percent(10)],
);
})
}
}
fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_validator() {
ExtBuilder::default().build_and_execute(|| {
assert_eq_uvec!(Session::validators(), vec![11, 21]);
assert_eq!(Balances::free_balance(11), 1000);
assert_eq!(Balances::free_balance(101), 2000);
// 11 and 21 both have the support of 100
let exposure_11 = Staking::eras_stakers(Staking::active_era().unwrap().index, &11);
let exposure_21 = Staking::eras_stakers(Staking::active_era().unwrap().index, &21);
assert_eq!(exposure_11.total, 1000 + 125);
assert_eq!(exposure_21.total, 1000 + 375);
on_offence_now(
&[OffenceDetails {
offender: (11, exposure_11.clone()),
reporters: vec![],
}],
&[Perbill::from_percent(10)],
);
// post-slash balance
let nominator_slash_amount_11 = 125 / 10;
assert_eq!(Balances::free_balance(11), 900);
assert_eq!(
Balances::free_balance(101),
2000 - nominator_slash_amount_11
);
// This is the best way to check that the validator was chilled; `get` will
// return default value.
for (stash, _) in <Staking as Store>::Validators::iter() {
assert!(stash != 11);
}
let nominations = <Staking as Store>::Nominators::get(&101).unwrap();
// and make sure that the vote will be ignored even if the validator
// re-registers.
let last_slash = <Staking as Store>::SlashingSpans::get(&11)
.unwrap()
.last_nonzero_slash();
assert!(nominations.submitted_in < last_slash);
// actually re-bond the slashed validator
assert_ok!(Staking::validate(Origin::signed(10), Default::default()));
let exposure_11 = Staking::eras_stakers(Staking::active_era().unwrap().index, &11);
let exposure_21 = Staking::eras_stakers(Staking::active_era().unwrap().index, &21);
// 10 is re-elected, but without the support of 100
assert_eq!(exposure_11.total, 900);
// 20 is re-elected, with the (almost) entire support of 100
assert_eq!(exposure_21.total, 1000 + 500 - nominator_slash_amount_11);
}
#[test]
fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() {
// should check that:
// * rewards get paid until history_depth for both validators and nominators
// * an invalid era to claim doesn't update last_reward
// * double claim of one era fails
ExtBuilder::default().nominate(true).build_and_execute(|| {
let init_balance_10 = Balances::total_balance(&10);
let init_balance_100 = Balances::total_balance(&100);
let part_for_10 = Perbill::from_rational_approximation::<u32>(1000, 1125);
let part_for_100 = Perbill::from_rational_approximation::<u32>(125, 1125);
// Check state
Payee::<Test>::insert(11, RewardDestination::Controller);
Payee::<Test>::insert(101, RewardDestination::Controller);
<Module<Test>>::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(3000);
assert!(total_payout_0 > 10); // Test is meaningful if reward something
<Module<Test>>::reward_by_ids(vec![(11, 1)]);
// Change total issuance in order to modify total payout
let _ = Balances::deposit_creating(&999, 1_000_000_000);
// Compute total payout now for whole duration as other parameter won't change
let total_payout_1 = current_total_payout_for_duration(3000);
assert!(total_payout_1 > 10); // Test is meaningful if reward something
assert!(total_payout_1 != total_payout_0);
<Module<Test>>::reward_by_ids(vec![(11, 1)]);
// Change total issuance in order to modify total payout
let _ = Balances::deposit_creating(&999, 1_000_000_000);
// Compute total payout now for whole duration as other parameter won't change
let total_payout_2 = current_total_payout_for_duration(3000);
assert!(total_payout_2 > 10); // Test is meaningful if reward something
assert!(total_payout_2 != total_payout_0);
assert!(total_payout_2 != total_payout_1);
mock::start_era(Staking::history_depth() + 1);
let active_era = Staking::active_era().unwrap().index;
// This is the latest planned era in staking, not the active era
let current_era = Staking::current_era().unwrap();
// Last kept is 1:
assert!(current_era - Staking::history_depth() == 1);
assert_noop!(
Staking::payout_stakers(Origin::signed(1337), 11, 0),
// Fail: Era out of history
Error::<Test>::InvalidEraToReward
);
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1));
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 2));
Staking::payout_stakers(Origin::signed(1337), 11, 2),
Staking::payout_stakers(Origin::signed(1337), 11, active_era),
// Fail: Era not finished yet
Error::<Test>::InvalidEraToReward
);
// Era 0 can't be rewarded anymore and current era can't be rewarded yet
// only era 1 and 2 can be rewarded.
assert_eq!(
Balances::total_balance(&10),
init_balance_10 + part_for_10 * (total_payout_1 + total_payout_2),
);
assert_eq!(
Balances::total_balance(&100),
init_balance_100 + part_for_100 * (total_payout_1 + total_payout_2),
);
});
}
#[test]
fn zero_slash_keeps_nominators() {
ExtBuilder::default().build_and_execute(|| {
assert_eq!(Balances::free_balance(11), 1000);
let exposure = Staking::eras_stakers(Staking::active_era().unwrap().index, 11);
assert_eq!(Balances::free_balance(101), 2000);
on_offence_now(
&[
OffenceDetails {
offender: (11, exposure.clone()),
reporters: vec![],
},
],
&[Perbill::from_percent(0)],
);
assert_eq!(Balances::free_balance(11), 1000);
assert_eq!(Balances::free_balance(101), 2000);
// This is the best way to check that the validator was chilled; `get` will
// return default value.
for (stash, _) in <Staking as Store>::Validators::iter() {
assert!(stash != 11);
}
let nominations = <Staking as Store>::Nominators::get(&101).unwrap();
// and make sure that the vote will not be ignored, because the slash was
// zero.
let last_slash = <Staking as Store>::SlashingSpans::get(&11).unwrap().last_nonzero_slash();
assert!(nominations.submitted_in >= last_slash);
});
}
ExtBuilder::default().build_and_execute(|| {
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
use pallet_session::SessionManager;
let val_set = Session::validators();
let init_session = Session::current_index();
let init_active_era = Staking::active_era().unwrap().index;
// pallet-session is delaying session by one, thus the next session to plan is +2.
assert_eq!(<Staking as SessionManager<_>>::new_session(init_session + 2), None);
assert_eq!(<Staking as SessionManager<_>>::new_session(init_session + 3), Some(val_set.clone()));
assert_eq!(<Staking as SessionManager<_>>::new_session(init_session + 4), None);
assert_eq!(<Staking as SessionManager<_>>::new_session(init_session + 5), None);
assert_eq!(<Staking as SessionManager<_>>::new_session(init_session + 6), Some(val_set.clone()));
<Staking as SessionManager<_>>::end_session(init_session);
<Staking as SessionManager<_>>::start_session(init_session + 1);
assert_eq!(Staking::active_era().unwrap().index, init_active_era);
<Staking as SessionManager<_>>::end_session(init_session + 1);
<Staking as SessionManager<_>>::start_session(init_session + 2);
assert_eq!(Staking::active_era().unwrap().index, init_active_era);
// Reward current era
Staking::reward_by_ids(vec![(11, 1)]);
// New active era is triggered here.
<Staking as SessionManager<_>>::end_session(init_session + 2);
<Staking as SessionManager<_>>::start_session(init_session + 3);
assert_eq!(Staking::active_era().unwrap().index, init_active_era + 1);
<Staking as SessionManager<_>>::end_session(init_session + 3);
<Staking as SessionManager<_>>::start_session(init_session + 4);
assert_eq!(Staking::active_era().unwrap().index, init_active_era + 1);
<Staking as SessionManager<_>>::end_session(init_session + 4);
<Staking as SessionManager<_>>::start_session(init_session + 5);
assert_eq!(Staking::active_era().unwrap().index, init_active_era + 1);
// Reward current era
Staking::reward_by_ids(vec![(21, 2)]);
// New active era is triggered here.
<Staking as SessionManager<_>>::end_session(init_session + 5);
<Staking as SessionManager<_>>::start_session(init_session + 6);
assert_eq!(Staking::active_era().unwrap().index, init_active_era + 2);
// That reward are correct
assert_eq!(Staking::eras_reward_points(init_active_era).total, 1);
assert_eq!(Staking::eras_reward_points(init_active_era + 1).total, 2);
});
}
#[test]
fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward() {
// Test:
// * If nominator nomination is below the $MaxNominatorRewardedPerValidator other nominator
// then the nominator can't claim its reward
// * A nominator can't claim another nominator reward
ExtBuilder::default().build_and_execute(|| {
for i in 0..=<Test as Trait>::MaxNominatorRewardedPerValidator::get() {
let stash = 10_000 + i as AccountId;
let controller = 20_000 + i as AccountId;
let balance = 10_000 + i as Balance;
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
Balances::make_free_balance_be(&stash, balance);
assert_ok!(
Staking::bond(
Origin::signed(stash),
controller,
balance,
RewardDestination::Stash
)
);
assert_ok!(Staking::nominate(Origin::signed(controller), vec![11]));
}
mock::start_era(1);
<Module<Test>>::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);
mock::make_all_reward_payment(1);
// Assert only nominators from 1 to Max are rewarded
for i in 0..=<Test as Trait>::MaxNominatorRewardedPerValidator::get() {
let stash = 10_000 + i as AccountId;
let balance = 10_000 + i as Balance;
if stash == 10_000 {
assert!(Balances::free_balance(&stash) == balance);
} else {
assert!(Balances::free_balance(&stash) > balance);
}
}
});
}
#[test]
fn set_history_depth_works() {
ExtBuilder::default().build_and_execute(|| {
Staking::set_history_depth(Origin::root(), 20, 0).unwrap();
assert!(<Staking as Store>::ErasTotalStake::contains_key(10 - 4));
assert!(<Staking as Store>::ErasTotalStake::contains_key(10 - 5));
Staking::set_history_depth(Origin::root(), 4, 0).unwrap();
assert!(<Staking as Store>::ErasTotalStake::contains_key(10 - 4));
assert!(!<Staking as Store>::ErasTotalStake::contains_key(10 - 5));
Staking::set_history_depth(Origin::root(), 3, 0).unwrap();
assert!(!<Staking as Store>::ErasTotalStake::contains_key(10 - 4));
assert!(!<Staking as Store>::ErasTotalStake::contains_key(10 - 5));
Staking::set_history_depth(Origin::root(), 8, 0).unwrap();
assert!(!<Staking as Store>::ErasTotalStake::contains_key(10 - 4));
assert!(!<Staking as Store>::ErasTotalStake::contains_key(10 - 5));
});
}
#[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.
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
bond_validator(11, 10, balance); // Default(64)
// Create nominators, targeting stash of validators
for i in 0..100 {
bond_nominator(1000 + i, 100 + i, balance + i as Balance, vec![11]);
}
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));
// Top 64 nominators of validator 11 automatically paid out, including the validator
// Validator payout goes to controller.
assert!(Balances::free_balance(&10) > balance);
for i in 36..100 {
assert!(Balances::free_balance(&(100 + i)) > balance + i as Balance);
}
// The bottom 36 do not
for i in 0..36 {
assert_eq!(Balances::free_balance(&(100 + i)), balance + i as Balance);
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
}
// We track rewards in `claimed_rewards` vec
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![1] })
);
for i in 3..16 {
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(i);
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, i - 1));
}
// We track rewards in `claimed_rewards` vec
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: (1..=14).collect() })
);
for i in 16..100 {
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(i);
}
// We clean it up as history passes
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 15));
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 98));
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![15, 98] })
);
// Out of order claims works.
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 69));
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 23));
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 42));
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![], claimed_rewards: vec![15, 23, 42, 69, 98] })
);
});
}
#[test]
fn payout_stakers_handles_basic_errors() {
// Here we will test payouts handle all errors.
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
// Same setup as the test above
let balance = 1000;
bond_validator(11, 10, balance); // Default(64)
// Create nominators, targeting stash
for i in 0..100 {
bond_nominator(1000 + i, 100 + i, balance + i as Balance, vec![11]);
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
}
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);
// Wrong Era, too big
assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 2), Error::<Test>::InvalidEraToReward);
// Wrong Staker
assert_noop!(Staking::payout_stakers(Origin::signed(1337), 10, 1), Error::<Test>::NotStash);
for i in 3..100 {
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(i);
}
// We are at era 99, with history depth of 84
// We should be able to payout era 15 through 98 (84 total eras), but not 14 or 99.
assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 14), Error::<Test>::InvalidEraToReward);
assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 99), Error::<Test>::InvalidEraToReward);
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 15));
assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 98));
// Can't claim again
assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 15), Error::<Test>::AlreadyClaimed);
assert_noop!(Staking::payout_stakers(Origin::signed(1337), 11, 98), Error::<Test>::AlreadyClaimed);
});
}
#[test]
fn bond_during_era_correctly_populates_claimed_rewards() {
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
// Era = None
bond_validator(9, 8, 1000);
assert_eq!(
Staking::ledger(&8),
Some(StakingLedger {
stash: 9,
total: 1000,
active: 1000,
unlocking: vec![],
claimed_rewards: vec![],
})
);
mock::start_era(5);
bond_validator(11, 10, 1000);
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger {
stash: 11,
total: 1000,
active: 1000,
unlocking: vec![],
claimed_rewards: (0..5).collect(),
})
);
mock::start_era(99);
bond_validator(13, 12, 1000);
assert_eq!(
Staking::ledger(&12),
Some(StakingLedger {
stash: 13,
total: 1000,
active: 1000,
unlocking: vec![],
claimed_rewards: (15..99).collect(),
})
);
});
}
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
#[test]
fn offences_weight_calculated_correctly() {
ExtBuilder::default().nominate(true).build_and_execute(|| {
// On offence with zero offenders: 4 Reads, 1 Write
let zero_offence_weight = <Test as frame_system::Trait>::DbWeight::get().reads_writes(4, 1);
assert_eq!(Staking::on_offence(&[], &[Perbill::from_percent(50)], 0), Ok(zero_offence_weight));
// On Offence with N offenders, Unapplied: 4 Reads, 1 Write + 4 Reads, 5 Writes
let n_offence_unapplied_weight = <Test as frame_system::Trait>::DbWeight::get().reads_writes(4, 1)
+ <Test as frame_system::Trait>::DbWeight::get().reads_writes(4, 5);
let offenders: Vec<OffenceDetails<<Test as frame_system::Trait>::AccountId, pallet_session::historical::IdentificationTuple<Test>>>
= (1..10).map(|i|
OffenceDetails {
offender: (i, Staking::eras_stakers(Staking::active_era().unwrap().index, i)),
reporters: vec![],
}
).collect();
assert_eq!(Staking::on_offence(&offenders, &[Perbill::from_percent(50)], 0), Ok(n_offence_unapplied_weight));
// On Offence with one offenders, Applied
let one_offender = [
OffenceDetails {
offender: (11, Staking::eras_stakers(Staking::active_era().unwrap().index, 11)),
reporters: vec![1],
},
];
let n = 1; // Number of offenders
let rw = 3 + 3 * n; // rw reads and writes
let one_offence_unapplied_weight = <Test as frame_system::Trait>::DbWeight::get().reads_writes(4, 1)
+ <Test as frame_system::Trait>::DbWeight::get().reads_writes(rw, rw)
// One `slash_cost`
+ <Test as frame_system::Trait>::DbWeight::get().reads_writes(6, 5)
// `slash_cost` * nominators (1)
+ <Test as frame_system::Trait>::DbWeight::get().reads_writes(6, 5)
// `reward_cost` * reporters (1)
+ <Test as frame_system::Trait>::DbWeight::get().reads_writes(2, 2);
assert_eq!(Staking::on_offence(&one_offender, &[Perbill::from_percent(50)], 0), Ok(one_offence_unapplied_weight));
});
}
#[test]
fn on_initialize_weight_is_correct() {
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
assert_eq!(Validators::<Test>::iter().count(), 0);
assert_eq!(Nominators::<Test>::iter().count(), 0);
// When this pallet has nothing, we do 4 reads each block
let base_weight = <Test as frame_system::Trait>::DbWeight::get().reads(4);
assert_eq!(base_weight, Staking::on_initialize(0));
});
ExtBuilder::default()
.offchain_election_ext()
.validator_count(4)
.has_stakers(false)
.build()
.execute_with(|| {
crate::tests::offchain_election::build_offchain_election_test_ext();
run_to_block(11);
Staking::on_finalize(System::block_number());
System::set_block_number((System::block_number() + 1).into());
Timestamp::set_timestamp(System::block_number() * 1000 + INIT_TIMESTAMP);
Session::on_initialize(System::block_number());
assert_eq!(Validators::<Test>::iter().count(), 4);
assert_eq!(Nominators::<Test>::iter().count(), 5);
// With 4 validators and 5 nominator, we should increase weight by:
// - (4 + 5) reads
// - 3 Writes
let final_weight = <Test as frame_system::Trait>::DbWeight::get().reads_writes(4 + 9, 3);
assert_eq!(final_weight, Staking::on_initialize(System::block_number()));
});
}
#[test]
fn payout_creates_controller() {
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
let balance = 1000;
// Create a validator:
bond_validator(11, 10, balance);
// Create a stash/controller pair
bond_nominator(1234, 1337, 100, vec![11]);
// kill controller
assert_ok!(Balances::transfer(Origin::signed(1337), 1234, 100));
assert_eq!(Balances::free_balance(1337), 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));
// Controller is created
assert!(Balances::free_balance(1337) > 0);
})
}
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
#[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);
})
}