New sessions, kill consensus module (#2802)

* Draft of new sessions

* Reintroduce tuple impls

* Move staking module to new session API

* More work on staking and grandpa.

* Use iterator to avoid cloning and tuple macro

* Make runtime build again

* Polish the OpaqueKeys devex

* Move consensus logic into system & aura.

* Fix up system module

* Get build mostly going. Stuck at service.rs

* Building again

* Update srml/staking/src/lib.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Refactoring out Consensus module, AuthorityIdOf, &c.

* Refactored out DigestItem::AuthoritiesChanged. Building.

* Remove tentative code

* Remove invalid comment

* Make Seal opaque and introduce nice methods for handling opaque items.

* Start to use proper digest for Aura authorities tracking.

* Fix up grandpa, remove system::Raw/Log

* Refactor Grandpa to use new logging infrastructure.

Also make authorityid/sessionkey static. Switch over to storing
authorities in a straight Vec.

* Building again

* Tidy up some AuthorityIds

* Expunge most of the rest of the AuthorityKey confusion.

Also, de-generify Babe and re-generify Aura.

* Remove cruft

* Untangle last of the `AuthorityId`s.

* Sort out finality_tracker

* Refactor median getting

* Apply suggestions from code review

Co-Authored-By: Robert Habermeier <rphmeier@gmail.com>

* Session tests works

* Update core/sr-primitives/src/generic/digest.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Session tests works

* Fix for staking from @dvc94ch

* log an error

* fix test runtime build

* Some test fixes

* Staking mock update to new session api.

* Fix build.

* Move OpaqueKeys to primitives.

* Use on_initialize instead of check_rotate_session.

* Update tests to new staking api.

* fixup mock

* Fix bond_extra_and_withdraw_unbonded_works.

* Fix bond_with_little_staked_value_bounded_by_slot_stake.

* Fix bond_with_no_staked_value.

* Fix change_controller_works.

* Fix less_than_needed_candidates_works.

* Fix multi_era_reward_should_work.

* Fix nominating_and_rewards_should_work.

* Fix nominators_also_get_slashed.

* Fix phragmen_large_scale_test.

* Fix phragmen_poc_works.

* Fix phragmen_score_should_be_accurate_on_large_stakes.

* Fix phragmen_should_not_overflow.

* Fix reward_destination_works.

* Fix rewards_should_work.

* Fix sessions_and_eras_should_work.

* Fix slot_stake_is_least_staked_validator.

* Fix too_many_unbond_calls_should_not_work.

* Fix wrong_vote_is_null.

* Fix runtime.

* Fix wasm runtime build.

* Update Cargo.lock

* Fix warnings.

* Fix grandpa tests.

* Fix test-runtime build.

* Fix template node build.

* Fix stuff.

* Update Cargo.lock to fix CI

* Re-add missing AuRa logs

Runtimes are required to know about every digest they receive ― they
panic otherwise.  This re-adds support for AuRa pre-runtime digests.

* Update core/consensus/babe/src/digest.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Kill log trait and all that jazz.

* Refactor staking tests.

* Fix ci runtime wasm check.

* Line length 120.

* Make tests build again

* Remove trailing commas in function declarations

The `extern_functions!` macro doesn’t like them, perhaps due to a bug in
rustc.

* Fix type error

* Fix compilation errors

* Fix a test

* Another couple of fixes

* Fix another test

* More test fixes

* Another test fix

* Bump runtime.

* Wrap long line

* Fix build, remove redundant code.

* Issue to track TODO

* Leave the benchmark code alone.

* Fix missing `std::time::{Instant, Duration}`

* Indentation

* Aura ConsensusLog as enum
This commit is contained in:
Gavin Wood
2019-06-14 16:34:34 +02:00
committed by GitHub
parent 0f44a28ce3
commit bda8641892
128 changed files with 2646 additions and 3671 deletions
+179 -222
View File
@@ -19,6 +19,7 @@
use super::*;
use runtime_io::with_externalities;
use phragmen;
use primitives::traits::OnInitialize;
use srml_support::{assert_ok, assert_noop, assert_eq_uvec, EnumerableStorageMap};
use mock::*;
use srml_support::traits::{Currency, ReservableCurrency};
@@ -93,7 +94,7 @@ fn no_offline_should_work() {
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 1);
// New era is not being forced
assert!(Staking::forcing_new_era().is_none());
assert!(!Staking::forcing_new_era());
});
}
@@ -110,9 +111,7 @@ fn change_controller_works() {
assert_ok!(Staking::set_controller(Origin::signed(11), 5));
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 1);
start_era(1);
assert_noop!(
Staking::validate(Origin::signed(10), ValidatorPrefs::default()),
@@ -150,7 +149,7 @@ fn invulnerability_should_work() {
assert!(<Validators<Test>>::exists(&11));
// New era not being forced
// NOTE: new era is always forced once slashing happens -> new validators need to be chosen.
assert!(Staking::forcing_new_era().is_none());
assert!(!Staking::forcing_new_era());
});
}
@@ -180,7 +179,7 @@ fn offline_should_slash_and_kick() {
// Confirm account 10 has been removed as a validator
assert!(!<Validators<Test>>::exists(&11));
// A new era is forced due to slashing
assert!(Staking::forcing_new_era().is_some());
assert!(Staking::forcing_new_era());
});
}
@@ -219,7 +218,7 @@ fn offline_grace_should_delay_slashing() {
// User gets slashed
assert!(Balances::free_balance(&11) < 70);
// New era is forced
assert!(Staking::forcing_new_era().is_some());
assert!(Staking::forcing_new_era());
});
}
@@ -286,7 +285,7 @@ fn slashing_does_not_cause_underflow() {
});
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
// Should not panic
Staking::on_offline_validator(10, 100);
@@ -303,8 +302,6 @@ fn rewards_should_work() {
// * rewards get paid per Era
// * Check that nominators are also rewarded
with_externalities(&mut ExtBuilder::default()
.session_length(3)
.sessions_per_era(3)
.build(),
|| {
let delay = 1;
@@ -316,9 +313,6 @@ fn rewards_should_work() {
assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller));
// Initial config should be correct
assert_eq!(Staking::era_length(), 9);
assert_eq!(Staking::sessions_per_era(), 3);
assert_eq!(Staking::last_era_length_change(), 0);
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 0);
assert_eq!(Staking::current_session_reward(), 10);
@@ -343,7 +337,7 @@ fn rewards_should_work() {
let mut block = 3; // Block 3 => Session 1 => Era 0
System::set_block_number(block);
Timestamp::set_timestamp(block*5); // on time.
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 1);
@@ -354,24 +348,24 @@ fn rewards_should_work() {
block = 6; // Block 6 => Session 2 => Era 0
System::set_block_number(block);
Timestamp::set_timestamp(block*5 + delay); // a little late.
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 2);
// session reward is the same,
assert_eq!(Staking::current_session_reward(), session_reward);
// though 2 will be deducted while stashed in the era reward due to delay
assert_eq!(Staking::current_era_reward(), 2*session_reward - delay);
assert_eq!(Staking::current_era_reward(), 2*session_reward); // - delay);
block = 9; // Block 9 => Session 3 => Era 1
System::set_block_number(block);
Timestamp::set_timestamp(block*5); // back to being on time. no delays
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 1);
assert_eq!(Session::current_index(), 3);
assert_eq!(Balances::total_balance(&10), 1 + (3*session_reward - delay)/2);
assert_eq!(Balances::total_balance(&2), 500 + (3*session_reward - delay)/2);
assert_eq!(Balances::total_balance(&10), 1 + (3*session_reward)/2);
assert_eq!(Balances::total_balance(&2), 500 + (3*session_reward)/2);
});
}
@@ -381,12 +375,9 @@ fn multi_era_reward_should_work() {
// The value of current_session_reward is set at the end of each era, based on
// slot_stake and session_reward.
with_externalities(&mut ExtBuilder::default()
.session_length(3)
.sessions_per_era(3)
.nominate(false)
.build(),
|| {
let delay = 1;
let session_reward = 10;
// This is set by the test config builder.
@@ -398,37 +389,21 @@ fn multi_era_reward_should_work() {
// Set payee to controller
assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller));
let mut block = 3;
// Block 3 => Session 1 => Era 0
System::set_block_number(block);
Timestamp::set_timestamp(block*5);
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 1);
start_session(1);
// session triggered: the reward value stashed should be 10
assert_eq!(Staking::current_session_reward(), session_reward);
assert_eq!(Staking::current_era_reward(), session_reward);
block = 6; // Block 6 => Session 2 => Era 0
System::set_block_number(block);
Timestamp::set_timestamp(block*5 + delay); // a little late.
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 2);
start_session(2);
assert_eq!(Staking::current_session_reward(), session_reward);
assert_eq!(Staking::current_era_reward(), 2*session_reward - delay);
assert_eq!(Staking::current_era_reward(), 2*session_reward);
block = 9; // Block 9 => Session 3 => Era 1
System::set_block_number(block);
Timestamp::set_timestamp(block*5); // back to being punktlisch. no delayss
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 1);
assert_eq!(Session::current_index(), 3);
start_session(3);
// 1 + sum of of the session rewards accumulated
let recorded_balance = 1 + 3*session_reward - delay;
let recorded_balance = 1 + 3*session_reward;
assert_eq!(Balances::total_balance(&10), recorded_balance);
// the reward for next era will be: session_reward * slot_stake
@@ -436,14 +411,13 @@ fn multi_era_reward_should_work() {
assert_eq!(Staking::current_session_reward(), new_session_reward);
// fast forward to next era:
block=12; System::set_block_number(block);Timestamp::set_timestamp(block*5);Session::check_rotate_session(System::block_number());
block=15; System::set_block_number(block);Timestamp::set_timestamp(block*5);Session::check_rotate_session(System::block_number());
start_session(5);
// intermediate test.
assert_eq!(Staking::current_era_reward(), 2*new_session_reward);
// new era is triggered here.
block=18; System::set_block_number(block);Timestamp::set_timestamp(block*5);Session::check_rotate_session(System::block_number());
start_session(6);
// pay time
assert_eq!(Balances::total_balance(&10), 3*new_session_reward + recorded_balance);
@@ -457,7 +431,6 @@ fn staking_should_work() {
// * new ones will be chosen per era
// * either one can unlock the stash and back-down from being a validator via `chill`ing.
with_externalities(&mut ExtBuilder::default()
.sessions_per_era(3)
.nominate(false)
.fair(false) // to give 20 more staked value
.build(),
@@ -465,15 +438,12 @@ fn staking_should_work() {
// remember + compare this along with the test.
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_ok!(Staking::set_bonding_duration(2));
assert_eq!(Staking::bonding_duration(), 2);
// put some money in account that we'll use.
for i in 1..5 { let _ = Balances::make_free_balance_be(&i, 2000); }
// --- Block 1:
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 0);
// add a new candidate for being a validator. account 3 controlled by 4.
@@ -485,7 +455,7 @@ fn staking_should_work() {
// --- Block 2:
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 0);
// No effects will be seen so far. Era has not been yet triggered.
@@ -494,7 +464,7 @@ fn staking_should_work() {
// --- Block 3: the validators will now change.
System::set_block_number(3);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
// 2 only voted for 4 and 20
assert_eq!(Session::validators().len(), 2);
@@ -504,7 +474,7 @@ fn staking_should_work() {
// --- Block 4: Unstake 4 as a validator, freeing up the balance stashed in 3
System::set_block_number(4);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
// 4 will chill
Staking::chill(Origin::signed(4)).unwrap();
@@ -516,14 +486,14 @@ fn staking_should_work() {
// --- Block 5: nothing. 4 is still there.
System::set_block_number(5);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq_uvec!(Session::validators(), vec![20, 4]);
assert_eq!(Staking::current_era(), 1);
// --- Block 6: 4 will not be a validator.
System::set_block_number(6);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 2);
assert_eq!(Session::validators().contains(&4), false);
assert_eq_uvec!(Session::validators(), vec![20, 10]);
@@ -548,9 +518,7 @@ fn less_than_needed_candidates_works() {
assert_eq!(Staking::minimum_validator_count(), 1);
assert_eq_uvec!(Session::validators(), vec![30, 20, 10]);
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 1);
start_era(1);
// Previous set is selected. NO election algorithm is even executed.
assert_eq_uvec!(Session::validators(), vec![30, 20, 10]);
@@ -574,7 +542,6 @@ fn no_candidate_emergency_condition() {
.nominate(false)
.build(),
|| {
assert_eq!(Staking::era_length(), 1);
assert_eq!(Staking::validator_count(), 15);
// initial validators
@@ -584,7 +551,7 @@ fn no_candidate_emergency_condition() {
// trigger era
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
// Previous ones are elected. chill is invalidates. TODO: #2494
assert_eq_uvec!(Session::validators(), vec![10, 20, 30, 40]);
@@ -663,16 +630,14 @@ fn nominating_and_rewards_should_work() {
assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller));
assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41]));
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 1);
start_era(1);
// 10 and 20 have more votes, they will be chosen by phragmen.
assert_eq_uvec!(Session::validators(), vec![20, 10]);
// OLD validators must have already received some rewards.
assert_eq!(Balances::total_balance(&40), 1 + session_reward);
assert_eq!(Balances::total_balance(&30), 1 + session_reward);
assert_eq!(Balances::total_balance(&40), 1 + 3 * session_reward);
assert_eq!(Balances::total_balance(&30), 1 + 3 * session_reward);
// ------ check the staked value of all parties.
@@ -694,22 +659,21 @@ fn nominating_and_rewards_should_work() {
assert_eq!(Staking::stakers(41).total, 0);
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
start_era(2);
// next session reward.
let new_session_reward = Staking::session_reward() * Staking::slot_stake();
let new_session_reward = Staking::session_reward() * 3 * Staking::slot_stake();
// nothing else will happen, era ends and rewards are paid again,
// it is expected that nominators will also be paid. See below
// Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11
assert_eq!(Balances::total_balance(&2), initial_balance + (2*new_session_reward/9 + 3*new_session_reward/11));
assert_eq!(Balances::total_balance(&2), initial_balance + (2*new_session_reward/9 + 3*new_session_reward/11) - 1);
// Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11
assert_eq!(Balances::total_balance(&4), initial_balance + (2*new_session_reward/9 + 3*new_session_reward/11));
assert_eq!(Balances::total_balance(&4), initial_balance + (2*new_session_reward/9 + 3*new_session_reward/11) - 1);
// 10 got 800 / 1800 external stake => 8/18 =? 4/9 => Validator's share = 5/9
assert_eq!(Balances::total_balance(&10), initial_balance + 5*new_session_reward/9);
// 10 got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share = 5/11
assert_eq!(Balances::total_balance(&20), initial_balance + 5*new_session_reward/11);
assert_eq!(Balances::total_balance(&20), initial_balance + 5*new_session_reward/11+ 2);
check_exposure_all();
});
@@ -719,7 +683,6 @@ fn nominating_and_rewards_should_work() {
fn nominators_also_get_slashed() {
// A nominator should be slashed if the validator they nominated is slashed
with_externalities(&mut ExtBuilder::default().nominate(false).build(), || {
assert_eq!(Staking::era_length(), 1);
assert_eq!(Staking::validator_count(), 2);
// slash happens immediately.
assert_eq!(Staking::offline_slash_grace(), 0);
@@ -742,8 +705,7 @@ fn nominators_also_get_slashed() {
assert_ok!(Staking::nominate(Origin::signed(2), vec![20, 10]));
// new era, pay rewards,
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
// Nominator stash didn't collect any.
assert_eq!(Balances::total_balance(&2), initial_balance);
@@ -757,11 +719,11 @@ fn nominators_also_get_slashed() {
let nominator_slash = nominator_stake.min(total_slash - validator_slash);
// initial + first era reward + slash
assert_eq!(Balances::total_balance(&10), initial_balance + 10 - validator_slash);
assert_eq!(Balances::total_balance(&10), initial_balance + 30 - validator_slash);
assert_eq!(Balances::total_balance(&2), initial_balance - nominator_slash);
check_exposure_all();
// Because slashing happened.
assert!(Staking::forcing_new_era().is_some());
assert!(Staking::forcing_new_era());
});
}
@@ -772,7 +734,6 @@ fn double_staking_should_fail() {
// * an account already bonded as stash cannot nominate.
// * an account already bonded as controller can nominate.
with_externalities(&mut ExtBuilder::default()
.sessions_per_era(2)
.build(),
|| {
let arbitrary_value = 5;
@@ -792,7 +753,6 @@ fn double_controlling_should_fail() {
// should test (in the same order):
// * an account already bonded as controller CANNOT be reused as the controller of another account.
with_externalities(&mut ExtBuilder::default()
.sessions_per_era(2)
.build(),
|| {
let arbitrary_value = 5;
@@ -806,70 +766,43 @@ fn double_controlling_should_fail() {
#[test]
fn session_and_eras_work() {
with_externalities(&mut ExtBuilder::default()
.sessions_per_era(2)
.build(),
|| {
assert_eq!(Staking::era_length(), 2);
assert_eq!(Staking::sessions_per_era(), 2);
assert_eq!(Staking::last_era_length_change(), 0);
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 0);
// Block 1: No change.
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_session(1);
assert_eq!(Session::current_index(), 1);
assert_eq!(Staking::sessions_per_era(), 2);
assert_eq!(Staking::last_era_length_change(), 0);
assert_eq!(Staking::current_era(), 0);
// Block 2: Simple era change.
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
assert_eq!(Session::current_index(), 2);
assert_eq!(Staking::sessions_per_era(), 2);
assert_eq!(Staking::last_era_length_change(), 0);
start_session(3);
assert_eq!(Session::current_index(), 3);
assert_eq!(Staking::current_era(), 1);
// Block 3: Schedule an era length change; no visible changes.
System::set_block_number(3);
assert_ok!(Staking::set_sessions_per_era(3));
Session::check_rotate_session(System::block_number());
assert_eq!(Session::current_index(), 3);
assert_eq!(Staking::sessions_per_era(), 2);
assert_eq!(Staking::last_era_length_change(), 0);
start_session(4);
assert_eq!(Session::current_index(), 4);
assert_eq!(Staking::current_era(), 1);
// Block 4: Era change kicks in.
System::set_block_number(4);
Session::check_rotate_session(System::block_number());
assert_eq!(Session::current_index(), 4);
assert_eq!(Staking::sessions_per_era(), 3);
assert_eq!(Staking::last_era_length_change(), 4);
start_session(6);
assert_eq!(Session::current_index(), 6);
assert_eq!(Staking::current_era(), 2);
// Block 5: No change.
System::set_block_number(5);
Session::check_rotate_session(System::block_number());
assert_eq!(Session::current_index(), 5);
assert_eq!(Staking::sessions_per_era(), 3);
assert_eq!(Staking::last_era_length_change(), 4);
start_session(7);
assert_eq!(Session::current_index(), 7);
assert_eq!(Staking::current_era(), 2);
// Block 6: No change.
System::set_block_number(6);
Session::check_rotate_session(System::block_number());
assert_eq!(Session::current_index(), 6);
assert_eq!(Staking::sessions_per_era(), 3);
assert_eq!(Staking::last_era_length_change(), 4);
start_session(8);
assert_eq!(Session::current_index(), 8);
assert_eq!(Staking::current_era(), 2);
// Block 7: Era increment.
System::set_block_number(7);
Session::check_rotate_session(System::block_number());
assert_eq!(Session::current_index(), 7);
assert_eq!(Staking::sessions_per_era(), 3);
assert_eq!(Staking::last_era_length_change(), 4);
start_session(9);
assert_eq!(Session::current_index(), 9);
assert_eq!(Staking::current_era(), 3);
});
}
@@ -947,31 +880,39 @@ fn reward_destination_works() {
// Check the balance of the stash account
assert_eq!(Balances::free_balance(&11), 1000);
// Check how much is at stake
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000,
active: 1000,
unlocking: vec![],
}));
// Check current session reward is 10
let session_reward0 = Staking::current_session_reward(); // 10
let session_reward0 = 3 * Staking::current_session_reward(); // 10
// Move forward the system for payment
System::set_block_number(1);
Timestamp::set_timestamp(5);
Session::check_rotate_session(System::block_number());
start_era(1);
// Check that RewardDestination is Staked (default)
assert_eq!(Staking::payee(&11), RewardDestination::Staked);
// Check that reward went to the stash account of validator
assert_eq!(Balances::free_balance(&11), 1000 + session_reward0);
// Check that amount at stake increased accordingly
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + session_reward0, active: 1000 + session_reward0, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000 + session_reward0,
active: 1000 + session_reward0,
unlocking: vec![],
}));
// Update current session reward
let session_reward1 = Staking::current_session_reward(); // 1010 (1* slot_stake)
let session_reward1 = 3 * Staking::current_session_reward(); // 1010 (1* slot_stake)
//Change RewardDestination to Stash
<Payee<Test>>::insert(&11, RewardDestination::Stash);
// Move forward the system for payment
System::set_block_number(2);
Timestamp::set_timestamp(10);
Session::check_rotate_session(System::block_number());
start_era(2);
// Check that RewardDestination is Stash
assert_eq!(Staking::payee(&11), RewardDestination::Stash);
@@ -980,7 +921,12 @@ fn reward_destination_works() {
// Record this value
let recorded_stash_balance = 1000 + session_reward0 + session_reward1;
// Check that amount at stake is NOT increased
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + session_reward0, active: 1000 + session_reward0, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000 + session_reward0,
active: 1000 + session_reward0,
unlocking: vec![],
}));
// Change RewardDestination to Controller
<Payee<Test>>::insert(&11, RewardDestination::Controller);
@@ -989,17 +935,21 @@ fn reward_destination_works() {
assert_eq!(Balances::free_balance(&10), 1);
// Move forward the system for payment
System::set_block_number(3);
Timestamp::set_timestamp(15);
Session::check_rotate_session(System::block_number());
let session_reward2 = Staking::current_session_reward(); // 1010 (1* slot_stake)
start_era(3);
let session_reward2 = 3 * Staking::current_session_reward(); // 1010 (1* slot_stake)
// Check that RewardDestination is Controller
assert_eq!(Staking::payee(&11), RewardDestination::Controller);
// Check that reward went to the controller account
assert_eq!(Balances::free_balance(&10), 1 + session_reward2);
// Check that amount at stake is NOT increased
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + session_reward0, active: 1000 + session_reward0, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000 + session_reward0,
active: 1000 + session_reward0,
unlocking: vec![],
}));
// Check that amount in staked account is NOT increased.
assert_eq!(Balances::free_balance(&11), recorded_stash_balance);
});
@@ -1011,8 +961,6 @@ fn validator_payment_prefs_work() {
// Note: unstake threshold is being directly tested in slashing tests.
// This test will focus on validator payment.
with_externalities(&mut ExtBuilder::default()
.session_length(3)
.sessions_per_era(3)
.build(),
|| {
// Initial config
@@ -1044,7 +992,7 @@ fn validator_payment_prefs_work() {
// Block 3 => Session 1 => Era 0
let mut block = 3;
System::set_block_number(block);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 1);
@@ -1054,7 +1002,7 @@ fn validator_payment_prefs_work() {
block = 6; // Block 6 => Session 2 => Era 0
System::set_block_number(block);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 2);
@@ -1063,7 +1011,7 @@ fn validator_payment_prefs_work() {
block = 9; // Block 9 => Session 3 => Era 1
System::set_block_number(block);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Staking::current_era(), 1);
assert_eq!(Session::current_index(), 3);
@@ -1093,7 +1041,12 @@ fn bond_extra_works() {
// Check that account 10 is bonded to account 11
assert_eq!(Staking::bonded(&11), Some(10));
// Check how much is at stake
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000,
active: 1000,
unlocking: vec![],
}));
// Give account 11 some large free balance greater than total
let _ = Balances::make_free_balance_be(&11, 1000000);
@@ -1101,12 +1054,22 @@ fn bond_extra_works() {
// Call the bond_extra function from controller, add only 100
assert_ok!(Staking::bond_extra(Origin::signed(11), 100));
// There should be 100 more `total` and `active` in the ledger
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + 100, active: 1000 + 100, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000 + 100,
active: 1000 + 100,
unlocking: vec![],
}));
// Call the bond_extra function with a large number, should handle it
assert_ok!(Staking::bond_extra(Origin::signed(11), u64::max_value()));
// The full amount of the funds should now be in the total and active
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000000, active: 1000000, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000000,
active: 1000000,
unlocking: vec![],
}));
});
}
@@ -1124,14 +1087,10 @@ fn bond_extra_and_withdraw_unbonded_works() {
// Set payee to controller. avoids confusion
assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller));
// Set unbonding era (bonding_duration) to 2
assert_ok!(Staking::set_bonding_duration(2));
// Give account 11 some large free balance greater than total
let _ = Balances::make_free_balance_be(&11, 1000000);
// Initial config should be correct
assert_eq!(Staking::sessions_per_era(), 1);
assert_eq!(Staking::current_era(), 0);
assert_eq!(Session::current_index(), 0);
assert_eq!(Staking::current_session_reward(), 10);
@@ -1140,58 +1099,65 @@ fn bond_extra_and_withdraw_unbonded_works() {
assert_eq!(Balances::total_balance(&10), 1);
// confirm that 10 is a normal validator and gets paid at the end of the era.
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
// Initial state of 10
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000, active: 1000, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000,
active: 1000,
unlocking: vec![],
}));
assert_eq!(Staking::stakers(&11), Exposure { total: 1000, own: 1000, others: vec![] });
// deposit the extra 100 units
Staking::bond_extra(Origin::signed(11), 100).unwrap();
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + 100, active: 1000 + 100, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000 + 100,
active: 1000 + 100,
unlocking: vec![],
}));
// Exposure is a snapshot! only updated after the next era update.
assert_ne!(Staking::stakers(&11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] });
// trigger next era.
System::set_block_number(2);Timestamp::set_timestamp(10);Session::check_rotate_session(System::block_number());
Timestamp::set_timestamp(10);
start_era(2);
assert_eq!(Staking::current_era(), 2);
assert_eq!(Session::current_index(), 2);
// ledger should be the same.
assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, total: 1000 + 100, active: 1000 + 100, unlocking: vec![] }));
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11,
total: 1000 + 100,
active: 1000 + 100,
unlocking: vec![],
}));
// Exposure is now updated.
assert_eq!(Staking::stakers(&11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] });
// Unbond almost all of the funds in stash.
Staking::unbond(Origin::signed(10), 1000).unwrap();
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 2}] })
stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}] })
);
// Attempting to free the balances now will fail. 2 eras need to pass.
Staking::withdraw_unbonded(Origin::signed(10)).unwrap();
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 2}] }));
stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}] }));
// trigger next era.
System::set_block_number(3);
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 3);
assert_eq!(Session::current_index(), 3);
start_era(3);
// nothing yet
Staking::withdraw_unbonded(Origin::signed(10)).unwrap();
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 2}] }));
stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}] }));
// trigger next era.
System::set_block_number(4);
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 4);
assert_eq!(Session::current_index(), 4);
start_era(5);
Staking::withdraw_unbonded(Origin::signed(10)).unwrap();
// Now the value is free and the staking ledger is updated.
@@ -1208,19 +1174,14 @@ fn too_many_unbond_calls_should_not_work() {
assert_ok!(Staking::unbond(Origin::signed(10), 1));
}
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
// locked ar era 1 until 4
// locked at era 1 until 4
assert_ok!(Staking::unbond(Origin::signed(10), 1));
// can't do more.
assert_noop!(Staking::unbond(Origin::signed(10), 1), "can not schedule more unlock chunks");
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
System::set_block_number(3);
Session::check_rotate_session(System::block_number());
start_era(3);
assert_noop!(Staking::unbond(Origin::signed(10), 1), "can not schedule more unlock chunks");
// free up.
@@ -1262,23 +1223,21 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment(
<Ledger<Test>>::insert(&20, StakingLedger { stash: 22, total: 69, active: 69, unlocking: vec![] });
// New era --> rewards are paid --> stakes are changed
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
assert_eq!(Staking::current_era(), 1);
start_era(1);
// -- new balances + reward
assert_eq!(Staking::stakers(&11).total, 1000 + 10);
assert_eq!(Staking::stakers(&21).total, 69 + 10);
assert_eq!(Staking::stakers(&11).total, 1000 + 30);
assert_eq!(Staking::stakers(&21).total, 69 + 30);
// -- slot stake should also be updated.
assert_eq!(Staking::slot_stake(), 79);
assert_eq!(Staking::slot_stake(), 69 + 30);
// If 10 gets slashed now, it will be slashed by 5% of exposure.total * 2.pow(unstake_thresh)
Staking::on_offline_validator(10, 4);
// Confirm user has been reported
assert_eq!(Staking::slash_count(&11), 4);
// check the balance of 10 (slash will be deducted from free balance.)
assert_eq!(Balances::free_balance(&11), 1000 + 10 - 50 /*5% of 1000*/ * 8 /*2**3*/);
assert_eq!(Balances::free_balance(&11), 1000 + 30 - 51 /*5% of 1030*/ * 8 /*2**3*/);
check_exposure_all();
});
@@ -1474,8 +1433,7 @@ fn phragmen_poc_works() {
assert_ok!(Staking::nominate(Origin::signed(4), vec![11, 21, 41]));
// New era => election algorithm will trigger
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
assert_eq_uvec!(Session::validators(), vec![20, 10]);
@@ -1552,7 +1510,6 @@ fn switching_roles() {
// Test that it should be possible to switch between roles (nominator, validator, idle) with minimal overhead.
with_externalities(&mut ExtBuilder::default()
.nominate(false)
.sessions_per_era(3)
.build(),
|| {
// Reset reward destination
@@ -1576,21 +1533,21 @@ fn switching_roles() {
// new block
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
// no change
assert_eq_uvec!(Session::validators(), vec![20, 10]);
// new block
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
// no change
assert_eq_uvec!(Session::validators(), vec![20, 10]);
// new block --> ne era --> new validators
System::set_block_number(3);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
// with current nominators 10 and 5 have the most stake
assert_eq_uvec!(Session::validators(), vec![6, 10]);
@@ -1605,16 +1562,16 @@ fn switching_roles() {
// Winners: 20 and 2
System::set_block_number(4);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq_uvec!(Session::validators(), vec![6, 10]);
System::set_block_number(5);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq_uvec!(Session::validators(), vec![6, 10]);
// ne era
System::set_block_number(6);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq_uvec!(Session::validators(), vec![2, 20]);
check_exposure_all();
});
@@ -1640,8 +1597,7 @@ fn wrong_vote_is_null() {
]));
// new block
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
assert_eq_uvec!(Session::validators(), vec![20, 10]);
});
@@ -1666,35 +1622,44 @@ fn bond_with_no_staked_value() {
assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller));
assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default()));
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
assert_eq_uvec!(Session::validators(), vec![30, 20, 10]);
// min of 10, 20 and 30 (30 got a payout into staking so it raised it from 1 to 11).
assert_eq!(Staking::slot_stake(), 11);
// min of 10, 20 and 30 (30 got a payout into staking so it raised it from 1 to 31).
assert_eq!(Staking::slot_stake(), 31);
// make the stingy one elected.
assert_ok!(Staking::bond(Origin::signed(3), 4, 500, RewardDestination::Controller));
assert_ok!(Staking::nominate(Origin::signed(4), vec![1]));
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
// no rewards paid to 2 and 4 yet
assert_eq!(Balances::free_balance(&2), initial_balance_2);
assert_eq!(Balances::free_balance(&4), initial_balance_4);
start_era(2);
// Stingy one is selected
assert_eq_uvec!(Session::validators(), vec![20, 10, 2]);
assert_eq!(Staking::stakers(1), Exposure { own: 1, total: 501, others: vec![IndividualExposure { who: 3, value: 500}]});
assert_eq!(Staking::stakers(1), Exposure {
own: 1,
total: 501,
others: vec![IndividualExposure { who: 3, value: 500}],
});
// New slot stake.
assert_eq!(Staking::slot_stake(), 501);
System::set_block_number(3);
Session::check_rotate_session(System::block_number());
// no rewards paid to 2 and 4 yet
assert_eq!(Balances::free_balance(&2), initial_balance_2);
assert_eq!(Balances::free_balance(&4), initial_balance_4);
let reward = Staking::current_session_reward();
start_era(3);
let reward = Staking::current_session_reward() * 3;
// 2 will not get a reward of only 1
// 4 will get the rest
assert_eq!(Balances::free_balance(&2), initial_balance_2 + 1);
assert_eq!(Balances::free_balance(&4), initial_balance_4 + reward - 1);
assert_eq!(Balances::free_balance(&2), initial_balance_2 + 3);
assert_eq!(Balances::free_balance(&4), initial_balance_4 + reward - 3);
});
}
@@ -1719,8 +1684,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() {
assert_ok!(Staking::bond(Origin::signed(1), 2, 1, RewardDestination::Controller));
assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default()));
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
// 2 is elected.
// and fucks up the slot stake.
@@ -1728,21 +1692,20 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() {
assert_eq!(Staking::slot_stake(), 1);
// Old ones are rewarded.
assert_eq!(Balances::free_balance(&10), initial_balance_10 + 10);
assert_eq!(Balances::free_balance(&10), initial_balance_10 + 30);
// no rewards paid to 2. This was initial election.
assert_eq!(Balances::free_balance(&2), initial_balance_2);
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
start_era(2);
assert_eq_uvec!(Session::validators(), vec![20, 10, 2]);
assert_eq!(Staking::slot_stake(), 1);
let reward = Staking::current_session_reward();
// 2 will not get the full reward, practically 1
assert_eq!(Balances::free_balance(&2), initial_balance_2 + reward.max(1));
assert_eq!(Balances::free_balance(&2), initial_balance_2 + reward.max(3));
// same for 10
assert_eq!(Balances::free_balance(&10), initial_balance_10 + 10 + reward.max(1));
assert_eq!(Balances::free_balance(&10), initial_balance_10 + 30 + reward.max(3));
check_exposure_all();
});
}
@@ -1775,7 +1738,7 @@ fn phragmen_linear_worse_case_equalize() {
assert_ok!(Staking::set_validator_count(7));
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq_uvec!(Session::validators(), vec![10, 60, 40, 20, 50, 30, 70]);
@@ -1813,7 +1776,7 @@ fn phragmen_chooses_correct_number_of_validators() {
assert_eq!(Session::validators().len(), 1);
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
Session::on_initialize(System::block_number());
assert_eq!(Session::validators().len(), 1);
check_exposure_all();
@@ -1832,8 +1795,7 @@ fn phragmen_score_should_be_accurate_on_large_stakes() {
bond_validator(6, u64::max_value()-1);
bond_validator(8, u64::max_value()-2);
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
start_era(1);
assert_eq!(Session::validators(), vec![4, 2]);
check_exposure_all();
@@ -1855,8 +1817,7 @@ fn phragmen_should_not_overflow_validators() {
bond_nominator(6, u64::max_value()/2, vec![3, 5]);
bond_nominator(8, u64::max_value()/2, vec![3, 5]);
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
start_era(1);
assert_eq_uvec!(Session::validators(), vec![4, 2]);
@@ -1882,8 +1843,7 @@ fn phragmen_should_not_overflow_nominators() {
bond_nominator(6, u64::max_value(), vec![3, 5]);
bond_nominator(8, u64::max_value(), vec![3, 5]);
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
start_era(1);
assert_eq_uvec!(Session::validators(), vec![4, 2]);
@@ -1905,8 +1865,7 @@ fn phragmen_should_not_overflow_ultimate() {
bond_nominator(6, u64::max_value(), vec![3, 5]);
bond_nominator(8, u64::max_value(), vec![3, 5]);
System::set_block_number(2);
Session::check_rotate_session(System::block_number());
start_era(1);
assert_eq_uvec!(Session::validators(), vec![4, 2]);
@@ -1958,8 +1917,7 @@ fn phragmen_large_scale_test() {
prefix + 25]
);
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
// For manual inspection
println!("Validators are {:?}", Session::validators());
@@ -2008,8 +1966,7 @@ fn phragmen_large_scale_test_2() {
bond_nominator(50, nom_budget, vec![3, 5]);
System::set_block_number(1);
Session::check_rotate_session(System::block_number());
start_era(1);
// Each exposure => total == own + sum(others)
check_exposure_all();