Update Staking Weights (#5964)

This commit is contained in:
Shawn Tabrizi
2020-05-15 11:07:19 +02:00
committed by GitHub
parent 27250681bf
commit 71d3abe7d4
8 changed files with 654 additions and 130 deletions
+128 -28
View File
@@ -24,7 +24,7 @@ use sp_runtime::{
use sp_staking::offence::OffenceDetails;
use frame_support::{
assert_ok, assert_noop, StorageMap,
traits::{Currency, ReservableCurrency, OnInitialize},
traits::{Currency, ReservableCurrency, OnInitialize, OnFinalize},
};
use pallet_balances::Error as BalancesError;
use substrate_test_utils::assert_eq_uvec;
@@ -34,15 +34,19 @@ fn force_unstake_works() {
ExtBuilder::default().build_and_execute(|| {
// Account 11 is stashed and locked, and account 10 is the controller
assert_eq!(Staking::bonded(&11), Some(10));
// Adds 2 slashing spans
add_slash(&11);
// Cant transfer
assert_noop!(
Balances::transfer(Origin::signed(11), 1, 10),
BalancesError::<Test, _>::LiquidityRestrictions
);
// Force unstake requires root.
assert_noop!(Staking::force_unstake(Origin::signed(11), 11), BadOrigin);
assert_noop!(Staking::force_unstake(Origin::signed(11), 11, 2), BadOrigin);
// Force unstake needs correct number of slashing spans (for weight calculation)
assert_noop!(Staking::force_unstake(Origin::signed(11), 11, 0), BadOrigin);
// We now force them to unstake
assert_ok!(Staking::force_unstake(Origin::ROOT, 11));
assert_ok!(Staking::force_unstake(Origin::ROOT, 11, 2));
// No longer bonded.
assert_eq!(Staking::bonded(&11), None);
// Transfer works.
@@ -50,6 +54,24 @@ fn force_unstake_works() {
});
}
#[test]
fn kill_stash_works() {
ExtBuilder::default().build_and_execute(|| {
// Account 11 is stashed and locked, and account 10 is the controller
assert_eq!(Staking::bonded(&11), Some(10));
// Adds 2 slashing spans
add_slash(&11);
// Only can kill a stash account
assert_noop!(Staking::kill_stash(&12, 0), Error::<Test>::NotStash);
// Respects slashing span count
assert_noop!(Staking::kill_stash(&11, 0), Error::<Test>::IncorrectSlashingSpans);
// Correct inputs, everything works
assert_ok!(Staking::kill_stash(&11, 2));
// No longer bonded.
assert_eq!(Staking::bonded(&11), None);
});
}
#[test]
fn basic_setup_works() {
// Verifies initial conditions of mock
@@ -1023,7 +1045,10 @@ fn bond_extra_and_withdraw_unbonded_works() {
unlocking: vec![],
claimed_rewards: vec![],
}));
assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000, own: 1000, others: vec![] });
assert_eq!(
Staking::eras_stakers(Staking::active_era().unwrap().index, 11),
Exposure { total: 1000, own: 1000, others: vec![] }
);
// deposit the extra 100 units
Staking::bond_extra(Origin::signed(11), 100).unwrap();
@@ -1036,7 +1061,10 @@ fn bond_extra_and_withdraw_unbonded_works() {
claimed_rewards: vec![],
}));
// Exposure is a snapshot! only updated after the next era update.
assert_ne!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] });
assert_ne!(
Staking::eras_stakers(Staking::active_era().unwrap().index, 11),
Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] }
);
// trigger next era.
mock::start_era(2);
@@ -1051,34 +1079,68 @@ fn bond_extra_and_withdraw_unbonded_works() {
claimed_rewards: vec![],
}));
// Exposure is now updated.
assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] });
assert_eq!(
Staking::eras_stakers(Staking::active_era().unwrap().index, 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 + 3}], claimed_rewards: vec![] })
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger {
stash: 11,
total: 1000 + 100,
active: 100,
unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}],
claimed_rewards: vec![]
}),
);
// 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 + 3}], claimed_rewards: vec![] }));
assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0));
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger {
stash: 11,
total: 1000 + 100,
active: 100,
unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}],
claimed_rewards: vec![]
}),
);
// trigger next era.
mock::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 + 3}], claimed_rewards: vec![] }));
assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0));
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger {
stash: 11,
total: 1000 + 100,
active: 100,
unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}],
claimed_rewards: vec![]
}),
);
// trigger next era.
mock::start_era(5);
Staking::withdraw_unbonded(Origin::signed(10)).unwrap();
assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0));
// Now the value is free and the staking ledger is updated.
assert_eq!(Staking::ledger(&10), Some(StakingLedger {
stash: 11, total: 100, active: 100, unlocking: vec![], claimed_rewards: vec![] }));
assert_eq!(
Staking::ledger(&10),
Some(StakingLedger {
stash: 11,
total: 100,
active: 100,
unlocking: vec![],
claimed_rewards: vec![]
}),
);
})
}
@@ -1101,7 +1163,7 @@ fn too_many_unbond_calls_should_not_work() {
assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::<Test>::NoMoreChunks);
// free up.
assert_ok!(Staking::withdraw_unbonded(Origin::signed(10)));
assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0));
// Can add again.
assert_ok!(Staking::unbond(Origin::signed(10), 1));
@@ -1449,7 +1511,7 @@ fn on_free_balance_zero_stash_removes_validator() {
assert_eq!(Balances::total_balance(&11), 0);
// Reap the stash
assert_ok!(Staking::reap_stash(Origin::NONE, 11));
assert_ok!(Staking::reap_stash(Origin::NONE, 11, 0));
// Check storage items do not exist
assert!(!<Ledger<Test>>::contains_key(&10));
@@ -1505,7 +1567,7 @@ fn on_free_balance_zero_stash_removes_nominator() {
assert_eq!(Balances::total_balance(&11), 0);
// Reap the stash
assert_ok!(Staking::reap_stash(Origin::NONE, 11));
assert_ok!(Staking::reap_stash(Origin::NONE, 11, 0));
// Check storage items do not exist
assert!(!<Ledger<Test>>::contains_key(&10));
@@ -1619,14 +1681,14 @@ fn bond_with_no_staked_value() {
mock::start_era(2);
// not yet removed.
assert_ok!(Staking::withdraw_unbonded(Origin::signed(2)));
assert_ok!(Staking::withdraw_unbonded(Origin::signed(2), 0));
assert!(Staking::ledger(2).is_some());
assert_eq!(Balances::locks(&1)[0].amount, 5);
mock::start_era(3);
// poof. Account 1 is removed from the staking system.
assert_ok!(Staking::withdraw_unbonded(Origin::signed(2)));
assert_ok!(Staking::withdraw_unbonded(Origin::signed(2), 0));
assert!(Staking::ledger(2).is_none());
assert_eq!(Balances::locks(&1).len(), 0);
});
@@ -2270,7 +2332,12 @@ fn garbage_collection_after_slashing() {
assert_eq!(Balances::free_balance(11), 0);
assert_eq!(Balances::total_balance(&11), 0);
assert_ok!(Staking::reap_stash(Origin::NONE, 11));
let slashing_spans = <Staking as crate::Store>::SlashingSpans::get(&11).unwrap();
assert_eq!(slashing_spans.iter().count(), 2);
// reap_stash respects num_slashing_spans so that weight is accurate
assert_noop!(Staking::reap_stash(Origin::NONE, 11, 0), Error::<Test>::IncorrectSlashingSpans);
assert_ok!(Staking::reap_stash(Origin::NONE, 11, 2));
assert!(<Staking as crate::Store>::SlashingSpans::get(&11).is_none());
assert_eq!(<Staking as crate::Store>::SpanSlash::get(&(11, 0)).amount_slashed(), &0);
@@ -2705,7 +2772,7 @@ mod offchain_phragmen {
/// setup a new set of validators and nominator storage items independent of the parent mock
/// file. This produces a edge graph that can be reduced.
fn build_offchain_phragmen_test_ext() {
pub fn build_offchain_phragmen_test_ext() {
for i in (10..=40).step_by(10) {
// Note: we respect the convention of the mock (10, 11 pairs etc.) since these accounts
// have corresponding keys in session which makes everything more ergonomic and
@@ -4092,16 +4159,16 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward(
fn set_history_depth_works() {
ExtBuilder::default().build_and_execute(|| {
mock::start_era(10);
Staking::set_history_depth(Origin::ROOT, 20).unwrap();
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).unwrap();
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).unwrap();
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).unwrap();
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));
});
@@ -4598,3 +4665,36 @@ fn migrate_era_should_handle_errors_2() {
assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2);
});
}
#[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_phragmen_ext()
.validator_count(4)
.has_stakers(false)
.build()
.execute_with(|| {
crate::tests::offchain_phragmen::build_offchain_phragmen_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()));
});
}