Invulnerabiity from slashing for certain validators (#1355)

* Invulnerabiity from slashing

* Update srml/staking/src/lib.rs

Co-Authored-By: gavofyork <github@gavwood.com>
This commit is contained in:
Gav Wood
2019-01-07 16:07:58 +01:00
committed by GitHub
parent d271a4647c
commit 043831cfb0
9 changed files with 43 additions and 5 deletions
+14
View File
@@ -224,6 +224,11 @@ decl_module! {
let new: u32 = new.into();
<OfflineSlashGrace<T>>::put(new);
}
/// Set the validators who cannot be slashed (if any).
fn set_invulnerables(validators: Vec<T::AccountId>) {
<Invulerables<T>>::put(validators);
}
}
}
@@ -260,6 +265,10 @@ decl_storage! {
/// The length of the bonding duration in blocks.
pub BondingDuration get(bonding_duration) config(): T::BlockNumber = T::BlockNumber::sa(1000);
/// Any validators that may never be slashed or forcible kicked. It's a Vec since they're easy to initialise
/// and the performance hit is minimal (we expect no more than four invulnerables) and restricted to testnets.
pub Invulerables get(invulnerables) config(): Vec<T::AccountId>;
/// The current era index.
pub CurrentEra get(current_era) config(): T::BlockNumber;
/// Preferences that a validator has.
@@ -501,6 +510,11 @@ impl<T: Trait> Module<T> {
pub fn on_offline_validator(v: T::AccountId, count: usize) {
use primitives::traits::CheckedShl;
// Early exit if validator is invulnerable.
if Self::invulnerables().contains(&v) {
return
}
for _ in 0..count {
let slash_count = Self::slash_count(&v);
<SlashCount<T>>::insert(v.clone(), slash_count + 1);
+1
View File
@@ -123,6 +123,7 @@ pub fn new_test_ext(
current_session_reward: reward,
current_offline_slash: 20,
offline_slash_grace: 0,
invulnerables: vec![],
}.build_storage().unwrap().0);
t.extend(timestamp::GenesisConfig::<Test>{
period: 5,
+16
View File
@@ -35,6 +35,22 @@ fn note_null_offline_should_work() {
});
}
#[test]
fn invulnerability_should_work() {
with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || {
Staking::set_invulnerables(vec![10]);
Balances::set_free_balance(&10, 70);
assert_eq!(Staking::offline_slash_grace(), 0);
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 70);
System::set_extrinsic_index(1);
Staking::on_offline_validator(10, 1);
assert_eq!(Staking::slash_count(&10), 0);
assert_eq!(Balances::free_balance(&10), 70);
assert!(Staking::forcing_new_era().is_none());
});
}
#[test]
fn note_offline_should_work() {
with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || {