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

Properly defer slashes #11823

Merged
merged 9 commits into from
Jul 26, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions frame/staking/src/pallet/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use frame_support::{
use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
use pallet_session::historical;
use sp_runtime::{
traits::{Bounded, Convert, SaturatedConversion, Saturating, StaticLookup, Zero},
traits::{Bounded, Convert, SaturatedConversion, Saturating, StaticLookup, Zero, One},
Perbill,
};
use sp_staking::{
Expand Down Expand Up @@ -599,18 +599,16 @@ impl<T: Config> Pallet<T> {

/// Apply previously-unapplied slashes on the beginning of a new era, after a delay.
fn apply_unapplied_slashes(active_era: EraIndex) {
if <Self as Store>::UnappliedSlashes::contains_key(&active_era) {
let era_slashes = <Self as Store>::UnappliedSlashes::take(&active_era);
log!(
debug,
"found {} slashes scheduled to be executed in era {}",
active_era,
era_slashes.len()
);
for slash in era_slashes {
let slash_era = active_era.saturating_sub(T::SlashDeferDuration::get());
slashing::apply_slash::<T>(slash, slash_era);
}
let era_slashes = <Self as Store>::UnappliedSlashes::take(&active_era);
log!(
debug,
"found {} slashes scheduled to be executed in era {:?}",
era_slashes.len(),
active_era,
);
for slash in era_slashes {
let slash_era = active_era.saturating_sub(T::SlashDeferDuration::get());
slashing::apply_slash::<T>(slash, slash_era);
}
}

Expand Down Expand Up @@ -1266,7 +1264,7 @@ where
slash_era + slash_defer_duration + 1,
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
);
<Self as Store>::UnappliedSlashes::mutate(
slash_era + slash_defer_duration + 1,
slash_era.saturating_add(slash_defer_duration).saturating_add(One::one()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe pull the slash_era.saturating_add(slash_defer_duration).saturating_add(One::one()) out and use it in the log above as well?
There should also be saturating_inc.

move |for_later| for_later.push(unapplied),
);
add_db_reads_writes(1, 1);
Expand Down
4 changes: 0 additions & 4 deletions frame/staking/src/pallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,6 @@ pub mod pallet {
ValueQuery,
>;

/// The earliest era for which we have a pending, unapplied slash.
#[pallet::storage]
pub(crate) type EarliestUnappliedSlash<T> = StorageValue<_, EraIndex>;
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

/// The last planned session scheduled by the session pallet.
///
/// This is basically in sync with the call to [`pallet_session::SessionManager::new_session`].
Expand Down
11 changes: 7 additions & 4 deletions frame/staking/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2778,7 +2778,7 @@ fn deferred_slashes_are_deferred() {
assert_eq!(Balances::free_balance(11), 1000);
assert_eq!(Balances::free_balance(101), 2000);

let _ = staking_events_since_last_call();
System::reset_events();

// at the start of era 4, slashes from era 1 are processed,
// after being deferred for at least 2 full eras.
Expand Down Expand Up @@ -2814,7 +2814,7 @@ fn retroactive_deferred_slashes_two_eras_before_() {
1, // should be deferred for two full eras, and applied at the beginning of era 4.
DisableStrategy::Never,
);
let _ = staking_events_since_last_call();
System::reset_events();

mock::start_active_era(4);

Expand All @@ -2838,14 +2838,17 @@ fn retroactive_deferred_slashes_one_before() {
mock::start_active_era(1);
let exposure_11_at_era1 = Staking::eras_stakers(active_era(), 11);

mock::start_active_era(2);


mock::start_active_era(3);
on_offence_in_era(
&[OffenceDetails { offender: (11, exposure_11_at_era1), reporters: vec![] }],
&[Perbill::from_percent(10)],
2, // should be deferred for two full eras, and applied at the beginning of era 5.
DisableStrategy::Never,
);
let _ = staking_events_since_last_call();
System::reset_events();

mock::start_active_era(4);
assert_eq!(
Expand Down Expand Up @@ -2989,7 +2992,7 @@ fn remove_deferred() {

// at the start of era 4, slashes from era 1 are processed,
// after being deferred for at least 2 full eras.
let _ = staking_events_since_last_call();
System::reset_events();
mock::start_active_era(4);

// the first slash for 10% was cancelled, but the 15% one
Expand Down