diff --git a/substrate/frame/authorship/src/lib.rs b/substrate/frame/authorship/src/lib.rs index a7803319c5..4243ae5571 100644 --- a/substrate/frame/authorship/src/lib.rs +++ b/substrate/frame/authorship/src/lib.rs @@ -23,43 +23,18 @@ use sp_std::{result, prelude::*}; use sp_std::collections::btree_set::BTreeSet; -use frame_support::{decl_module, decl_storage, decl_error, dispatch, ensure}; +use frame_support::dispatch; use frame_support::traits::{FindAuthor, VerifySeal, Get}; use codec::{Encode, Decode}; -use frame_system::ensure_none; use sp_runtime::traits::{Header as HeaderT, One, Zero}; -use frame_support::weights::{Weight, DispatchClass}; use sp_inherents::{InherentIdentifier, ProvideInherent, InherentData}; use sp_authorship::{INHERENT_IDENTIFIER, UnclesInherentData, InherentError}; const MAX_UNCLES: usize = 10; -pub trait Config: frame_system::Config { - /// Find the author of a block. - type FindAuthor: FindAuthor; - /// The number of blocks back we should accept uncles. - /// This means that we will deal with uncle-parents that are - /// `UncleGenerations + 1` before `now`. - type UncleGenerations: Get; - /// A filter for uncles within a block. This is for implementing - /// further constraints on what uncles can be included, other than their ancestry. - /// - /// For PoW, as long as the seals are checked, there is no need to use anything - /// but the `VerifySeal` implementation as the filter. This is because the cost of making many equivocating - /// uncles is high. - /// - /// For PoS, there is no such limitation, so a further constraint must be imposed - /// beyond a seal check in order to prevent an arbitrary number of - /// equivocating uncles from being included. - /// - /// The `OnePerAuthorPerHeight` filter is good for many slot-based PoS - /// engines. - type FilterUncle: FilterUncle; - /// An event handler for authored blocks. - type EventHandler: EventHandler; -} +pub use pallet::*; -/// An event handler for the authorship module. There is a dummy implementation +/// An event handler for the authorship pallet. There is a dummy implementation /// for `()`, which does nothing. #[impl_trait_for_tuples::impl_for_tuples(30)] pub trait EventHandler { @@ -150,21 +125,87 @@ enum UncleEntryItem { InclusionHeight(BlockNumber), Uncle(Hash, Option), } +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; -decl_storage! { - trait Store for Module as Authorship { - /// Uncles - Uncles: Vec>; - /// Author of current block. - Author: Option; - /// Whether uncles were already set in this block. - DidSetUncles: bool; + #[pallet::config] + pub trait Config: frame_system::Config { + /// Find the author of a block. + type FindAuthor: FindAuthor; + /// The number of blocks back we should accept uncles. + /// This means that we will deal with uncle-parents that are + /// `UncleGenerations + 1` before `now`. + type UncleGenerations: Get; + /// A filter for uncles within a block. This is for implementing + /// further constraints on what uncles can be included, other than their ancestry. + /// + /// For PoW, as long as the seals are checked, there is no need to use anything + /// but the `VerifySeal` implementation as the filter. This is because the cost of making many equivocating + /// uncles is high. + /// + /// For PoS, there is no such limitation, so a further constraint must be imposed + /// beyond a seal check in order to prevent an arbitrary number of + /// equivocating uncles from being included. + /// + /// The `OnePerAuthorPerHeight` filter is good for many slot-based PoS + /// engines. + type FilterUncle: FilterUncle; + /// An event handler for authored blocks. + type EventHandler: EventHandler; } -} -decl_error! { - /// Error for the authorship module. - pub enum Error for Module { + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + + #[pallet::hooks] + impl Hooks> for Pallet { + + fn on_initialize(now: T::BlockNumber) -> Weight { + let uncle_generations = T::UncleGenerations::get(); + // prune uncles that are older than the allowed number of generations. + if uncle_generations <= now { + let minimum_height = now - uncle_generations; + Self::prune_old_uncles(minimum_height) + } + + >::put(false); + + T::EventHandler::note_author(Self::author()); + + 0 + } + + fn on_finalize(_: T::BlockNumber) { + // ensure we never go to trie with these values. + >::kill(); + >::kill(); + } + } + + #[pallet::storage] + /// Uncles + pub(super) type Uncles = StorageValue< + _, + Vec>, + ValueQuery, + >; + + #[pallet::storage] + /// Author of current block. + pub(super) type Author = StorageValue<_, T::AccountId, OptionQuery>; + + #[pallet::storage] + /// Whether uncles were already set in this block. + pub(super) type DidSetUncles = StorageValue<_, bool, ValueQuery>; + + + #[pallet::error] + pub enum Error { /// The uncle parent not in the chain. InvalidUncleParent, /// Uncles already set in the block. @@ -180,64 +221,40 @@ decl_error! { /// The uncle isn't recent enough to be included. OldUncle, } -} - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - type Error = Error; - - fn on_initialize(now: T::BlockNumber) -> Weight { - let uncle_generations = T::UncleGenerations::get(); - // prune uncles that are older than the allowed number of generations. - if uncle_generations <= now { - let minimum_height = now - uncle_generations; - Self::prune_old_uncles(minimum_height) - } - - ::DidSetUncles::put(false); - - T::EventHandler::note_author(Self::author()); - - 0 - } - - fn on_finalize() { - // ensure we never go to trie with these values. - ::Author::kill(); - ::DidSetUncles::kill(); - } + #[pallet::call] + impl Pallet { /// Provide a set of uncles. - #[weight = (0, DispatchClass::Mandatory)] - fn set_uncles(origin, new_uncles: Vec) -> dispatch::DispatchResult { + #[pallet::weight((0, DispatchClass::Mandatory))] + fn set_uncles(origin: OriginFor, new_uncles: Vec) -> DispatchResult { ensure_none(origin)?; ensure!(new_uncles.len() <= MAX_UNCLES, Error::::TooManyUncles); - if ::DidSetUncles::get() { + if >::get() { Err(Error::::UnclesAlreadySet)? } - ::DidSetUncles::put(true); + >::put(true); Self::verify_and_import_uncles(new_uncles) } } } -impl Module { +impl Pallet { /// Fetch the author of the block. /// /// This is safe to invoke in `on_initialize` implementations, as well /// as afterwards. pub fn author() -> T::AccountId { // Check the memoized storage value. - if let Some(author) = ::Author::get() { + if let Some(author) = >::get() { return author; } let digest = >::digest(); let pre_runtime_digests = digest.logs.iter().filter_map(|d| d.as_pre_runtime()); if let Some(author) = T::FindAuthor::find_author(pre_runtime_digests) { - ::Author::put(&author); + >::put(&author); author } else { Default::default() @@ -247,7 +264,7 @@ impl Module { fn verify_and_import_uncles(new_uncles: Vec) -> dispatch::DispatchResult { let now = >::block_number(); - let mut uncles = ::Uncles::get(); + let mut uncles = >::get(); uncles.push(UncleEntryItem::InclusionHeight(now)); let mut acc: >::Accumulator = Default::default(); @@ -268,7 +285,7 @@ impl Module { uncles.push(UncleEntryItem::Uncle(hash, author)); } - ::Uncles::put(&uncles); + >::put(&uncles); Ok(()) } @@ -325,7 +342,7 @@ impl Module { } fn prune_old_uncles(minimum_height: T::BlockNumber) { - let mut uncles = ::Uncles::get(); + let mut uncles = >::get(); let prune_entries = uncles.iter().take_while(|item| match item { UncleEntryItem::Uncle(_, _) => true, UncleEntryItem::InclusionHeight(height) => height < &minimum_height, @@ -333,11 +350,11 @@ impl Module { let prune_index = prune_entries.count(); let _ = uncles.drain(..prune_index); - ::Uncles::put(uncles); + >::put(uncles); } } -impl ProvideInherent for Module { +impl ProvideInherent for Pallet { type Call = Call; type Error = InherentError; const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; @@ -347,7 +364,7 @@ impl ProvideInherent for Module { let mut set_uncles = Vec::new(); if !uncles.is_empty() { - let prev_uncles = ::Uncles::get(); + let prev_uncles = >::get(); let mut existing_hashes: Vec<_> = prev_uncles.into_iter().filter_map(|entry| match entry { UncleEntryItem::InclusionHeight(_) => None, @@ -458,7 +475,7 @@ mod tests { pub const UncleGenerations: u64 = 5; } - impl Config for Test { + impl pallet::Config for Test { type FindAuthor = AuthorGiven; type UncleGenerations = UncleGenerations; type FilterUncle = SealVerify; diff --git a/substrate/frame/babe/src/equivocation.rs b/substrate/frame/babe/src/equivocation.rs index 154faa49f0..0fd74882c1 100644 --- a/substrate/frame/babe/src/equivocation.rs +++ b/substrate/frame/babe/src/equivocation.rs @@ -175,7 +175,7 @@ where } fn block_author() -> Option { - Some(>::author()) + Some(>::author()) } } diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index 39831eceb7..d01a67f403 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -52,6 +52,7 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, + Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Historical: pallet_session_historical::{Pallet}, Offences: pallet_offences::{Pallet, Call, Storage, Event}, diff --git a/substrate/frame/grandpa/src/equivocation.rs b/substrate/frame/grandpa/src/equivocation.rs index 8ab86b2fed..441311ebc5 100644 --- a/substrate/frame/grandpa/src/equivocation.rs +++ b/substrate/frame/grandpa/src/equivocation.rs @@ -186,7 +186,7 @@ where } fn block_author() -> Option { - Some(>::author()) + Some(>::author()) } } diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index d59d0d19d0..b13c431dc5 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -52,6 +52,7 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, + Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Staking: pallet_staking::{Pallet, Call, Config, Storage, Event}, diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 4252eae50d..b1d6ba6bd9 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -2709,7 +2709,7 @@ where } fn note_uncle(author: T::AccountId, _age: T::BlockNumber) { Self::reward_by_ids(vec![ - (>::author(), 2), + (>::author(), 2), (author, 1) ]) } diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 188eda8010..c8556a806a 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -96,6 +96,7 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Pallet, Call, Config, Storage, Event}, + Authorship: pallet_authorship::{Pallet, Call, Storage, Inherent}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Staking: staking::{Pallet, Call, Config, Storage, Event}, diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 05eb6fdc5e..634504ccb6 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -2007,7 +2007,7 @@ fn reward_from_authorship_event_handler_works() { ExtBuilder::default().build_and_execute(|| { use pallet_authorship::EventHandler; - assert_eq!(>::author(), 11); + assert_eq!(>::author(), 11); >::note_author(11); >::note_uncle(21, 1);