use super::{Config, OffenceDetails, Perbill, SessionIndex};
use frame_support::{pallet_prelude::ValueQuery, storage_alias, traits::Get, weights::Weight};
use sp_staking::offence::{DisableStrategy, OnOffenceHandler};
use sp_std::vec::Vec;
type DeferredOffenceOf<T> = (
Vec<OffenceDetails<<T as frame_system::Config>::AccountId, <T as Config>::IdentificationTuple>>,
Vec<Perbill>,
SessionIndex,
);
#[storage_alias]
type DeferredOffences<T: Config> =
StorageValue<crate::Pallet<T>, Vec<DeferredOffenceOf<T>>, ValueQuery>;
pub fn remove_deferred_storage<T: Config>() -> Weight {
let mut weight = T::DbWeight::get().reads_writes(1, 1);
let deferred = <DeferredOffences<T>>::take();
log::info!(target: "runtime::offences", "have {} deferred offences, applying.", deferred.len());
for (offences, perbill, session) in deferred.iter() {
let consumed = T::OnOffenceHandler::on_offence(
offences,
perbill,
*session,
DisableStrategy::WhenSlashed,
);
weight = weight.saturating_add(consumed);
}
weight
}
#[cfg(test)]
mod test {
use super::*;
use crate::mock::{new_test_ext, with_on_offence_fractions, Runtime as T};
use sp_runtime::Perbill;
use sp_staking::offence::OffenceDetails;
#[test]
fn should_resubmit_deferred_offences() {
new_test_ext().execute_with(|| {
assert_eq!(<DeferredOffences<T>>::get().len(), 0);
with_on_offence_fractions(|f| {
assert_eq!(f.clone(), vec![]);
});
let offence_details = OffenceDetails::<
<T as frame_system::Config>::AccountId,
<T as Config>::IdentificationTuple,
> {
offender: 5,
reporters: vec![],
};
<DeferredOffences<T>>::append((
vec![offence_details],
vec![Perbill::from_percent(5 + 1 * 100 / 5)],
1,
));
assert_eq!(
remove_deferred_storage::<T>(),
<T as frame_system::Config>::DbWeight::get().reads_writes(1, 1),
);
assert!(!<DeferredOffences<T>>::exists());
with_on_offence_fractions(|f| {
assert_eq!(f.clone(), vec![Perbill::from_percent(5 + 1 * 100 / 5)]);
});
})
}
}