Fix fast-unstake for accounts with slashing (#12963)

* Fix fast-unstake for accounts with slashing

* ".git/.scripts/fmt.sh" 1

* fmt

* fix

* fix weight tracking

* Adds tests for withdraw_unbonded with slashing

* Removes tests for withdraw_unbonded with slashing

* ".git/.scripts/fmt.sh"

* Adds slash spans calculation test for withdraw_unbonded

Co-authored-by: command-bot <>
Co-authored-by: gpestana <g6pestana@gmail.com>
This commit is contained in:
Kian Paimani
2022-12-23 08:04:47 +01:00
committed by GitHub
parent 8b57471221
commit 70e9f8e920
4 changed files with 62 additions and 8 deletions
+8 -6
View File
@@ -91,7 +91,7 @@ pub mod pallet {
DispatchResult,
};
use sp_staking::{EraIndex, StakingInterface};
use sp_std::{prelude::*, vec::Vec};
use sp_std::{collections::btree_set::BTreeSet, prelude::*, vec::Vec};
pub use weights::WeightInfo;
#[derive(scale_info::TypeInfo, codec::Encode, codec::Decode, codec::MaxEncodedLen)]
@@ -429,9 +429,9 @@ pub mod pallet {
}
};
let check_stash = |stash, deposit, eras_checked: &mut u32| {
let check_stash = |stash, deposit, eras_checked: &mut BTreeSet<EraIndex>| {
let is_exposed = unchecked_eras_to_check.iter().any(|e| {
eras_checked.saturating_inc();
eras_checked.insert(*e);
T::Staking::is_exposed_in_era(&stash, e)
});
@@ -452,7 +452,7 @@ pub mod pallet {
<T as Config>::WeightInfo::on_idle_unstake()
} else {
// eras checked so far.
let mut eras_checked = 0u32;
let mut eras_checked = BTreeSet::<EraIndex>::new();
let pre_length = stashes.len();
let stashes: BoundedVec<(T::AccountId, BalanceOf<T>), T::BatchSize> = stashes
@@ -468,7 +468,7 @@ pub mod pallet {
log!(
debug,
"checked {:?} eras, pre stashes: {:?}, post: {:?}",
eras_checked,
eras_checked.len(),
pre_length,
post_length,
);
@@ -489,7 +489,9 @@ pub mod pallet {
},
}
<T as Config>::WeightInfo::on_idle_check(validator_count * eras_checked)
<T as Config>::WeightInfo::on_idle_check(
validator_count * eras_checked.len() as u32,
)
}
}
}
+1 -1
View File
@@ -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)
}
+2 -1
View File
@@ -982,7 +982,8 @@ pub mod pallet {
// `BondingDuration` to proceed with the unbonding.
let maybe_withdraw_weight = {
if unlocking == T::MaxUnlockingChunks::get() as usize {
let real_num_slashing_spans = Self::slashing_spans(&controller).iter().count();
let real_num_slashing_spans =
Self::slashing_spans(&controller).map_or(0, |s| s.iter().count());
Some(Self::do_withdraw_unbonded(&controller, real_num_slashing_spans as u32)?)
} else {
None
+51
View File
@@ -5725,3 +5725,54 @@ 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));
});
}
#[test]
fn do_withdraw_unbonded_with_wrong_slash_spans_works_as_expected() {
ExtBuilder::default().build_and_execute(|| {
on_offence_now(
&[OffenceDetails {
offender: (11, Staking::eras_stakers(active_era(), 11)),
reporters: vec![],
}],
&[Perbill::from_percent(100)],
);
assert_eq!(Staking::bonded(&11), Some(10));
assert_noop!(
Staking::withdraw_unbonded(RuntimeOrigin::signed(10), 0),
Error::<Test>::IncorrectSlashingSpans
);
let num_slashing_spans = Staking::slashing_spans(&11).map_or(0, |s| s.iter().count());
assert_ok!(Staking::withdraw_unbonded(
RuntimeOrigin::signed(10),
num_slashing_spans as u32
));
});
}
}