Slash and prove membership of prior sessions (#2970)

* skeleton for tracking historical sessions

* refactor OpaqueKeys

* some more skeleton work

* adjust session to new OpaqueKeys API

* further refactoring of key-type-ids

* session gets validator ID parameter

* run up against compiler

* tweak staking to support new session changes

* first run at child storage for deduplication

* Make session use `AccountId` as `ValidatorId`

* run up against child trie issues

* switch to using normal trie but with a fixed prefix

* clear out some println

* add dedup test

* flesh out historical module more

* introduce ExposureOf for staking

* test the historical module

* WASM compiles

* tests all compile

* do some mock change

* fix bulk of tests

* fix staking tests

* test obsolecence mechanic

* Apply suggestions from code review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* some more style nits

* a couple more nits

* tweak tries

* fix typo thie -> this
This commit is contained in:
Robert Habermeier
2019-07-08 14:36:46 +02:00
committed by GitHub
parent bb7ff32e77
commit 7df8e52cfe
23 changed files with 1188 additions and 341 deletions
+41 -37
View File
@@ -458,7 +458,7 @@ fn staking_should_work() {
.build(),
|| {
// remember + compare this along with the test.
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// put some money in account that we'll use.
for i in 1..5 { let _ = Balances::make_free_balance_be(&i, 2000); }
@@ -470,13 +470,13 @@ fn staking_should_work() {
assert_ok!(Staking::validate(Origin::signed(4), ValidatorPrefs::default()));
// No effects will be seen so far.
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// --- Block 2:
start_session(2);
// No effects will be seen so far. Era has not been yet triggered.
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// --- Block 3: the validators will now be queued.
@@ -486,18 +486,18 @@ fn staking_should_work() {
// --- Block 4: the validators will now be changed.
start_session(4);
assert_eq_uvec!(Session::validators(), vec![20, 4]);
assert_eq_uvec!(validator_controllers(), vec![20, 4]);
// --- Block 4: Unstake 4 as a validator, freeing up the balance stashed in 3
// 4 will chill
Staking::chill(Origin::signed(4)).unwrap();
// --- Block 5: nothing. 4 is still there.
start_session(5);
assert_eq_uvec!(Session::validators(), vec![20, 4]);
assert_eq_uvec!(validator_controllers(), vec![20, 4]);
// --- Block 6: 4 will not be a validator.
start_session(7);
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// Note: the stashed value of 4 is still lock
assert_eq!(
@@ -521,12 +521,12 @@ fn less_than_needed_candidates_works() {
|| {
assert_eq!(Staking::validator_count(), 4);
assert_eq!(Staking::minimum_validator_count(), 1);
assert_eq_uvec!(Session::validators(), vec![30, 20, 10]);
assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]);
start_era(1);
// Previous set is selected. NO election algorithm is even executed.
assert_eq_uvec!(Session::validators(), vec![30, 20, 10]);
assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]);
// But the exposure is updated in a simple way. No external votes exists. This is purely self-vote.
assert_eq!(Staking::stakers(10).others.len(), 0);
@@ -549,10 +549,14 @@ fn no_candidate_emergency_condition() {
.nominate(false)
.build(),
|| {
assert_eq!(Staking::validator_count(), 15);
// initial validators
assert_eq_uvec!(Session::validators(), vec![10, 20, 30, 40]);
assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]);
// set the minimum validator count.
<Staking as crate::Store>::MinimumValidatorCount::put(10);
<Staking as crate::Store>::ValidatorCount::put(15);
assert_eq!(Staking::validator_count(), 15);
let _ = Staking::chill(Origin::signed(10));
@@ -561,7 +565,7 @@ fn no_candidate_emergency_condition() {
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]);
assert_eq_uvec!(validator_controllers(), vec![10, 20, 30, 40]);
assert_eq!(Staking::current_elected().len(), 0);
});
}
@@ -610,7 +614,7 @@ fn nominating_and_rewards_should_work() {
.build(),
|| {
// initial validators -- everyone is actually even.
assert_eq_uvec!(Session::validators(), vec![40, 30]);
assert_eq_uvec!(validator_controllers(), vec![40, 30]);
// Set payee to controller
assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller));
@@ -639,7 +643,7 @@ fn nominating_and_rewards_should_work() {
start_era(1);
// 10 and 20 have more votes, they will be chosen by phragmen.
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// OLD validators must have already received some rewards.
assert_eq!(Balances::total_balance(&40), 1 + 3 * session_reward);
@@ -1478,7 +1482,7 @@ fn phragmen_poc_works() {
.build(),
|| {
// We don't really care about this. At this point everything is even.
assert_eq_uvec!(Session::validators(), vec![40, 30]);
assert_eq_uvec!(validator_controllers(), vec![40, 30]);
// Set payees to Controller
assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Controller));
@@ -1502,7 +1506,7 @@ fn phragmen_poc_works() {
// New era => election algorithm will trigger
start_era(1);
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
assert_eq!(Staking::stakers(11).own, 1000);
assert_eq!(Staking::stakers(21).own, 1000);
@@ -1574,7 +1578,7 @@ fn phragmen_poc_2_works() {
// 30 is elected with stake 1344.2622950819673 and score 0.0007439024390243903
with_externalities(&mut ExtBuilder::default().nominate(false).build(), || {
// initial setup of 10 and 20, both validators
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// Bond [30, 31] as the third validator
assert_ok!(Staking::bond_extra(Origin::signed(31), 999));
@@ -1620,7 +1624,7 @@ fn switching_roles() {
// Reset reward destination
for i in &[10, 20] { assert_ok!(Staking::set_payee(Origin::signed(*i), RewardDestination::Controller)); }
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// put some money in account that we'll use.
for i in 1..7 { let _ = Balances::deposit_creating(&i, 5000); }
@@ -1640,19 +1644,19 @@ fn switching_roles() {
start_session(1);
// no change
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// new block
start_session(2);
// no change
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// new block --> ne era --> new validators
start_session(3);
// with current nominators 10 and 5 have the most stake
assert_eq_uvec!(Session::validators(), vec![6, 10]);
assert_eq_uvec!(validator_controllers(), vec![6, 10]);
// 2 decides to be a validator. Consequences:
assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default()));
@@ -1664,14 +1668,14 @@ fn switching_roles() {
// Winners: 20 and 2
start_session(4);
assert_eq_uvec!(Session::validators(), vec![6, 10]);
assert_eq_uvec!(validator_controllers(), vec![6, 10]);
start_session(5);
assert_eq_uvec!(Session::validators(), vec![6, 10]);
assert_eq_uvec!(validator_controllers(), vec![6, 10]);
// ne era
start_session(6);
assert_eq_uvec!(Session::validators(), vec![2, 20]);
assert_eq_uvec!(validator_controllers(), vec![2, 20]);
check_exposure_all();
check_nominator_all();
@@ -1685,7 +1689,7 @@ fn wrong_vote_is_null() {
.validator_pool(true)
.build(),
|| {
assert_eq_uvec!(Session::validators(), vec![40, 30]);
assert_eq_uvec!(validator_controllers(), vec![40, 30]);
// put some money in account that we'll use.
for i in 1..3 { let _ = Balances::deposit_creating(&i, 5000); }
@@ -1700,7 +1704,7 @@ fn wrong_vote_is_null() {
// new block
start_era(1);
assert_eq_uvec!(Session::validators(), vec![20, 10]);
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
});
}
@@ -1725,7 +1729,7 @@ fn bond_with_no_staked_value() {
start_era(1);
assert_eq_uvec!(Session::validators(), vec![30, 20, 10]);
assert_eq_uvec!(validator_controllers(), vec![30, 20, 10]);
// 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);
@@ -1741,7 +1745,7 @@ fn bond_with_no_staked_value() {
start_era(2);
// Stingy one is selected
assert_eq_uvec!(Session::validators(), vec![20, 10, 2]);
assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]);
assert_eq!(Staking::stakers(1), Exposure {
own: 1,
total: 501,
@@ -1791,7 +1795,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() {
// 2 is elected.
// and fucks up the slot stake.
assert_eq_uvec!(Session::validators(), vec![20, 10, 2]);
assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]);
assert_eq!(Staking::slot_stake(), 1);
// Old ones are rewarded.
@@ -1801,7 +1805,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() {
start_era(2);
assert_eq_uvec!(Session::validators(), vec![20, 10, 2]);
assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]);
assert_eq!(Staking::slot_stake(), 1);
let reward = Staking::current_session_reward();
@@ -1841,12 +1845,12 @@ fn phragmen_linear_worse_case_equalize() {
assert_ok!(Staking::set_payee(Origin::signed(*i), RewardDestination::Controller));
}
assert_eq_uvec!(Session::validators(), vec![40, 30]);
assert_eq_uvec!(validator_controllers(), vec![40, 30]);
assert_ok!(Staking::set_validator_count(7));
start_era(1);
assert_eq_uvec!(Session::validators(), vec![10, 60, 40, 20, 50, 30, 70]);
assert_eq_uvec!(validator_controllers(), vec![10, 60, 40, 20, 50, 30, 70]);
assert_eq!(Staking::stakers(11).total, 3000);
assert_eq!(Staking::stakers(21).total, 2254);
@@ -1871,12 +1875,12 @@ fn phragmen_chooses_correct_number_of_validators() {
.build(),
|| {
assert_eq!(Staking::validator_count(), 1);
assert_eq!(Session::validators().len(), 1);
assert_eq!(validator_controllers().len(), 1);
System::set_block_number(1);
Session::on_initialize(System::block_number());
assert_eq!(Session::validators().len(), 1);
assert_eq!(validator_controllers().len(), 1);
check_exposure_all();
check_nominator_all();
})
@@ -1896,7 +1900,7 @@ fn phragmen_score_should_be_accurate_on_large_stakes() {
start_era(1);
assert_eq!(Session::validators(), vec![4, 2]);
assert_eq!(validator_controllers(), vec![4, 2]);
check_exposure_all();
check_nominator_all();
})
@@ -1919,7 +1923,7 @@ fn phragmen_should_not_overflow_validators() {
start_era(1);
assert_eq_uvec!(Session::validators(), vec![4, 2]);
assert_eq_uvec!(validator_controllers(), vec![4, 2]);
// This test will fail this. Will saturate.
// check_exposure_all();
@@ -1945,7 +1949,7 @@ fn phragmen_should_not_overflow_nominators() {
start_era(1);
assert_eq_uvec!(Session::validators(), vec![4, 2]);
assert_eq_uvec!(validator_controllers(), vec![4, 2]);
// Saturate.
assert_eq!(Staking::stakers(3).total, u64::max_value());
@@ -1967,7 +1971,7 @@ fn phragmen_should_not_overflow_ultimate() {
start_era(1);
assert_eq_uvec!(Session::validators(), vec![4, 2]);
assert_eq_uvec!(validator_controllers(), vec![4, 2]);
// Saturate.
assert_eq!(Staking::stakers(3).total, u64::max_value());