diff --git a/substrate/frame/balances/src/weights.rs b/substrate/frame/balances/src/weights.rs index 2b69c9c11d..463ac7dd35 100644 --- a/substrate/frame/balances/src/weights.rs +++ b/substrate/frame/balances/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_balances //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2021-01-06, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! DATE: 2021-01-06, STEPS: \[50, \], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: diff --git a/substrate/frame/benchmarking/src/lib.rs b/substrate/frame/benchmarking/src/lib.rs index e5a8bb51a2..94803b88b9 100644 --- a/substrate/frame/benchmarking/src/lib.rs +++ b/substrate/frame/benchmarking/src/lib.rs @@ -930,7 +930,7 @@ macro_rules! impl_benchmark_test { /// This creates a test suite which runs the module's benchmarks. /// -/// When called in [`pallet_example`] as +/// When called in `pallet_example` as /// /// ```rust,ignore /// impl_benchmark_test_suite!(Module, crate::tests::new_test_ext(), crate::tests::Test); diff --git a/substrate/frame/example-offchain-worker/src/lib.rs b/substrate/frame/example-offchain-worker/src/lib.rs index dbcf7b10f4..0c5e92a96e 100644 --- a/substrate/frame/example-offchain-worker/src/lib.rs +++ b/substrate/frame/example-offchain-worker/src/lib.rs @@ -16,7 +16,7 @@ // limitations under the License. //! -//! # Offchain Worker Example Module +//! # Offchain Worker Example Pallet //! //! The Offchain Worker Example: A simple pallet demonstrating //! concepts, APIs and structures common to most offchain workers. @@ -24,9 +24,9 @@ //! Run `cargo doc --package pallet-example-offchain-worker --open` to view this module's //! documentation. //! -//! - [`pallet_example_offchain_worker::Config`](./trait.Config.html) -//! - [`Call`](./enum.Call.html) -//! - [`Module`](./struct.Module.html) +//! - [`Config`] +//! - [`Call`] +//! - [`Pallet`] //! //! //! ## Overview @@ -44,27 +44,18 @@ use frame_system::{ self as system, - ensure_signed, - ensure_none, offchain::{ AppCrypto, CreateSignedTransaction, SendUnsignedTransaction, SendSignedTransaction, SignedPayload, SigningTypes, Signer, SubmitTransaction, } }; -use frame_support::{ - debug, - dispatch::DispatchResult, decl_module, decl_storage, decl_event, - traits::Get, -}; +use frame_support::{debug, traits::Get}; use sp_core::crypto::KeyTypeId; use sp_runtime::{ RuntimeDebug, offchain::{http, Duration, storage::StorageValueRef}, traits::Zero, - transaction_validity::{ - InvalidTransaction, ValidTransaction, TransactionValidity, TransactionSource, - TransactionPriority, - }, + transaction_validity::{InvalidTransaction, ValidTransaction, TransactionValidity}, }; use codec::{Encode, Decode}; use sp_std::vec::Vec; @@ -102,154 +93,59 @@ pub mod crypto { } } -/// This pallet's configuration trait -pub trait Config: CreateSignedTransaction> { - /// The identifier type for an offchain worker. - type AuthorityId: AppCrypto; +pub use pallet::*; - /// The overarching event type. - type Event: From> + Into<::Event>; - /// The overarching dispatch call type. - type Call: From>; +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; - // Configuration parameters + /// This pallet's configuration trait + #[pallet::config] + pub trait Config: CreateSignedTransaction> + frame_system::Config { + /// The identifier type for an offchain worker. + type AuthorityId: AppCrypto; - /// A grace period after we send transaction. - /// - /// To avoid sending too many transactions, we only attempt to send one - /// every `GRACE_PERIOD` blocks. We use Local Storage to coordinate - /// sending between distinct runs of this offchain worker. - type GracePeriod: Get; + /// The overarching event type. + type Event: From> + IsType<::Event>; - /// Number of blocks of cooldown after unsigned transaction is included. - /// - /// This ensures that we only accept unsigned transactions once, every `UnsignedInterval` blocks. - type UnsignedInterval: Get; + /// The overarching dispatch call type. + type Call: From>; - /// A configuration for base priority of unsigned transactions. - /// - /// This is exposed so that it can be tuned for particular runtime, when - /// multiple pallets send unsigned transactions. - type UnsignedPriority: Get; -} + // Configuration parameters -/// Payload used by this example crate to hold price -/// data required to submit a transaction. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct PricePayload { - block_number: BlockNumber, - price: u32, - public: Public, -} + /// A grace period after we send transaction. + /// + /// To avoid sending too many transactions, we only attempt to send one + /// every `GRACE_PERIOD` blocks. We use Local Storage to coordinate + /// sending between distinct runs of this offchain worker. + #[pallet::constant] + type GracePeriod: Get; -impl SignedPayload for PricePayload { - fn public(&self) -> T::Public { - self.public.clone() + /// Number of blocks of cooldown after unsigned transaction is included. + /// + /// This ensures that we only accept unsigned transactions once, every `UnsignedInterval` blocks. + #[pallet::constant] + type UnsignedInterval: Get; + + /// A configuration for base priority of unsigned transactions. + /// + /// This is exposed so that it can be tuned for particular runtime, when + /// multiple pallets send unsigned transactions. + #[pallet::constant] + type UnsignedPriority: Get; } -} -decl_storage! { - trait Store for Module as ExampleOffchainWorker { - /// A vector of recently submitted prices. - /// - /// This is used to calculate average price, should have bounded size. - Prices get(fn prices): Vec; - /// Defines the block when next unsigned transaction will be accepted. - /// - /// To prevent spam of unsigned (and unpayed!) transactions on the network, - /// we only allow one transaction every `T::UnsignedInterval` blocks. - /// This storage entry defines when new transaction is going to be accepted. - NextUnsignedAt get(fn next_unsigned_at): T::BlockNumber; - } -} - -decl_event!( - /// Events generated by the module. - pub enum Event where AccountId = ::AccountId { - /// Event generated when new price is accepted to contribute to the average. - /// \[price, who\] - NewPrice(u32, AccountId), - } -); - -decl_module! { - /// A public part of the pallet. - pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; - - /// Submit new price to the list. - /// - /// This method is a public function of the module and can be called from within - /// a transaction. It appends given `price` to current list of prices. - /// In our example the `offchain worker` will create, sign & submit a transaction that - /// calls this function passing the price. - /// - /// The transaction needs to be signed (see `ensure_signed`) check, so that the caller - /// pays a fee to execute it. - /// This makes sure that it's not easy (or rather cheap) to attack the chain by submitting - /// excesive transactions, but note that it doesn't ensure the price oracle is actually - /// working and receives (and provides) meaningful data. - /// This example is not focused on correctness of the oracle itself, but rather its - /// purpose is to showcase offchain worker capabilities. - #[weight = 0] - pub fn submit_price(origin, price: u32) -> DispatchResult { - // Retrieve sender of the transaction. - let who = ensure_signed(origin)?; - // Add the price to the on-chain list. - Self::add_price(who, price); - Ok(()) - } - - /// Submit new price to the list via unsigned transaction. - /// - /// Works exactly like the `submit_price` function, but since we allow sending the - /// transaction without a signature, and hence without paying any fees, - /// we need a way to make sure that only some transactions are accepted. - /// This function can be called only once every `T::UnsignedInterval` blocks. - /// Transactions that call that function are de-duplicated on the pool level - /// via `validate_unsigned` implementation and also are rendered invalid if - /// the function has already been called in current "session". - /// - /// It's important to specify `weight` for unsigned calls as well, because even though - /// they don't charge fees, we still don't want a single block to contain unlimited - /// number of such transactions. - /// - /// This example is not focused on correctness of the oracle itself, but rather its - /// purpose is to showcase offchain worker capabilities. - #[weight = 0] - pub fn submit_price_unsigned(origin, _block_number: T::BlockNumber, price: u32) - -> DispatchResult - { - // This ensures that the function can only be called via unsigned transaction. - ensure_none(origin)?; - // Add the price to the on-chain list, but mark it as coming from an empty address. - Self::add_price(Default::default(), price); - // now increment the block number at which we expect next unsigned transaction. - let current_block = >::block_number(); - >::put(current_block + T::UnsignedInterval::get()); - Ok(()) - } - - #[weight = 0] - pub fn submit_price_unsigned_with_signed_payload( - origin, - price_payload: PricePayload, - _signature: T::Signature, - ) -> DispatchResult { - // This ensures that the function can only be called via unsigned transaction. - ensure_none(origin)?; - // Add the price to the on-chain list, but mark it as coming from an empty address. - Self::add_price(Default::default(), price_payload.price); - // now increment the block number at which we expect next unsigned transaction. - let current_block = >::block_number(); - >::put(current_block + T::UnsignedInterval::get()); - Ok(()) - } + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + #[pallet::hooks] + impl Hooks> for Pallet { /// Offchain Worker entry point. /// - /// By implementing `fn offchain_worker` within `decl_module!` you declare a new offchain - /// worker. + /// By implementing `fn offchain_worker` you declare a new offchain worker. /// This function will be called when the node is fully synced and a new best block is /// succesfuly imported. /// Note that it's not guaranteed for offchain workers to run on EVERY block, there might @@ -270,7 +166,7 @@ decl_module! { // to the storage and other included pallets. // // We can easily import `frame_system` and retrieve a block hash of the parent block. - let parent_hash = >::block_hash(block_number - 1u32.into()); + let parent_hash = >::block_hash(block_number - 1u32.into()); debug::debug!("Current block: {:?} (parent hash: {:?})", block_number, parent_hash); // It's a good practice to keep `fn offchain_worker()` function minimal, and move most @@ -296,6 +192,151 @@ decl_module! { } } } + + /// A public part of the pallet. + #[pallet::call] + impl Pallet { + /// Submit new price to the list. + /// + /// This method is a public function of the module and can be called from within + /// a transaction. It appends given `price` to current list of prices. + /// In our example the `offchain worker` will create, sign & submit a transaction that + /// calls this function passing the price. + /// + /// The transaction needs to be signed (see `ensure_signed`) check, so that the caller + /// pays a fee to execute it. + /// This makes sure that it's not easy (or rather cheap) to attack the chain by submitting + /// excesive transactions, but note that it doesn't ensure the price oracle is actually + /// working and receives (and provides) meaningful data. + /// This example is not focused on correctness of the oracle itself, but rather its + /// purpose is to showcase offchain worker capabilities. + #[pallet::weight(0)] + pub fn submit_price(origin: OriginFor, price: u32) -> DispatchResultWithPostInfo { + // Retrieve sender of the transaction. + let who = ensure_signed(origin)?; + // Add the price to the on-chain list. + Self::add_price(who, price); + Ok(().into()) + } + + /// Submit new price to the list via unsigned transaction. + /// + /// Works exactly like the `submit_price` function, but since we allow sending the + /// transaction without a signature, and hence without paying any fees, + /// we need a way to make sure that only some transactions are accepted. + /// This function can be called only once every `T::UnsignedInterval` blocks. + /// Transactions that call that function are de-duplicated on the pool level + /// via `validate_unsigned` implementation and also are rendered invalid if + /// the function has already been called in current "session". + /// + /// It's important to specify `weight` for unsigned calls as well, because even though + /// they don't charge fees, we still don't want a single block to contain unlimited + /// number of such transactions. + /// + /// This example is not focused on correctness of the oracle itself, but rather its + /// purpose is to showcase offchain worker capabilities. + #[pallet::weight(0)] + pub fn submit_price_unsigned( + origin: OriginFor, + _block_number: T::BlockNumber, + price: u32 + ) -> DispatchResultWithPostInfo { + // This ensures that the function can only be called via unsigned transaction. + ensure_none(origin)?; + // Add the price to the on-chain list, but mark it as coming from an empty address. + Self::add_price(Default::default(), price); + // now increment the block number at which we expect next unsigned transaction. + let current_block = >::block_number(); + >::put(current_block + T::UnsignedInterval::get()); + Ok(().into()) + } + + #[pallet::weight(0)] + pub fn submit_price_unsigned_with_signed_payload( + origin: OriginFor, + price_payload: PricePayload, + _signature: T::Signature, + ) -> DispatchResultWithPostInfo { + // This ensures that the function can only be called via unsigned transaction. + ensure_none(origin)?; + // Add the price to the on-chain list, but mark it as coming from an empty address. + Self::add_price(Default::default(), price_payload.price); + // now increment the block number at which we expect next unsigned transaction. + let current_block = >::block_number(); + >::put(current_block + T::UnsignedInterval::get()); + Ok(().into()) + } + } + + /// Events for the pallet. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Event generated when new price is accepted to contribute to the average. + /// \[price, who\] + NewPrice(u32, T::AccountId), + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + /// Validate unsigned call to this module. + /// + /// By default unsigned transactions are disallowed, but implementing the validator + /// here we make sure that some particular calls (the ones produced by offchain worker) + /// are being whitelisted and marked as valid. + fn validate_unsigned( + _source: TransactionSource, + call: &Self::Call, + ) -> TransactionValidity { + // Firstly let's check that we call the right function. + if let Call::submit_price_unsigned_with_signed_payload( + ref payload, ref signature + ) = call { + let signature_valid = SignedPayload::::verify::(payload, signature.clone()); + if !signature_valid { + return InvalidTransaction::BadProof.into(); + } + Self::validate_transaction_parameters(&payload.block_number, &payload.price) + } else if let Call::submit_price_unsigned(block_number, new_price) = call { + Self::validate_transaction_parameters(block_number, new_price) + } else { + InvalidTransaction::Call.into() + } + } + } + + /// A vector of recently submitted prices. + /// + /// This is used to calculate average price, should have bounded size. + #[pallet::storage] + #[pallet::getter(fn prices)] + pub(super) type Prices = StorageValue<_, Vec, ValueQuery>; + + /// Defines the block when next unsigned transaction will be accepted. + /// + /// To prevent spam of unsigned (and unpayed!) transactions on the network, + /// we only allow one transaction every `T::UnsignedInterval` blocks. + /// This storage entry defines when new transaction is going to be accepted. + #[pallet::storage] + #[pallet::getter(fn next_unsigned_at)] + pub(super) type NextUnsignedAt = StorageValue<_, T::BlockNumber, ValueQuery>; +} + +/// Payload used by this example crate to hold price +/// data required to submit a transaction. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct PricePayload { + block_number: BlockNumber, + price: u32, + public: Public, +} + +impl SignedPayload for PricePayload { + fn public(&self) -> T::Public { + self.public.clone() + } } enum TransactionType { @@ -306,11 +347,7 @@ enum TransactionType { None, } -/// Most of the functions are moved outside of the `decl_module!` macro. -/// -/// This greatly helps with error messages, as the ones inside the macro -/// can sometimes be hard to debug. -impl Module { +impl Pallet { /// Chooses which transaction type to send. /// /// This function serves mostly to showcase `StorageValue` helper @@ -598,7 +635,7 @@ impl Module { /// Add new price to the list. fn add_price(who: T::AccountId, price: u32) { debug::info!("Adding to the average: {}", price); - Prices::mutate(|prices| { + >::mutate(|prices| { const MAX_LEN: usize = 64; if prices.len() < MAX_LEN { @@ -612,12 +649,12 @@ impl Module { .expect("The average is not empty, because it was just mutated; qed"); debug::info!("Current average price is: {}", average); // here we are raising the NewPrice event - Self::deposit_event(RawEvent::NewPrice(price, who)); + Self::deposit_event(Event::NewPrice(price, who)); } /// Calculate current average price. fn average_price() -> Option { - let prices = Prices::get(); + let prices = >::get(); if prices.is_empty() { None } else { @@ -635,7 +672,7 @@ impl Module { return InvalidTransaction::Stale.into(); } // Let's make sure to reject transactions from the future. - let current_block = >::block_number(); + let current_block = >::block_number(); if ¤t_block < block_number { return InvalidTransaction::Future.into(); } @@ -677,33 +714,3 @@ impl Module { .build() } } - -#[allow(deprecated)] // ValidateUnsigned -impl frame_support::unsigned::ValidateUnsigned for Module { - type Call = Call; - - /// Validate unsigned call to this module. - /// - /// By default unsigned transactions are disallowed, but implementing the validator - /// here we make sure that some particular calls (the ones produced by offchain worker) - /// are being whitelisted and marked as valid. - fn validate_unsigned( - _source: TransactionSource, - call: &Self::Call, - ) -> TransactionValidity { - // Firstly let's check that we call the right function. - if let Call::submit_price_unsigned_with_signed_payload( - ref payload, ref signature - ) = call { - let signature_valid = SignedPayload::::verify::(payload, signature.clone()); - if !signature_valid { - return InvalidTransaction::BadProof.into(); - } - Self::validate_transaction_parameters(&payload.block_number, &payload.price) - } else if let Call::submit_price_unsigned(block_number, new_price) = call { - Self::validate_transaction_parameters(block_number, new_price) - } else { - InvalidTransaction::Call.into() - } - } -} diff --git a/substrate/frame/example-parallel/src/lib.rs b/substrate/frame/example-parallel/src/lib.rs index c83a722be1..e777100c6f 100644 --- a/substrate/frame/example-parallel/src/lib.rs +++ b/substrate/frame/example-parallel/src/lib.rs @@ -22,10 +22,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -use frame_system::ensure_signed; -use frame_support::{ - dispatch::DispatchResult, decl_module, decl_storage, decl_event, -}; use sp_runtime::RuntimeDebug; use codec::{Encode, Decode}; @@ -34,34 +30,72 @@ use sp_std::vec::Vec; #[cfg(test)] mod tests; -pub trait Config: frame_system::Config { - /// The overarching event type. - type Event: From + Into<::Event>; - /// The overarching dispatch call type. - type Call: From>; -} +pub use pallet::*; -decl_storage! { - trait Store for Module as ExampleOffchainWorker { - /// A vector of current participants +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching dispatch call type. + type Call: From>; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + /// A public part of the pallet. + #[pallet::call] + impl Pallet { + /// Get the new event running. + #[pallet::weight(0)] + pub fn run_event(origin: OriginFor, id: Vec) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin)?; + >::kill(); + >::mutate(move |event_id| *event_id = id); + Ok(().into()) + } + + /// Submit list of participants to the current event. /// - /// To enlist someone to participate, signed payload should be - /// sent to `enlist`. - Participants get(fn participants): Vec>; + /// The example utilizes parallel execution by checking half of the + /// signatures in spawned task. + #[pallet::weight(0)] + pub fn enlist_participants(origin: OriginFor, participants: Vec) + -> DispatchResultWithPostInfo + { + let _ = ensure_signed(origin)?; - /// Current event id to enlist participants to. - CurrentEventId get(fn get_current_event_id): Vec; + if validate_participants_parallel(&>::get(), &participants[..]) { + for participant in participants { + >::append(participant.account); + } + } + Ok(().into()) + } } + + /// A vector of current participants + /// + /// To enlist someone to participate, signed payload should be + /// sent to `enlist`. + #[pallet::storage] + #[pallet::getter(fn participants)] + pub(super) type Participants = StorageValue<_, Vec>, ValueQuery>; + + /// Current event id to enlist participants to. + #[pallet::storage] + #[pallet::getter(fn get_current_event_id)] + pub(super) type CurrentEventId = StorageValue<_, Vec, ValueQuery>; } -decl_event!( - /// Events generated by the module. - pub enum Event { - /// When new event is drafted. - NewEventDrafted(Vec), - } -); - /// Request to enlist participant. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] pub struct EnlistedParticipant { @@ -85,40 +119,6 @@ impl EnlistedParticipant { } } -decl_module! { - /// A public part of the pallet. - pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; - - /// Get the new event running. - #[weight = 0] - pub fn run_event(origin, id: Vec) -> DispatchResult { - let _ = ensure_signed(origin)?; - Participants::kill(); - CurrentEventId::mutate(move |event_id| *event_id = id); - Ok(()) - } - - /// Submit list of participants to the current event. - /// - /// The example utilizes parallel execution by checking half of the - /// signatures in spawned task. - #[weight = 0] - pub fn enlist_participants(origin, participants: Vec) - -> DispatchResult - { - let _ = ensure_signed(origin)?; - - if validate_participants_parallel(&CurrentEventId::get(), &participants[..]) { - for participant in participants { - Participants::append(participant.account); - } - } - Ok(()) - } - } -} - fn validate_participants_parallel(event_id: &[u8], participants: &[EnlistedParticipant]) -> bool { fn spawn_verify(data: Vec) -> Vec { diff --git a/substrate/frame/example-parallel/src/tests.rs b/substrate/frame/example-parallel/src/tests.rs index 9c921e0ddf..da2892c67d 100644 --- a/substrate/frame/example-parallel/src/tests.rs +++ b/substrate/frame/example-parallel/src/tests.rs @@ -34,7 +34,7 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system::{Module, Call, Config, Storage, Event}, - Example: pallet_example_parallel::{Module, Call, Storage, Event}, + Example: pallet_example_parallel::{Module, Call, Storage}, } ); @@ -75,7 +75,6 @@ parameter_types! { } impl Config for Test { - type Event = Event; type Call = Call; } diff --git a/substrate/frame/example/src/lib.rs b/substrate/frame/example/src/lib.rs index 763ec504eb..b4ae35c550 100644 --- a/substrate/frame/example/src/lib.rs +++ b/substrate/frame/example/src/lib.rs @@ -63,9 +63,9 @@ //! // Include the following links that shows what trait needs to be implemented to use the pallet //! // and the supported dispatchables that are documented in the Call enum. //! -//! - \[`::Config`](./trait.Config.html) -//! - \[`Call`](./enum.Call.html) -//! - \[`Module`](./struct.Module.html) +//! - \[`Config`] +//! - \[`Call`] +//! - \[`Pallet`] //! //! \## Overview //! @@ -257,11 +257,11 @@ use sp_std::marker::PhantomData; use frame_support::{ - dispatch::DispatchResult, decl_module, decl_storage, decl_event, traits::IsSubType, + dispatch::DispatchResult, traits::IsSubType, weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, Pays}, }; use sp_std::prelude::*; -use frame_system::{ensure_signed, ensure_root}; +use frame_system::{ensure_signed}; use codec::{Encode, Decode}; use sp_runtime::{ traits::{ @@ -278,7 +278,7 @@ use sp_runtime::{ // The `WeightData` trait has access to the arguments of the dispatch that it wants to assign a // weight to. Nonetheless, the trait itself can not make any assumptions about what the generic type // of the arguments (`T`) is. Based on our needs, we could replace `T` with a more concrete type -// while implementing the trait. The `decl_module!` expects whatever implements `WeighData` to +// while implementing the trait. The `pallet::weight` expects whatever implements `WeighData` to // replace `T` with a tuple of the dispatch arguments. This is exactly how we will craft the // implementation below. // @@ -315,111 +315,97 @@ impl PaysFee<(&BalanceOf,)> for WeightForSetDummy /// A type alias for the balance type from this pallet's point of view. type BalanceOf = ::Balance; -/// Our pallet's configuration trait. All our types and constants go in here. If the -/// pallet is dependent on specific other pallets, then their configuration traits -/// should be added to our implied traits list. -/// -/// `frame_system::Config` should always be included in our implied traits. -pub trait Config: pallet_balances::Config { - /// The overarching event type. - type Event: From> + Into<::Event>; -} +// Re-export pallet items so that they can be accessed from the crate namespace. +pub use pallet::*; -decl_storage! { - // A macro for the Storage trait, and its implementation, for this pallet. - // This allows for type-safe usage of the Substrate storage database, so you can - // keep things around between blocks. +// Definition of the pallet logic, to be aggregated at runtime definition through +// `construct_runtime`. +#[frame_support::pallet] +pub mod pallet { + // Import various types used to declare pallet in scope. + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; + + /// Our pallet's configuration trait. All our types and constants go in here. If the + /// pallet is dependent on specific other pallets, then their configuration traits + /// should be added to our implied traits list. + /// + /// `frame_system::Config` should always be included. + #[pallet::config] + pub trait Config: pallet_balances::Config + frame_system::Config { + /// The overarching event type. + type Event: From> + IsType<::Event>; + } + + // Simple declaration of the `Pallet` type. It is placeholder we use to implement traits and + // method. + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + // Pallet implements [`Hooks`] trait to define some logic to execute in some context. + #[pallet::hooks] + impl Hooks> for Pallet { + // `on_initialize` is executed at the beginning of the block before any extrinsic are + // dispatched. + // + // This function must return the weight consumed by `on_initialize` and `on_finalize`. + fn on_initialize(_n: T::BlockNumber) -> Weight { + // Anything that needs to be done at the start of the block. + // We don't do anything here. + + 0 + } + + // `on_finalize` is executed at the end of block after all extrinsic are dispatched. + fn on_finalize(_n: T::BlockNumber) { + // We just kill our dummy storage item. + >::kill(); + } + + // A runtime code run after every block and have access to extended set of APIs. + // + // For instance you can generate extrinsics for the upcoming produced block. + fn offchain_worker(_n: T::BlockNumber) { + // We don't do anything here. + // but we could dispatch extrinsic (transaction/unsigned/inherent) using + // sp_io::submit_extrinsic + } + } + + // The call declaration. This states the entry points that we handle. The + // macro takes care of the marshalling of arguments and dispatch. // - // It is important to update your storage name so that your pallet's - // storage items are isolated from other pallets. - // ---------------------------------vvvvvvv - trait Store for Module as Example { - // Any storage declarations of the form: - // `pub? Name get(fn getter_name)? [config()|config(myname)] [build(|_| {...})] : (= )?;` - // where `` is either: - // - `Type` (a basic value item); or - // - `map hasher(HasherKind) KeyType => ValueType` (a map item). - // - // Note that there are two optional modifiers for the storage type declaration. - // - `Foo: Option`: - // - `Foo::put(1); Foo::get()` returns `Some(1)`; - // - `Foo::kill(); Foo::get()` returns `None`. - // - `Foo: u32`: - // - `Foo::put(1); Foo::get()` returns `1`; - // - `Foo::kill(); Foo::get()` returns `0` (u32::default()). - // e.g. Foo: u32; - // e.g. pub Bar get(fn bar): map hasher(blake2_128_concat) T::AccountId => Vec<(T::Balance, u64)>; - // - // For basic value items, you'll get a type which implements - // `frame_support::StorageValue`. For map items, you'll get a type which - // implements `frame_support::StorageMap`. - // - // If they have a getter (`get(getter_name)`), then your pallet will come - // equipped with `fn getter_name() -> Type` for basic value items or - // `fn getter_name(key: KeyType) -> ValueType` for map items. - Dummy get(fn dummy) config(): Option; - - // A map that has enumerable entries. - Bar get(fn bar) config(): map hasher(blake2_128_concat) T::AccountId => T::Balance; - - // this one uses the default, we'll demonstrate the usage of 'mutate' API. - Foo get(fn foo) config(): T::Balance; - } -} - -decl_event!( - /// Events are a simple means of reporting specific conditions and - /// circumstances that have happened that users, Dapps and/or chain explorers would find - /// interesting and otherwise difficult to detect. - pub enum Event where B = ::Balance { - // Just a normal `enum`, here's a dummy event to ensure it compiles. - /// Dummy event, just here so there's a generic type that's used. - Dummy(B), - } -); - -// The module declaration. This states the entry points that we handle. The -// macro takes care of the marshalling of arguments and dispatch. -// -// Anyone can have these functions execute by signing and submitting -// an extrinsic. Ensure that calls into each of these execute in a time, memory and -// using storage space proportional to any costs paid for by the caller or otherwise the -// difficulty of forcing the call to happen. -// -// Generally you'll want to split these into three groups: -// - Public calls that are signed by an external account. -// - Root calls that are allowed to be made only by the governance system. -// - Unsigned calls that can be of two kinds: -// * "Inherent extrinsics" that are opinions generally held by the block -// authors that build child blocks. -// * Unsigned Transactions that are of intrinsic recognizable utility to the -// network, and are validated by the runtime. -// -// Information about where this dispatch initiated from is provided as the first argument -// "origin". As such functions must always look like: -// -// `fn foo(origin, bar: Bar, baz: Baz) -> Result;` -// -// The `Result` is required as part of the syntax (and expands to the conventional dispatch -// result of `Result<(), &'static str>`). -// -// When you come to `impl` them later in the pallet, you must specify the full type for `origin`: -// -// `fn foo(origin: T::Origin, bar: Bar, baz: Baz) { ... }` -// -// There are three entries in the `frame_system::Origin` enum that correspond -// to the above bullets: `::Signed(AccountId)`, `::Root` and `::None`. You should always match -// against them as the first thing you do in your function. There are three convenience calls -// in system that do the matching for you and return a convenient result: `ensure_signed`, -// `ensure_root` and `ensure_none`. -decl_module! { - // Simple declaration of the `Module` type. Lets the macro know what its working on. - pub struct Module for enum Call where origin: T::Origin { - /// Deposit one of this pallet's events by using the default implementation. - /// It is also possible to provide a custom implementation. - /// For non-generic events, the generic parameter just needs to be dropped, so that it - /// looks like: `fn deposit_event() = default;`. - fn deposit_event() = default; + // Anyone can have these functions execute by signing and submitting + // an extrinsic. Ensure that calls into each of these execute in a time, memory and + // using storage space proportional to any costs paid for by the caller or otherwise the + // difficulty of forcing the call to happen. + // + // Generally you'll want to split these into three groups: + // - Public calls that are signed by an external account. + // - Root calls that are allowed to be made only by the governance system. + // - Unsigned calls that can be of two kinds: + // * "Inherent extrinsics" that are opinions generally held by the block + // authors that build child blocks. + // * Unsigned Transactions that are of intrinsic recognizable utility to the + // network, and are validated by the runtime. + // + // Information about where this dispatch initiated from is provided as the first argument + // "origin". As such functions must always look like: + // + // `fn foo(origin: OriginFor, bar: Bar, baz: Baz) -> DispatchResultWithPostInfo { ... }` + // + // The `DispatchResultWithPostInfo` is required as part of the syntax (and can be found at + // `pallet_prelude::DispatchResultWithPostInfo`). + // + // There are three entries in the `frame_system::Origin` enum that correspond + // to the above bullets: `::Signed(AccountId)`, `::Root` and `::None`. You should always match + // against them as the first thing you do in your function. There are three convenience calls + // in system that do the matching for you and return a convenient result: `ensure_signed`, + // `ensure_root` and `ensure_none`. + #[pallet::call] + impl Pallet { /// This is your public interface. Be extremely careful. /// This is just a simple example of how to interact with the pallet from the external /// world. @@ -458,18 +444,22 @@ decl_module! { // // If you don't respect these rules, it is likely that your chain will be attackable. // - // Each transaction can define an optional `#[weight]` attribute to convey a set of static + // Each transaction must define a `#[pallet::weight(..)]` attribute to convey a set of static // information about its dispatch. FRAME System and FRAME Executive pallet then use this // information to properly execute the transaction, whilst keeping the total load of the // chain in a moderate rate. // - // The _right-hand-side_ value of the `#[weight]` attribute can be any type that implements - // a set of traits, namely [`WeighData`] and [`ClassifyDispatch`]. The former conveys the - // weight (a numeric representation of pure execution time and difficulty) of the - // transaction and the latter demonstrates the [`DispatchClass`] of the call. A higher - // weight means a larger transaction (less of which can be placed in a single block). - #[weight = 0] - fn accumulate_dummy(origin, increase_by: T::Balance) -> DispatchResult { + // The parenthesized value of the `#[pallet::weight(..)]` attribute can be any type that + // implements a set of traits, namely [`WeighData`] and [`ClassifyDispatch`]. + // The former conveys the weight (a numeric representation of pure execution time and + // difficulty) of the transaction and the latter demonstrates the [`DispatchClass`] of the + // call. A higher weight means a larger transaction (less of which can be placed in a + // single block). + #[pallet::weight(0)] + pub(super) fn accumulate_dummy( + origin: OriginFor, + increase_by: T::Balance + ) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let _sender = ensure_signed(origin)?; @@ -493,10 +483,10 @@ decl_module! { }); // Let's deposit an event to let the outside world know this happened. - Self::deposit_event(RawEvent::Dummy(increase_by)); + Self::deposit_event(Event::Dummy(increase_by)); - // All good. - Ok(()) + // All good, no refund. + Ok(().into()) } /// A privileged call; in this case it resets our dummy value to something new. @@ -506,39 +496,92 @@ decl_module! { // calls to be executed - we don't need to care why. Because it's privileged, we can // assume it's a one-off operation and substantial processing/storage/memory can be used // without worrying about gameability or attack scenarios. - // If you do not specify `Result` explicitly as return value, it will be added automatically - // for you and `Ok(())` will be returned. - #[weight = WeightForSetDummy::(>::from(100u32))] - fn set_dummy(origin, #[compact] new_value: T::Balance) { + #[pallet::weight(WeightForSetDummy::(>::from(100u32)))] + fn set_dummy( + origin: OriginFor, + #[pallet::compact] new_value: T::Balance, + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; // Put the new value into storage. >::put(new_value); + + // All good, no refund. + Ok(().into()) } + } - // The signature could also look like: `fn on_initialize()`. - // This function could also very well have a weight annotation, similar to any other. The - // only difference is that it mut be returned, not annotated. - fn on_initialize(_n: T::BlockNumber) -> Weight { - // Anything that needs to be done at the start of the block. - // We don't do anything here. + /// Events are a simple means of reporting specific conditions and + /// circumstances that have happened that users, Dapps and/or chain explorers would find + /// interesting and otherwise difficult to detect. + #[pallet::event] + /// This attribute generate the function `deposit_event` to deposit one of this pallet event, + /// it is optional, it is also possible to provide a custom implementation. + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + // Just a normal `enum`, here's a dummy event to ensure it compiles. + /// Dummy event, just here so there's a generic type that's used. + Dummy(BalanceOf), + } - 0 + // pallet::storage attributes allow for type-safe usage of the Substrate storage database, + // so you can keep things around between blocks. + // + // Any storage must be one of `StorageValue`, `StorageMap` or `StorageDoubleMap`. + // The first generic holds the prefix to use and is generated by the macro. + // The query kind is either `OptionQuery` (the default) or `ValueQuery`. + // - for `type Foo = StorageValue<_, u32, OptionQuery>`: + // - `Foo::put(1); Foo::get()` returns `Some(1)`; + // - `Foo::kill(); Foo::get()` returns `None`. + // - for `type Foo = StorageValue<_, u32, ValueQuery>`: + // - `Foo::put(1); Foo::get()` returns `1`; + // - `Foo::kill(); Foo::get()` returns `0` (u32::default()). + #[pallet::storage] + // The getter attribute generate a function on `Pallet` placeholder: + // `fn getter_name() -> Type` for basic value items or + // `fn getter_name(key: KeyType) -> ValueType` for map items. + #[pallet::getter(fn dummy)] + pub(super) type Dummy = StorageValue<_, T::Balance>; + + // A map that has enumerable entries. + #[pallet::storage] + #[pallet::getter(fn bar)] + pub(super) type Bar = StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, ValueQuery>; + + // this one uses the query kind: `ValueQuery`, we'll demonstrate the usage of 'mutate' API. + #[pallet::storage] + #[pallet::getter(fn foo)] + pub(super) type Foo = StorageValue<_, T::Balance, ValueQuery>; + + + // The genesis config type. + #[pallet::genesis_config] + pub struct GenesisConfig { + pub dummy: T::Balance, + pub bar: Vec<(T::AccountId, T::Balance)>, + pub foo: T::Balance, + } + + // The default value for the genesis config type. + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self { + dummy: Default::default(), + bar: Default::default(), + foo: Default::default(), + } } + } - // The signature could also look like: `fn on_finalize()` - fn on_finalize(_n: T::BlockNumber) { - // Anything that needs to be done at the end of the block. - // We just kill our dummy storage item. - >::kill(); - } - - // A runtime code run after every block and have access to extended set of APIs. - // - // For instance you can generate extrinsics for the upcoming produced block. - fn offchain_worker(_n: T::BlockNumber) { - // We don't do anything here. - // but we could dispatch extrinsic (transaction/unsigned/inherent) using - // sp_io::submit_extrinsic + // The build of genesis for the pallet. + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + >::put(&self.dummy); + for (a, b) in &self.bar { + >::insert(a, b); + } + >::put(&self.foo); } } } @@ -548,7 +591,7 @@ decl_module! { // - Public interface. These are functions that are `pub` and generally fall into inspector // functions that do not write to storage and operation functions that do. // - Private functions. These are your usual private utilities unavailable to other pallets. -impl Module { +impl Pallet { // Add public immutables and private mutables. #[allow(dead_code)] fn accumulate_foo(origin: T::Origin, increase_by: T::Balance) -> DispatchResult { @@ -684,7 +727,7 @@ mod benchmarking { } } - impl_benchmark_test_suite!(Module, crate::tests::new_test_ext(), crate::tests::Test); + impl_benchmark_test_suite!(Pallet, crate::tests::new_test_ext(), crate::tests::Test); } #[cfg(test)] diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index fc7939fe30..e7af1ccab6 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -2034,9 +2034,9 @@ pub mod pallet_prelude { /// * `add_extra_genesis` fields are converted to `GenesisConfig` field with their correct /// default if specified /// * `add_extra_genesis` build is written into `GenesisBuild::build` -/// * storage items defined with [`pallet`] use the name of the pallet provided by [`PalletInfo::name`] -/// as `pallet_prefix` (in `decl_storage`, storage items used the `pallet_prefix` given as input of -/// `decl_storage` with the syntax `as Example`). +/// * storage items defined with [`pallet`] use the name of the pallet provided by +/// [`traits::PalletInfo::name`] as `pallet_prefix` (in `decl_storage`, storage items used the +/// `pallet_prefix` given as input of `decl_storage` with the syntax `as Example`). /// Thus a runtime using the pallet must be careful with this change. /// To handle this change: /// * either ensure that the name of the pallet given to `construct_runtime!` is the same diff --git a/substrate/frame/system/src/weights.rs b/substrate/frame/system/src/weights.rs index f28e90b34c..ae96659417 100644 --- a/substrate/frame/system/src/weights.rs +++ b/substrate/frame/system/src/weights.rs @@ -16,8 +16,9 @@ // limitations under the License. //! Weights for frame_system +//! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0 -//! DATE: 2020-10-28, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] +//! DATE: 2020-10-28, STEPS: \[50, \], REPEAT: 20, LOW RANGE: [], HIGH RANGE: [] //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 // Executed Command: