Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Fix fast-unstake for accounts with slashing #12963

Merged
merged 11 commits into from
Dec 23, 2022
2 changes: 1 addition & 1 deletion frame/staking/src/pallet/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1569,7 +1569,7 @@ impl<T: Config> StakingInterface for Pallet<T> {
}

fn force_unstake(who: Self::AccountId) -> sp_runtime::DispatchResult {
let num_slashing_spans = Self::slashing_spans(&who).iter().count() as u32;
let num_slashing_spans = Self::slashing_spans(&who).map_or(0, |s| s.iter().count() as u32);
Self::force_unstake(RawOrigin::Root.into(), who.clone(), num_slashing_spans)
}

Expand Down
25 changes: 25 additions & 0 deletions frame/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5725,3 +5725,28 @@ fn scale_validator_count_errors() {
);
})
}

mod staking_interface {
use frame_support::storage::with_storage_layer;
use sp_staking::StakingInterface;

use super::*;

#[test]
fn force_unstake_with_slash_works() {
ExtBuilder::default().build_and_execute(|| {
// without slash
let _ = with_storage_layer::<(), _, _>(|| {
// bond an account, can unstake
assert_eq!(Staking::bonded(&11), Some(10));
assert_ok!(<Staking as StakingInterface>::force_unstake(11));
Err(DispatchError::from("revert"))
});

// bond again and add a slash, still can unstake.
assert_eq!(Staking::bonded(&11), Some(10));
add_slash(&11);
assert_ok!(<Staking as StakingInterface>::force_unstake(11));
});
}
}