1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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)]);
			});
		})
	}
}