diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index f65bdddd36d02..e27c66c75a669 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -38,7 +38,7 @@ use pallet_balances::Config as BalancesConfig; use pallet_babe::BabeEquivocationOffence; use pallet_grandpa::{GrandpaEquivocationOffence, GrandpaTimeSlot}; use pallet_im_online::{Config as ImOnlineConfig, Pallet as ImOnline, UnresponsivenessOffence}; -use pallet_offences::{Config as OffencesConfig, Module as Offences}; +use pallet_offences::{Config as OffencesConfig, Pallet as Offences}; use pallet_session::historical::{Config as HistoricalConfig, IdentificationTuple}; use pallet_session::{Config as SessionConfig, SessionManager}; use pallet_staking::{ diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index cd25ca1ef1dc4..84a7414927d69 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Offences Module +//! # Offences Pallet //! //! Tracks reported offences @@ -26,16 +26,16 @@ mod mock; mod tests; mod migration; -use sp_std::vec::Vec; -use frame_support::{ - decl_module, decl_event, decl_storage, Parameter, weights::Weight, -}; +use sp_std::prelude::*; +use frame_support::weights::Weight; use sp_runtime::{traits::Hash, Perbill}; use sp_staking::{ - SessionIndex, - offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails, OffenceError}, + offence::{Kind, Offence, OffenceDetails, OffenceError, OnOffenceHandler, ReportOffence}, + SessionIndex }; -use codec::{Encode, Decode}; +use codec::{Decode, Encode}; + +pub use pallet::*; /// A binary blob which represents a SCALE codec-encoded `O::TimeSlot`. type OpaqueTimeSlot = Vec; @@ -57,59 +57,87 @@ impl WeightInfo for () { fn on_initialize(_d: u32, ) -> Weight { 1_000_000_000 } } -/// Offences trait -pub trait Config: frame_system::Config { - /// The overarching event type. - type Event: From + Into<::Event>; - /// Full identification of the validator. - type IdentificationTuple: Parameter + Ord; - /// A handler called for every offence report. - type OnOffenceHandler: OnOffenceHandler; -} - -decl_storage! { - trait Store for Module as Offences { - /// The primary structure that holds all offence records keyed by report identifiers. - Reports get(fn reports): - map hasher(twox_64_concat) ReportIdOf - => Option>; - - /// A vector of reports of the same kind that happened at the same time slot. - ConcurrentReportsIndex: - double_map hasher(twox_64_concat) Kind, hasher(twox_64_concat) OpaqueTimeSlot - => Vec>; - - /// Enumerates all reports of a kind along with the time they happened. - /// - /// All reports are sorted by the time of offence. - /// - /// Note that the actual type of this mapping is `Vec`, this is because values of - /// different types are not supported at the moment so we are doing the manual serialization. - ReportsByKindIndex: map hasher(twox_64_concat) Kind => Vec; // (O::TimeSlot, ReportIdOf) +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + /// The pallet's config trait. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type Event: From + IsType<::Event>; + /// Full identification of the validator. + type IdentificationTuple: Parameter + Ord; + /// A handler called for every offence report. + type OnOffenceHandler: OnOffenceHandler; } -} -decl_event!( + /// The primary structure that holds all offence records keyed by report identifiers. + #[pallet::storage] + #[pallet::getter(fn reports)] + pub type Reports = StorageMap< + _, + Twox64Concat, + ReportIdOf, + OffenceDetails, + >; + + /// A vector of reports of the same kind that happened at the same time slot. + #[pallet::storage] + pub type ConcurrentReportsIndex = StorageDoubleMap< + _, + Twox64Concat, + Kind, + Twox64Concat, + OpaqueTimeSlot, + Vec>, + ValueQuery, + >; + + /// Enumerates all reports of a kind along with the time they happened. + /// + /// All reports are sorted by the time of offence. + /// + /// Note that the actual type of this mapping is `Vec`, this is because values of + /// different types are not supported at the moment so we are doing the manual serialization. + #[pallet::storage] + pub type ReportsByKindIndex = StorageMap< + _, + Twox64Concat, + Kind, + Vec, // (O::TimeSlot, ReportIdOf) + ValueQuery, + >; + + /// Events type. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// There is an offence reported of the given `kind` happened at the `session_index` and /// (kind-specific) time slot. This event is not deposited for duplicate slashes. /// \[kind, timeslot\]. Offence(Kind, OpaqueTimeSlot), } -); - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + #[pallet::hooks] + impl Hooks> for Pallet { fn on_runtime_upgrade() -> Weight { migration::remove_deferred_storage::() } } + + #[pallet::call] + impl Pallet {} } impl> - ReportOffence for Module + ReportOffence for Pallet where T::IdentificationTuple: Clone, { @@ -120,11 +148,9 @@ where // Go through all offenders in the offence report and find all offenders that were spotted // in unique reports. - let TriageOutcome { concurrent_offenders } = match Self::triage_offence_report::( - reporters, - &time_slot, - offenders, - ) { + let TriageOutcome { + concurrent_offenders, + } = match Self::triage_offence_report::(reporters, &time_slot, offenders) { Some(triage) => triage, // The report contained only duplicates, so there is no need to slash again. None => return Err(OffenceError::DuplicateReport), @@ -136,7 +162,8 @@ where let new_fraction = O::slash_fraction(offenders_count, validator_set_count); let slash_perbill: Vec<_> = (0..concurrent_offenders.len()) - .map(|_| new_fraction.clone()).collect(); + .map(|_| new_fraction.clone()) + .collect(); T::OnOffenceHandler::on_offence( &concurrent_offenders, @@ -160,7 +187,7 @@ where } } -impl Module { +impl Pallet { /// Compute the ID for the given report properties. /// /// The report id depends on the offence kind, time slot and the id of offender. @@ -200,7 +227,8 @@ impl Module { if any_new { // Load report details for the all reports happened at the same time. - let concurrent_offenders = storage.concurrent_reports + let concurrent_offenders = storage + .concurrent_reports .iter() .filter_map(|report_id| >::get(report_id)) .collect::>(); @@ -238,7 +266,7 @@ impl> ReportIndexStorage { fn load(time_slot: &O::TimeSlot) -> Self { let opaque_time_slot = time_slot.encode(); - let same_kind_reports = ::get(&O::ID); + let same_kind_reports = ReportsByKindIndex::::get(&O::ID); let same_kind_reports = Vec::<(O::TimeSlot, ReportIdOf)>::decode(&mut &same_kind_reports[..]) .unwrap_or_default(); @@ -272,7 +300,7 @@ impl> ReportIndexStorage { /// Dump the indexes to the storage. fn save(self) { - ::insert(&O::ID, self.same_kind_reports.encode()); + ReportsByKindIndex::::insert(&O::ID, self.same_kind_reports.encode()); >::insert( &O::ID, &self.opaque_time_slot, diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 4176a54d9ecec..e7655d7ee29a7 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -31,7 +31,7 @@ use sp_runtime::testing::Header; use sp_runtime::traits::{IdentityLookup, BlakeTwo256}; use sp_core::H256; use frame_support::{ - parameter_types, StorageMap, StorageDoubleMap, + parameter_types, weights::{Weight, constants::{WEIGHT_PER_SECOND, RocksDbWeight}}, }; use crate as offences;