From 62914315fd282c3bb528391e59fbd917669d9595 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 13 Jan 2021 17:40:19 +0000 Subject: [PATCH 01/52] PRINT_PALLET_UPGRADE=1 cargo check -p frame-system --- frame/system/src/lib2.rs | 241 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 frame/system/src/lib2.rs diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs new file mode 100644 index 0000000000000..628522b439085 --- /dev/null +++ b/frame/system/src/lib2.rs @@ -0,0 +1,241 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! TODO module docs + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config // TODO_MAYBE_ADDITIONAL_BOUNDS_AND_WHERE_CLAUSE + { + // TODO_ASSOCIATED_TYPE_AND_CONSTANTS + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(PhantomData); + + #[pallet::interface] + impl Hooks> for Pallet + // TODO_MAYBE_WHERE_CLAUSE + { + // TODO_ON_FINALIZE + // TODO_ON_INITIALIZE + // TODO_ON_RUNTIME_UPGRADE + // TODO_INTEGRITY_TEST + // TODO_OFFCHAIN_WORKER + } + + #[pallet::call] + impl Pallet + // TODO_MAYBE_WHERE_CLAUSE + { + // TODO_UPGRADE_DISPATCHABLES + } + + #[pallet::inherent] + // TODO_INHERENT + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + // TODO_EVENT + + // TODO_REMOVE_IF_NO_EVENT + /// Old name generated by `decl_event`. + #[deprecated(note = "use `Event` instead")] + pub type RawEvent = Event; + + #[pallet::error] + // TODO_ERROR + #[pallet::origin] + // TODO_ORIGIN + #[pallet::validate_unsigned] + // TODO_VALIDATE_UNSIGNED + + /// The full account information for a particular account ID. + #[pallet::storage] + #[pallet::getter(fn account)] + pub type Account = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + AccountInfo, + ValueQuery, + >; + + /// Total extrinsics count for the current block. + #[pallet::storage] + pub(super) type ExtrinsicCount = StorageValue<_, u32>; + + /// The current weight for the block. + #[pallet::storage] + #[pallet::getter(fn block_weight)] + pub(super) type BlockWeight = StorageValue<_, ConsumedWeight, ValueQuery>; + + /// Total length (in bytes) for all extrinsics put together, for the current block. + #[pallet::storage] + pub(super) type AllExtrinsicsLen = StorageValue<_, u32>; + + /// Map of block numbers to block hashes. + #[pallet::storage] + #[pallet::getter(fn block_hash)] + pub type BlockHash = + StorageMap<_, Twox64Concat, T::BlockNumber, T::Hash, ValueQuery>; + + /// Extrinsics data for the current block (maps an extrinsic's index to its data). + #[pallet::storage] + #[pallet::getter(fn extrinsic_data)] + pub(super) type ExtrinsicData = + StorageMap<_, Twox64Concat, u32, Vec, ValueQuery>; + + /// The current block number being processed. Set by `execute_block`. + #[pallet::storage] + #[pallet::getter(fn block_number)] + pub(super) type Number = StorageValue<_, T::BlockNumber, ValueQuery>; + + /// Hash of the previous block. + #[pallet::storage] + #[pallet::getter(fn parent_hash)] + pub(super) type ParentHash = StorageValue<_, T::Hash, ValueQuery>; + + /// Digest of the current block, also part of the block header. + #[pallet::storage] + #[pallet::getter(fn digest)] + pub(super) type Digest = StorageValue<_, DigestOf, ValueQuery>; + + /// Events deposited for the current block. + #[pallet::storage] + #[pallet::getter(fn events)] + pub(super) type Events = + StorageValue<_, Vec>, ValueQuery>; + + /// The number of events in the `Events` list. + #[pallet::storage] + #[pallet::getter(fn event_count)] + pub(super) type EventCount = StorageValue<_, EventIndex, ValueQuery>; + + /// Mapping between a topic (represented by T::Hash) and a vector of indexes + /// of events in the `>` list. + /// + /// All topic vectors have deterministic storage locations depending on the topic. This + /// allows light-clients to leverage the changes trie storage tracking mechanism and + /// in case of changes fetch the list of events of interest. + /// + /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just + /// the `EventIndex` then in case if the topic has the same contents on the next block + /// no notification will be triggered thus the event might be lost. + #[pallet::storage] + #[pallet::getter(fn event_topics)] + pub(super) type EventTopics = + StorageMap<_, Blake2_128Concat, T::Hash, Vec<(T::BlockNumber, EventIndex)>, ValueQuery>; + + /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. + #[pallet::storage] + pub type LastRuntimeUpgrade = StorageValue<_, LastRuntimeUpgradeInfo>; + + /// True if we have upgraded so that `type RefCount` is `u32`. False (default) if not. + #[pallet::storage] + pub(super) type UpgradedToU32RefCount = StorageValue<_, bool, ValueQuery>; + + /// The execution phase of the block. + #[pallet::storage] + pub(super) type ExecutionPhase = StorageValue<_, Phase>; + + #[pallet::genesis_config] + pub struct GenesisConfig +// TODO_MAYBE_WHERE_CLAUSE + { + pub changes_trie_config: Option, + #[serde(with = "sp_core::bytes")] + pub code: Vec, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig + // TODO_MAYBE_WHERE_CLAUSE + { + fn default() -> Self { + Self { + changes_trie_config: Default::default(), + code: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig + // TODO_MAYBE_WHERE_CLAUSE + { + fn build(&self) { + { + let builder: fn(&Self) -> _ = |_| vec![(T::BlockNumber::zero(), hash69())]; + let data = &builder(self); + let data: &frame_support::sp_std::vec::Vec<(T::BlockNumber, T::Hash)> = data; + data.iter().for_each(|(k, v)| { + as frame_support::storage::StorageMap + >::insert::<& T:: + BlockNumber, & T::Hash>(k, v); + }); + } + { + let builder: fn(&Self) -> _ = |_| hash69(); + let data = &builder(self); + let v: &T::Hash = data; + as frame_support::storage::StorageValue>::put::<&T::Hash>( + v, + ); + } + { + let builder: fn(&Self) -> _ = + |_| Some(LastRuntimeUpgradeInfo::from(T::Version::get())); + let data = builder(self); + let data = Option::as_ref(&data); + let v: Option<&LastRuntimeUpgradeInfo> = data; + if let Some(v) = v { + >::put::<&LastRuntimeUpgradeInfo>(v); + } + } + { + let builder: fn(&Self) -> _ = |_| true; + let data = &builder(self); + let v: &bool = data; + >::put::<&bool>( + v, + ); + } + let extra_genesis_builder: fn(&Self) = |config: &GenesisConfig| { + use codec::Encode; + sp_io::storage::set(well_known_keys::CODE, &config.code); + sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); + if let Some(ref changes_trie_config) = config.changes_trie_config { + sp_io::storage::set( + well_known_keys::CHANGES_TRIE_CONFIG, + &changes_trie_config.encode(), + ); + } + }; + extra_genesis_builder(self); + } + } +} From 7c1a11f60a950cf57661f5ef613e22e3fd58d745 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 13 Jan 2021 17:43:00 +0000 Subject: [PATCH 02/52] Copy attributes, imports, mods and type defs --- frame/system/src/lib2.rs | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index 628522b439085..d436128bb1a5b 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -17,6 +17,80 @@ //! TODO module docs +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +use serde::Serialize; +use sp_std::prelude::*; +#[cfg(any(feature = "std", test))] +use sp_std::map; +use sp_std::convert::Infallible; +use sp_std::marker::PhantomData; +use sp_std::fmt::Debug; +use sp_version::RuntimeVersion; +use sp_runtime::{ + RuntimeDebug, Perbill, DispatchError, Either, generic, + traits::{ + self, CheckEqual, AtLeast32Bit, Zero, Lookup, LookupError, + SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, + MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, + Dispatchable, AtLeast32BitUnsigned, Saturating, + }, + offchain::storage_lock::BlockNumberProvider, +}; + +use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; +use frame_support::{ + decl_module, decl_event, decl_storage, decl_error, Parameter, ensure, debug, + storage, + traits::{ + Contains, Get, PalletInfo, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, + StoredMap, EnsureOrigin, OriginTrait, Filter, + }, + weights::{ + Weight, RuntimeDbWeight, DispatchInfo, DispatchClass, + extract_actual_weight, PerDispatchClass, + }, + dispatch::DispatchResultWithPostInfo, +}; +use codec::{Encode, Decode, FullCodec, EncodeLike}; + +#[cfg(any(feature = "std", test))] +use sp_io::TestExternalities; + +pub mod offchain; +pub mod limits; +#[cfg(test)] +pub(crate) mod mock; + +mod extensions; +pub mod weights; +#[cfg(test)] +mod tests; + + +pub use extensions::{ + check_mortality::CheckMortality, check_genesis::CheckGenesis, check_nonce::CheckNonce, + check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion, + check_weight::CheckWeight, +}; +// Backward compatible re-export. +pub use extensions::check_mortality::CheckMortality as CheckEra; +pub use weights::WeightInfo; + +/// Compute the trie root of a list of extrinsics. +pub fn extrinsics_root(extrinsics: &[E]) -> H::Output { + extrinsics_data_root::(extrinsics.iter().map(codec::Encode::encode).collect()) +} + +/// Compute the trie root of a list of extrinsics. +pub fn extrinsics_data_root(xts: Vec>) -> H::Output { + H::ordered_trie_root(xts) +} + +/// An object to track the currently used extrinsic weight in a block. +pub type ConsumedWeight = PerDispatchClass; + pub use pallet::*; #[frame_support::pallet] From ea53dde96bdbcdd13f16520248ac7271e92aa337 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 13 Jan 2021 17:45:28 +0000 Subject: [PATCH 03/52] Copy Config trait --- frame/system/src/lib2.rs | 110 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 6 deletions(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index d436128bb1a5b..cdea918d8aef3 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -100,12 +100,110 @@ pub mod pallet { use frame_system::pallet_prelude::*; #[pallet::config] - pub trait Config: frame_system::Config // TODO_MAYBE_ADDITIONAL_BOUNDS_AND_WHERE_CLAUSE - { - // TODO_ASSOCIATED_TYPE_AND_CONSTANTS - } - - #[pallet::pallet] + /// System configuration trait. Implemented by runtime. + pub trait Config: 'static + Eq + Clone { + /// The basic call filter to use in Origin. All origins are built with this filter as base, + /// except Root. + type BaseCallFilter: Filter; + + /// Block & extrinsics weights: base values and limits. + type BlockWeights: Get; + + /// The maximum length of a block (in bytes). + type BlockLength: Get; + + /// The `Origin` type used by dispatchable calls. + type Origin: + Into, Self::Origin>> + + From> + + Clone + + OriginTrait; + + /// The aggregated `Call` type. + type Call: Dispatchable + Debug; + + /// Account index (aka nonce) type. This stores the number of previous transactions associated + /// with a sender account. + type Index: + Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit + + Copy; + + /// The block number type used by the runtime. + type BlockNumber: + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + + AtLeast32BitUnsigned + Default + Bounded + Copy + sp_std::hash::Hash + + sp_std::str::FromStr + MaybeMallocSizeOf; + + /// The output of the `Hashing` function. + type Hash: + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + Ord + + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + MaybeMallocSizeOf; + + /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). + type Hashing: Hash; + + /// The user account identifier type for the runtime. + type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + + Default; + + /// Converting trait to take a source type and convert to `AccountId`. + /// + /// Used to define the type and conversion mechanism for referencing accounts in transactions. + /// It's perfectly reasonable for this to be an identity conversion (with the source type being + /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient + /// alternatives. + type Lookup: StaticLookup; + + /// The block header. + type Header: Parameter + traits::Header< + Number = Self::BlockNumber, + Hash = Self::Hash, + >; + + /// The aggregated event type of the runtime. + type Event: Parameter + Member + From> + Debug; + + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount: Get; + + /// The weight of runtime database operations the runtime can invoke. + type DbWeight: Get; + + /// Get the chain's current version. + type Version: Get; + + /// Provides information about the pallet setup in the runtime. + /// + /// Expects the `PalletInfo` type that is being generated by `construct_runtime!` in the + /// runtime. + /// + /// For tests it is okay to use `()` as type, however it will provide "useless" data. + type PalletInfo: PalletInfo; + + /// Data to be associated with an account (other than nonce/transaction counter, which this + /// module does regardless). + type AccountData: Member + FullCodec + Clone + Default; + + /// Handler for when a new account has just been created. + type OnNewAccount: OnNewAccount; + + /// A function that is invoked when an account has been determined to be dead. + /// + /// All resources should be cleaned up associated with the given account. + type OnKilledAccount: OnKilledAccount; + + type SystemWeightInfo: WeightInfo; + + /// The designated SS85 prefix of this chain. + /// + /// This replaces the "ss58Format" property declared in the chain spec. Reason is + /// that the runtime should know about the prefix in order to make use of it as + /// an identifier of the chain. + type SS58Prefix: Get; + } + + + #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(PhantomData); From 519a7f2c61ad4d39fb46ecd98895e2b30644d256 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 13 Jan 2021 17:55:49 +0000 Subject: [PATCH 04/52] Annotate constants --- frame/system/src/lib2.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index cdea918d8aef3..061a64ff4e581 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -107,6 +107,7 @@ pub mod pallet { type BaseCallFilter: Filter; /// Block & extrinsics weights: base values and limits. + #[pallet::constant] type BlockWeights: Get; /// The maximum length of a block (in bytes). @@ -164,9 +165,11 @@ pub mod pallet { type Event: Parameter + Member + From> + Debug; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + #[pallet::constant] type BlockHashCount: Get; /// The weight of runtime database operations the runtime can invoke. + #[pallet::constant] type DbWeight: Get; /// Get the chain's current version. @@ -199,6 +202,7 @@ pub mod pallet { /// This replaces the "ss58Format" property declared in the chain spec. Reason is /// that the runtime should know about the prefix in order to make use of it as /// an identifier of the chain. + #[pallet::constant] type SS58Prefix: Get; } From 7816dc7657e12f8f6cbd56532714f4fddf807b19 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 13 Jan 2021 17:58:08 +0000 Subject: [PATCH 05/52] Tabify --- frame/system/src/lib2.rs | 427 +++++++++++++++++++-------------------- 1 file changed, 213 insertions(+), 214 deletions(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index 061a64ff4e581..dfa8e62cfde6e 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -95,11 +95,11 @@ pub use pallet::*; #[frame_support::pallet] pub mod pallet { - use super::*; - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; - #[pallet::config] + #[pallet::config] /// System configuration trait. Implemented by runtime. pub trait Config: 'static + Eq + Clone { /// The basic call filter to use in Origin. All origins are built with this filter as base, @@ -118,7 +118,7 @@ pub mod pallet { Into, Self::Origin>> + From> + Clone - + OriginTrait; + + OriginTrait; /// The aggregated `Call` type. type Call: Dispatchable + Debug; @@ -141,7 +141,7 @@ pub mod pallet { + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + MaybeMallocSizeOf; /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). - type Hashing: Hash; + type Hashing: Hash; /// The user account identifier type for the runtime. type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord @@ -153,12 +153,12 @@ pub mod pallet { /// It's perfectly reasonable for this to be an identity conversion (with the source type being /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient /// alternatives. - type Lookup: StaticLookup; + type Lookup: StaticLookup; /// The block header. type Header: Parameter + traits::Header< - Number = Self::BlockNumber, - Hash = Self::Hash, + Number=Self::BlockNumber, + Hash=Self::Hash, >; /// The aggregated event type of the runtime. @@ -208,210 +208,209 @@ pub mod pallet { #[pallet::pallet] - #[pallet::generate_store(pub(super) trait Store)] - pub struct Pallet(PhantomData); - - #[pallet::interface] - impl Hooks> for Pallet - // TODO_MAYBE_WHERE_CLAUSE - { - // TODO_ON_FINALIZE - // TODO_ON_INITIALIZE - // TODO_ON_RUNTIME_UPGRADE - // TODO_INTEGRITY_TEST - // TODO_OFFCHAIN_WORKER - } - - #[pallet::call] - impl Pallet - // TODO_MAYBE_WHERE_CLAUSE - { - // TODO_UPGRADE_DISPATCHABLES - } - - #[pallet::inherent] - // TODO_INHERENT - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - // TODO_EVENT - - // TODO_REMOVE_IF_NO_EVENT - /// Old name generated by `decl_event`. - #[deprecated(note = "use `Event` instead")] - pub type RawEvent = Event; - - #[pallet::error] - // TODO_ERROR - #[pallet::origin] - // TODO_ORIGIN - #[pallet::validate_unsigned] - // TODO_VALIDATE_UNSIGNED - - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; - - /// Total extrinsics count for the current block. - #[pallet::storage] - pub(super) type ExtrinsicCount = StorageValue<_, u32>; - - /// The current weight for the block. - #[pallet::storage] - #[pallet::getter(fn block_weight)] - pub(super) type BlockWeight = StorageValue<_, ConsumedWeight, ValueQuery>; - - /// Total length (in bytes) for all extrinsics put together, for the current block. - #[pallet::storage] - pub(super) type AllExtrinsicsLen = StorageValue<_, u32>; - - /// Map of block numbers to block hashes. - #[pallet::storage] - #[pallet::getter(fn block_hash)] - pub type BlockHash = - StorageMap<_, Twox64Concat, T::BlockNumber, T::Hash, ValueQuery>; - - /// Extrinsics data for the current block (maps an extrinsic's index to its data). - #[pallet::storage] - #[pallet::getter(fn extrinsic_data)] - pub(super) type ExtrinsicData = - StorageMap<_, Twox64Concat, u32, Vec, ValueQuery>; - - /// The current block number being processed. Set by `execute_block`. - #[pallet::storage] - #[pallet::getter(fn block_number)] - pub(super) type Number = StorageValue<_, T::BlockNumber, ValueQuery>; - - /// Hash of the previous block. - #[pallet::storage] - #[pallet::getter(fn parent_hash)] - pub(super) type ParentHash = StorageValue<_, T::Hash, ValueQuery>; - - /// Digest of the current block, also part of the block header. - #[pallet::storage] - #[pallet::getter(fn digest)] - pub(super) type Digest = StorageValue<_, DigestOf, ValueQuery>; - - /// Events deposited for the current block. - #[pallet::storage] - #[pallet::getter(fn events)] - pub(super) type Events = - StorageValue<_, Vec>, ValueQuery>; - - /// The number of events in the `Events` list. - #[pallet::storage] - #[pallet::getter(fn event_count)] - pub(super) type EventCount = StorageValue<_, EventIndex, ValueQuery>; - - /// Mapping between a topic (represented by T::Hash) and a vector of indexes - /// of events in the `>` list. - /// - /// All topic vectors have deterministic storage locations depending on the topic. This - /// allows light-clients to leverage the changes trie storage tracking mechanism and - /// in case of changes fetch the list of events of interest. - /// - /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just - /// the `EventIndex` then in case if the topic has the same contents on the next block - /// no notification will be triggered thus the event might be lost. - #[pallet::storage] - #[pallet::getter(fn event_topics)] - pub(super) type EventTopics = - StorageMap<_, Blake2_128Concat, T::Hash, Vec<(T::BlockNumber, EventIndex)>, ValueQuery>; - - /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. - #[pallet::storage] - pub type LastRuntimeUpgrade = StorageValue<_, LastRuntimeUpgradeInfo>; - - /// True if we have upgraded so that `type RefCount` is `u32`. False (default) if not. - #[pallet::storage] - pub(super) type UpgradedToU32RefCount = StorageValue<_, bool, ValueQuery>; - - /// The execution phase of the block. - #[pallet::storage] - pub(super) type ExecutionPhase = StorageValue<_, Phase>; - - #[pallet::genesis_config] - pub struct GenesisConfig + #[pallet::generate_store(pub (super) trait Store)] + pub struct Pallet(PhantomData); + + #[pallet::interface] + impl Hooks> for Pallet + // TODO_MAYBE_WHERE_CLAUSE + { + // TODO_ON_FINALIZE + // TODO_ON_INITIALIZE + // TODO_ON_RUNTIME_UPGRADE + // TODO_INTEGRITY_TEST + // TODO_OFFCHAIN_WORKER + } + + #[pallet::call] + impl Pallet + // TODO_MAYBE_WHERE_CLAUSE + { + // TODO_UPGRADE_DISPATCHABLES + } + + #[pallet::inherent] + // TODO_INHERENT + #[pallet::event] + #[pallet::generate_deposit(pub (super) fn deposit_event)] + // TODO_EVENT + + // TODO_REMOVE_IF_NO_EVENT + /// Old name generated by `decl_event`. + #[deprecated(note = "use `Event` instead")] + pub type RawEvent = Event; + + #[pallet::error] + // TODO_ERROR + #[pallet::origin] + // TODO_ORIGIN + #[pallet::validate_unsigned] + // TODO_VALIDATE_UNSIGNED + /// The full account information for a particular account ID. + #[pallet::storage] + #[pallet::getter(fn account)] + pub type Account = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + AccountInfo, + ValueQuery, + >; + + /// Total extrinsics count for the current block. + #[pallet::storage] + pub(super) type ExtrinsicCount = StorageValue<_, u32>; + + /// The current weight for the block. + #[pallet::storage] + #[pallet::getter(fn block_weight)] + pub(super) type BlockWeight = StorageValue<_, ConsumedWeight, ValueQuery>; + + /// Total length (in bytes) for all extrinsics put together, for the current block. + #[pallet::storage] + pub(super) type AllExtrinsicsLen = StorageValue<_, u32>; + + /// Map of block numbers to block hashes. + #[pallet::storage] + #[pallet::getter(fn block_hash)] + pub type BlockHash = + StorageMap<_, Twox64Concat, T::BlockNumber, T::Hash, ValueQuery>; + + /// Extrinsics data for the current block (maps an extrinsic's index to its data). + #[pallet::storage] + #[pallet::getter(fn extrinsic_data)] + pub(super) type ExtrinsicData = + StorageMap<_, Twox64Concat, u32, Vec, ValueQuery>; + + /// The current block number being processed. Set by `execute_block`. + #[pallet::storage] + #[pallet::getter(fn block_number)] + pub(super) type Number = StorageValue<_, T::BlockNumber, ValueQuery>; + + /// Hash of the previous block. + #[pallet::storage] + #[pallet::getter(fn parent_hash)] + pub(super) type ParentHash = StorageValue<_, T::Hash, ValueQuery>; + + /// Digest of the current block, also part of the block header. + #[pallet::storage] + #[pallet::getter(fn digest)] + pub(super) type Digest = StorageValue<_, DigestOf, ValueQuery>; + + /// Events deposited for the current block. + #[pallet::storage] + #[pallet::getter(fn events)] + pub(super) type Events = + StorageValue<_, Vec>, ValueQuery>; + + /// The number of events in the `Events` list. + #[pallet::storage] + #[pallet::getter(fn event_count)] + pub(super) type EventCount = StorageValue<_, EventIndex, ValueQuery>; + + /// Mapping between a topic (represented by T::Hash) and a vector of indexes + /// of events in the `>` list. + /// + /// All topic vectors have deterministic storage locations depending on the topic. This + /// allows light-clients to leverage the changes trie storage tracking mechanism and + /// in case of changes fetch the list of events of interest. + /// + /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just + /// the `EventIndex` then in case if the topic has the same contents on the next block + /// no notification will be triggered thus the event might be lost. + #[pallet::storage] + #[pallet::getter(fn event_topics)] + pub(super) type EventTopics = + StorageMap<_, Blake2_128Concat, T::Hash, Vec<(T::BlockNumber, EventIndex)>, ValueQuery>; + + /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. + #[pallet::storage] + pub type LastRuntimeUpgrade = StorageValue<_, LastRuntimeUpgradeInfo>; + + /// True if we have upgraded so that `type RefCount` is `u32`. False (default) if not. + #[pallet::storage] + pub(super) type UpgradedToU32RefCount = StorageValue<_, bool, ValueQuery>; + + /// The execution phase of the block. + #[pallet::storage] + pub(super) type ExecutionPhase = StorageValue<_, Phase>; + + #[pallet::genesis_config] + pub struct GenesisConfig // TODO_MAYBE_WHERE_CLAUSE - { - pub changes_trie_config: Option, - #[serde(with = "sp_core::bytes")] - pub code: Vec, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig - // TODO_MAYBE_WHERE_CLAUSE - { - fn default() -> Self { - Self { - changes_trie_config: Default::default(), - code: Default::default(), - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig - // TODO_MAYBE_WHERE_CLAUSE - { - fn build(&self) { - { - let builder: fn(&Self) -> _ = |_| vec![(T::BlockNumber::zero(), hash69())]; - let data = &builder(self); - let data: &frame_support::sp_std::vec::Vec<(T::BlockNumber, T::Hash)> = data; - data.iter().for_each(|(k, v)| { - as frame_support::storage::StorageMap - >::insert::<& T:: - BlockNumber, & T::Hash>(k, v); - }); - } - { - let builder: fn(&Self) -> _ = |_| hash69(); - let data = &builder(self); - let v: &T::Hash = data; - as frame_support::storage::StorageValue>::put::<&T::Hash>( - v, - ); - } - { - let builder: fn(&Self) -> _ = - |_| Some(LastRuntimeUpgradeInfo::from(T::Version::get())); - let data = builder(self); - let data = Option::as_ref(&data); - let v: Option<&LastRuntimeUpgradeInfo> = data; - if let Some(v) = v { - >::put::<&LastRuntimeUpgradeInfo>(v); - } - } - { - let builder: fn(&Self) -> _ = |_| true; - let data = &builder(self); - let v: &bool = data; - >::put::<&bool>( - v, - ); - } - let extra_genesis_builder: fn(&Self) = |config: &GenesisConfig| { - use codec::Encode; - sp_io::storage::set(well_known_keys::CODE, &config.code); - sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); - if let Some(ref changes_trie_config) = config.changes_trie_config { - sp_io::storage::set( - well_known_keys::CHANGES_TRIE_CONFIG, - &changes_trie_config.encode(), - ); - } - }; - extra_genesis_builder(self); - } - } + { + pub changes_trie_config: Option, + #[serde(with = "sp_core::bytes")] + pub code: Vec, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig + // TODO_MAYBE_WHERE_CLAUSE + { + fn default() -> Self { + Self { + changes_trie_config: Default::default(), + code: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig + // TODO_MAYBE_WHERE_CLAUSE + { + fn build(&self) { + { + let builder: fn(&Self) -> _ = |_| vec![(T::BlockNumber::zero(), hash69())]; + let data = &builder(self); + let data: &frame_support::sp_std::vec::Vec<(T::BlockNumber, T::Hash)> = data; + data.iter().for_each(|(k, v)| { + as frame_support::storage::StorageMap + >::insert::<&T:: + BlockNumber, &T::Hash>(k, v); + }); + } + { + let builder: fn(&Self) -> _ = |_| hash69(); + let data = &builder(self); + let v: &T::Hash = data; + as frame_support::storage::StorageValue>::put::<&T::Hash>( + v, + ); + } + { + let builder: fn(&Self) -> _ = + |_| Some(LastRuntimeUpgradeInfo::from(T::Version::get())); + let data = builder(self); + let data = Option::as_ref(&data); + let v: Option<&LastRuntimeUpgradeInfo> = data; + if let Some(v) = v { + >::put::<&LastRuntimeUpgradeInfo>(v); + } + } + { + let builder: fn(&Self) -> _ = |_| true; + let data = &builder(self); + let v: &bool = data; + >::put::<&bool>( + v, + ); + } + let extra_genesis_builder: fn(&Self) = |config: &GenesisConfig| { + use codec::Encode; + sp_io::storage::set(well_known_keys::CODE, &config.code); + sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); + if let Some(ref changes_trie_config) = config.changes_trie_config { + sp_io::storage::set( + well_known_keys::CHANGES_TRIE_CONFIG, + &changes_trie_config.encode(), + ); + } + }; + extra_genesis_builder(self); + } + } } From a624cc08bf98e8eb823c1a89778e810b661fcb48 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 09:52:55 +0000 Subject: [PATCH 06/52] Migrate hooks --- frame/system/src/lib2.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index dfa8e62cfde6e..0871e5b76069b 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -211,6 +211,27 @@ pub mod pallet { #[pallet::generate_store(pub (super) trait Store)] pub struct Pallet(PhantomData); + #[pallet::hooks] + impl Hooks for Pallet { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + if !UpgradedToU32RefCount::get() { + Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| + Some(AccountInfo { nonce, refcount: rc as RefCount, data }) + ); + UpgradedToU32RefCount::put(true); + T::BlockWeights::get().max_block + } else { + 0 + } + } + + fn integrity_test() { + T::BlockWeights::get() + .validate() + .expect("The weights are invalid."); + } + } + #[pallet::interface] impl Hooks> for Pallet // TODO_MAYBE_WHERE_CLAUSE From 306f02394cd78f436baad564cdc4c7d196c1210d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 09:57:45 +0000 Subject: [PATCH 07/52] Upgrade template rename interface to hooks --- frame/support/procedural/src/storage/print_pallet_upgrade.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/frame/support/procedural/src/storage/print_pallet_upgrade.rs index 100bb9b35913c..9189724d7860f 100644 --- a/frame/support/procedural/src/storage/print_pallet_upgrade.rs +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -323,8 +323,8 @@ pub mod pallet {{ #[pallet::generate_store({store_vis} trait Store)] pub struct Pallet{decl_gen}(PhantomData{use_gen_tuple}); - #[pallet::interface] - impl{impl_gen} Hooks> for Pallet{use_gen} + #[pallet::hooks] + impl{impl_gen} Hooks for Pallet{use_gen} // TODO_MAYBE_WHERE_CLAUSE {{ // TODO_ON_FINALIZE From 1fb8b3b6216e36f8f7dd9c9b9fc6f9968632f706 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 10:10:04 +0000 Subject: [PATCH 08/52] Migrate pallet call --- frame/system/src/lib2.rs | 207 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 192 insertions(+), 15 deletions(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index 0871e5b76069b..204a1a03b757c 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -232,22 +232,199 @@ pub mod pallet { } } - #[pallet::interface] - impl Hooks> for Pallet - // TODO_MAYBE_WHERE_CLAUSE - { - // TODO_ON_FINALIZE - // TODO_ON_INITIALIZE - // TODO_ON_RUNTIME_UPGRADE - // TODO_INTEGRITY_TEST - // TODO_OFFCHAIN_WORKER - } - #[pallet::call] - impl Pallet - // TODO_MAYBE_WHERE_CLAUSE - { - // TODO_UPGRADE_DISPATCHABLES + impl Pallet { + /// A dispatch that will fill the block weight up to the given ratio. + // TODO: This should only be available for testing, rather than in general usage, but + // that's not possible at present (since it's within the decl_module macro). + #[weight(*_ratio * T::BlockWeights::get().max_block)] + fn fill_block(origin: OriginFor, _ratio: Perbill) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + Ok(().into()) + } + + /// Make some on-chain remark. + /// + /// # + /// - `O(1)` + /// - Base Weight: 0.665 µs, independent of remark length. + /// - No DB operations. + /// # + #[weight(T::SystemWeightInfo::remark(_remark.len() as u32))] + fn remark(origin: OriginFor, _remark: Vec) -> DispatchResultWithPostInfo { + ensure_signed(origin)?; + Ok(().into()) + } + + /// Set the number of pages in the WebAssembly environment's heap. + /// + /// # + /// - `O(1)` + /// - 1 storage write. + /// - Base Weight: 1.405 µs + /// - 1 write to HEAP_PAGES + /// # + #[weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))] + fn set_heap_pages(origin: OriginFor, pages: u64) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); + Ok(().into()) + } + + /// Set the new runtime code. + /// + /// # + /// - `O(C + S)` where `C` length of `code` and `S` complexity of `can_set_code` + /// - 1 storage write (codec `O(C)`). + /// - 1 call to `can_set_code`: `O(S)` (calls `sp_io::misc::runtime_version` which is expensive). + /// - 1 event. + /// The weight of this function is dependent on the runtime, but generally this is very expensive. + /// We will treat this as a full block. + /// # + #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] + pub fn set_code(origin: OriginFor, code: Vec) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + Self::can_set_code(&code)?; + + storage::unhashed::put_raw(well_known_keys::CODE, &code); + Self::deposit_event(RawEvent::CodeUpdated); + Ok(().into()) + } + + /// Set the new runtime code without doing any checks of the given `code`. + /// + /// # + /// - `O(C)` where `C` length of `code` + /// - 1 storage write (codec `O(C)`). + /// - 1 event. + /// The weight of this function is dependent on the runtime. We will treat this as a full block. + /// # + #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] + pub fn set_code_without_checks( + origin: OriginFor, + code: Vec + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + storage::unhashed::put_raw(well_known_keys::CODE, &code); + Self::deposit_event(RawEvent::CodeUpdated); + Ok(().into()) + } + + /// Set the new changes trie configuration. + /// + /// # + /// - `O(1)` + /// - 1 storage write or delete (codec `O(1)`). + /// - 1 call to `deposit_log`: Uses `append` API, so O(1) + /// - Base Weight: 7.218 µs + /// - DB Weight: + /// - Writes: Changes Trie, System Digest + /// # + #[weight((T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational))] + pub fn set_changes_trie_config( + origin: OriginFor, + changes_trie_config: Option + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + match changes_trie_config.clone() { + Some(changes_trie_config) => storage::unhashed::put_raw( + well_known_keys::CHANGES_TRIE_CONFIG, + &changes_trie_config.encode(), + ), + None => storage::unhashed::kill(well_known_keys::CHANGES_TRIE_CONFIG), + } + + let log = generic::DigestItem::ChangesTrieSignal( + generic::ChangesTrieSignal::NewConfiguration(changes_trie_config), + ); + Self::deposit_log(log.into()); + Ok(().into()) + } + + /// Set some items of storage. + /// + /// # + /// - `O(I)` where `I` length of `items` + /// - `I` storage writes (`O(1)`). + /// - Base Weight: 0.568 * i µs + /// - Writes: Number of items + /// # + #[weight(( + T::SystemWeightInfo::set_storage(items.len() as u32), + DispatchClass::Operational, + ))] + fn set_storage(origin: OriginFor, items: Vec) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + for i in &items { + storage::unhashed::put_raw(&i.0, &i.1); + } + Ok(().into()) + } + + /// Kill some items from storage. + /// + /// # + /// - `O(IK)` where `I` length of `keys` and `K` length of one key + /// - `I` storage deletions. + /// - Base Weight: .378 * i µs + /// - Writes: Number of items + /// # + #[weight(( + T::SystemWeightInfo::kill_storage(keys.len() as u32), + DispatchClass::Operational, + ))] + fn kill_storage(origin: OriginFor, keys: Vec) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + for key in &keys { + storage::unhashed::kill(&key); + } + Ok(().into()) + } + + /// Kill all storage items with a key that starts with the given prefix. + /// + /// **NOTE:** We rely on the Root origin to provide us the number of subkeys under + /// the prefix we are removing to accurately calculate the weight of this function. + /// + /// # + /// - `O(P)` where `P` amount of keys with prefix `prefix` + /// - `P` storage deletions. + /// - Base Weight: 0.834 * P µs + /// - Writes: Number of subkeys + 1 + /// # + #[weight(( + T::SystemWeightInfo::kill_prefix(_subkeys.saturating_add(1)), + DispatchClass::Operational, + ))] + fn kill_prefix( + origin: OriginFor, + prefix: Key, + _subkeys: u32 + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + storage::unhashed::kill_prefix(&prefix); + Ok(().into()) + } + + /// Kill the sending account, assuming there are no references outstanding and the composite + /// data is equal to its default value. + /// + /// # + /// - `O(1)` + /// - 1 storage read and deletion. + /// -------------------- + /// Base Weight: 8.626 µs + /// No DB Read or Write operations because caller is already in overlay + /// # + #[weight((T::SystemWeightInfo::suicide(), DispatchClass::Operational))] + pub fn suicide(origin: OriginFor) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let account = Account::::get(&who); + ensure!(account.refcount == 0, Error::::NonZeroRefCount); + ensure!(account.data == T::AccountData::default(), Error::::NonDefaultComposite); + Self::kill_account(&who); + Ok(().into()) + } } #[pallet::inherent] From cb8aa19fa53ffbe1b99311d6a3072740d1209d64 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 10:35:54 +0000 Subject: [PATCH 09/52] Migrate Event --- frame/system/src/lib2.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index 204a1a03b757c..e3fe50f6ec471 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -427,16 +427,24 @@ pub mod pallet { } } - #[pallet::inherent] - // TODO_INHERENT + /// Event for the System module. #[pallet::event] - #[pallet::generate_deposit(pub (super) fn deposit_event)] - // TODO_EVENT + pub enum Event { + /// An extrinsic completed successfully. \[info\] + ExtrinsicSuccess(DispatchInfo), + /// An extrinsic failed. \[error, info\] + ExtrinsicFailed(DispatchError, DispatchInfo), + /// `:code` was updated. + CodeUpdated, + /// A new \[account\] was created. + NewAccount(T::AccountId), + /// An \[account\] was reaped. + KilledAccount(T::AccountId), + } - // TODO_REMOVE_IF_NO_EVENT /// Old name generated by `decl_event`. #[deprecated(note = "use `Event` instead")] - pub type RawEvent = Event; + pub type RawEvent = Event; #[pallet::error] // TODO_ERROR From d973e4a0c3c2ba1eec3531edbd4cf19cc0fcc523 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 10:36:57 +0000 Subject: [PATCH 10/52] Migrate Error --- frame/system/src/lib2.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index e3fe50f6ec471..beefca083fcd6 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -446,8 +446,25 @@ pub mod pallet { #[deprecated(note = "use `Event` instead")] pub type RawEvent = Event; + /// Error for the System module #[pallet::error] - // TODO_ERROR + pub enum Error { + /// The name of specification does not match between the current runtime + /// and the new runtime. + InvalidSpecName, + /// The specification version is not allowed to decrease between the current runtime + /// and the new runtime. + SpecVersionNeedsToIncrease, + /// Failed to extract the runtime version from the new runtime. + /// + /// Either calling `Core_version` or decoding `RuntimeVersion` failed. + FailedToExtractRuntimeVersion, + /// Suicide called when the account has non-default composite data. + NonDefaultComposite, + /// There is a non-zero reference count preventing the account from being purged. + NonZeroRefCount, + } + #[pallet::origin] // TODO_ORIGIN #[pallet::validate_unsigned] From 6ee8dbacab3ce916ebc3bbf2e6bc513fa8dc8c25 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 10:40:49 +0000 Subject: [PATCH 11/52] Migrate Origin --- frame/system/src/lib2.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index beefca083fcd6..0e85a13e7f866 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -465,8 +465,10 @@ pub mod pallet { NonZeroRefCount, } + /// Exposed trait-generic origin type. #[pallet::origin] - // TODO_ORIGIN + pub type Origin = RawOrigin<::AccountId>; + #[pallet::validate_unsigned] // TODO_VALIDATE_UNSIGNED /// The full account information for a particular account ID. From 2c9d575e0ef1b3348649eca6040acd474f96029d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 10:42:59 +0000 Subject: [PATCH 12/52] Remove optional validate_unsigned --- frame/system/src/lib2.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index 0e85a13e7f866..e18d14bf6d344 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -469,8 +469,6 @@ pub mod pallet { #[pallet::origin] pub type Origin = RawOrigin<::AccountId>; - #[pallet::validate_unsigned] - // TODO_VALIDATE_UNSIGNED /// The full account information for a particular account ID. #[pallet::storage] #[pallet::getter(fn account)] From 21dd9d81c650d190cb19090884d354c0495953fe Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:13:23 +0000 Subject: [PATCH 13/52] Remove remaining TODO_MAYBE_WHERE_CLAUSE --- frame/system/src/lib2.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs index e18d14bf6d344..c84ee4ff6bb0b 100644 --- a/frame/system/src/lib2.rs +++ b/frame/system/src/lib2.rs @@ -559,18 +559,14 @@ pub mod pallet { pub(super) type ExecutionPhase = StorageValue<_, Phase>; #[pallet::genesis_config] - pub struct GenesisConfig -// TODO_MAYBE_WHERE_CLAUSE - { + pub struct GenesisConfig { pub changes_trie_config: Option, #[serde(with = "sp_core::bytes")] pub code: Vec, } #[cfg(feature = "std")] - impl Default for GenesisConfig - // TODO_MAYBE_WHERE_CLAUSE - { + impl Default for GenesisConfig { fn default() -> Self { Self { changes_trie_config: Default::default(), @@ -580,9 +576,7 @@ pub mod pallet { } #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig - // TODO_MAYBE_WHERE_CLAUSE - { + impl GenesisBuild for GenesisConfig { fn build(&self) { { let builder: fn(&Self) -> _ = |_| vec![(T::BlockNumber::zero(), hash69())]; From fea632a48fb696cac4a20f59c806162cf7ce5468 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:16:33 +0000 Subject: [PATCH 14/52] Overwrite original lib.rs with migrated lib2.rs. --- frame/system/src/lib.rs | 1407 +++++++++----------------------------- frame/system/src/lib2.rs | 633 ----------------- 2 files changed, 332 insertions(+), 1708 deletions(-) delete mode 100644 frame/system/src/lib2.rs diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 463712ba68df5..c84ee4ff6bb0b 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -15,80 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # System Module -//! -//! The System module provides low-level access to core types and cross-cutting utilities. -//! It acts as the base layer for other pallets to interact with the Substrate framework components. -//! -//! - [`system::Config`](./trait.Config.html) -//! -//! ## Overview -//! -//! The System module defines the core data types used in a Substrate runtime. -//! It also provides several utility functions (see [`Module`](./struct.Module.html)) for other FRAME pallets. -//! -//! In addition, it manages the storage items for extrinsics data, indexes, event records, and digest items, -//! among other things that support the execution of the current block. -//! -//! It also handles low-level tasks like depositing logs, basic set up and take down of -//! temporary storage entries, and access to previous block hashes. -//! -//! ## Interface -//! -//! ### Dispatchable Functions -//! -//! The System module does not implement any dispatchable functions. -//! -//! ### Public Functions -//! -//! See the [`Module`](./struct.Module.html) struct for details of publicly available functions. -//! -//! ### Signed Extensions -//! -//! The System module defines the following extensions: -//! -//! - [`CheckWeight`]: Checks the weight and length of the block and ensure that it does not -//! exceed the limits. -//! - [`CheckNonce`]: Checks the nonce of the transaction. Contains a single payload of type -//! `T::Index`. -//! - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`. -//! - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the -//! signed payload of the transaction. -//! - [`CheckSpecVersion`]: Checks that the runtime version is the same as the one used to sign the -//! transaction. -//! - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign the -//! transaction. -//! -//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed -//! extensions included in a chain. -//! -//! ## Usage -//! -//! ### Prerequisites -//! -//! Import the System module and derive your module's configuration trait from the system trait. -//! -//! ### Example - Get extrinsic count and parent hash for the current block -//! -//! ``` -//! use frame_support::{decl_module, dispatch}; -//! use frame_system::{self as system, ensure_signed}; -//! -//! pub trait Config: system::Config {} -//! -//! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { -//! #[weight = 0] -//! pub fn system_module_example(origin) -> dispatch::DispatchResult { -//! let _sender = ensure_signed(origin)?; -//! let _extrinsic_count = >::extrinsic_count(); -//! let _parent_hash = >::parent_hash(); -//! Ok(()) -//! } -//! } -//! } -//! # fn main() { } -//! ``` +//! TODO module docs #![cfg_attr(not(feature = "std"), no_std)] @@ -164,372 +91,128 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { /// An object to track the currently used extrinsic weight in a block. pub type ConsumedWeight = PerDispatchClass; -/// System configuration trait. Implemented by runtime. -pub trait Config: 'static + Eq + Clone { - /// The basic call filter to use in Origin. All origins are built with this filter as base, - /// except Root. - type BaseCallFilter: Filter; - - /// Block & extrinsics weights: base values and limits. - type BlockWeights: Get; - - /// The maximum length of a block (in bytes). - type BlockLength: Get; - - /// The `Origin` type used by dispatchable calls. - type Origin: - Into, Self::Origin>> - + From> - + Clone - + OriginTrait; - - /// The aggregated `Call` type. - type Call: Dispatchable + Debug; - - /// Account index (aka nonce) type. This stores the number of previous transactions associated - /// with a sender account. - type Index: - Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit - + Copy; - - /// The block number type used by the runtime. - type BlockNumber: - Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + - AtLeast32BitUnsigned + Default + Bounded + Copy + sp_std::hash::Hash + - sp_std::str::FromStr + MaybeMallocSizeOf; - - /// The output of the `Hashing` function. - type Hash: - Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + Ord - + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + MaybeMallocSizeOf; - - /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). - type Hashing: Hash; - - /// The user account identifier type for the runtime. - type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord - + Default; - - /// Converting trait to take a source type and convert to `AccountId`. - /// - /// Used to define the type and conversion mechanism for referencing accounts in transactions. - /// It's perfectly reasonable for this to be an identity conversion (with the source type being - /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient - /// alternatives. - type Lookup: StaticLookup; - - /// The block header. - type Header: Parameter + traits::Header< - Number = Self::BlockNumber, - Hash = Self::Hash, - >; - - /// The aggregated event type of the runtime. - type Event: Parameter + Member + From> + Debug; - - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount: Get; - - /// The weight of runtime database operations the runtime can invoke. - type DbWeight: Get; - - /// Get the chain's current version. - type Version: Get; - - /// Provides information about the pallet setup in the runtime. - /// - /// Expects the `PalletInfo` type that is being generated by `construct_runtime!` in the - /// runtime. - /// - /// For tests it is okay to use `()` as type, however it will provide "useless" data. - type PalletInfo: PalletInfo; - - /// Data to be associated with an account (other than nonce/transaction counter, which this - /// module does regardless). - type AccountData: Member + FullCodec + Clone + Default; - - /// Handler for when a new account has just been created. - type OnNewAccount: OnNewAccount; - - /// A function that is invoked when an account has been determined to be dead. - /// - /// All resources should be cleaned up associated with the given account. - type OnKilledAccount: OnKilledAccount; - - type SystemWeightInfo: WeightInfo; - - /// The designated SS85 prefix of this chain. - /// - /// This replaces the "ss58Format" property declared in the chain spec. Reason is - /// that the runtime should know about the prefix in order to make use of it as - /// an identifier of the chain. - type SS58Prefix: Get; -} - -pub type DigestOf = generic::Digest<::Hash>; -pub type DigestItemOf = generic::DigestItem<::Hash>; - -pub type Key = Vec; -pub type KeyValue = (Vec, Vec); - -/// A phase of a block's execution. -#[derive(Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] -pub enum Phase { - /// Applying an extrinsic. - ApplyExtrinsic(u32), - /// Finalizing the block. - Finalization, - /// Initializing the block. - Initialization, -} - -impl Default for Phase { - fn default() -> Self { - Self::Initialization - } -} - -/// Record of an event happening. -#[derive(Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] -pub struct EventRecord { - /// The phase of the block it happened in. - pub phase: Phase, - /// The event itself. - pub event: E, - /// The list of the topics this event has. - pub topics: Vec, -} - -/// Origin for the System module. -#[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode)] -pub enum RawOrigin { - /// The system itself ordained this dispatch to happen: this is the highest privilege level. - Root, - /// It is signed by some public key and we provide the `AccountId`. - Signed(AccountId), - /// It is signed by nobody, can be either: - /// * included and agreed upon by the validators anyway, - /// * or unsigned transaction validated by a module. - None, -} - -impl From> for RawOrigin { - fn from(s: Option) -> RawOrigin { - match s { - Some(who) => RawOrigin::Signed(who), - None => RawOrigin::None, - } - } -} - -/// Exposed trait-generic origin type. -pub type Origin = RawOrigin<::AccountId>; - -// Create a Hash with 69 for each byte, -// only used to build genesis config. -#[cfg(feature = "std")] -fn hash69 + Default>() -> T { - let mut h = T::default(); - h.as_mut().iter_mut().for_each(|byte| *byte = 69); - h -} - -/// This type alias represents an index of an event. -/// -/// We use `u32` here because this index is used as index for `Events` -/// which can't contain more than `u32::max_value()` items. -type EventIndex = u32; - -/// Type used to encode the number of references an account has. -pub type RefCount = u32; - -/// Information of an account. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] -pub struct AccountInfo { - /// The number of transactions this account has sent. - pub nonce: Index, - /// The number of other modules that currently depend on this account's existence. The account - /// cannot be reaped until this is zero. - pub refcount: RefCount, - /// The additional data that belongs to this account. Used to store the balance(s) in a lot of - /// chains. - pub data: AccountData, -} - -/// Stores the `spec_version` and `spec_name` of when the last runtime upgrade -/// happened. -#[derive(sp_runtime::RuntimeDebug, Encode, Decode)] -#[cfg_attr(feature = "std", derive(PartialEq))] -pub struct LastRuntimeUpgradeInfo { - pub spec_version: codec::Compact, - pub spec_name: sp_runtime::RuntimeString, -} - -impl LastRuntimeUpgradeInfo { - /// Returns if the runtime was upgraded in comparison of `self` and `current`. - /// - /// Checks if either the `spec_version` increased or the `spec_name` changed. - pub fn was_upgraded(&self, current: &sp_version::RuntimeVersion) -> bool { - current.spec_version > self.spec_version.0 || current.spec_name != self.spec_name - } -} - -impl From for LastRuntimeUpgradeInfo { - fn from(version: sp_version::RuntimeVersion) -> Self { - Self { - spec_version: version.spec_version.into(), - spec_name: version.spec_name, - } - } -} - -decl_storage! { - trait Store for Module as System { - /// The full account information for a particular account ID. - pub Account get(fn account): - map hasher(blake2_128_concat) T::AccountId => AccountInfo; - - /// Total extrinsics count for the current block. - ExtrinsicCount: Option; - - /// The current weight for the block. - BlockWeight get(fn block_weight): ConsumedWeight; - - /// Total length (in bytes) for all extrinsics put together, for the current block. - AllExtrinsicsLen: Option; - - /// Map of block numbers to block hashes. - pub BlockHash get(fn block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): - map hasher(twox_64_concat) T::BlockNumber => T::Hash; - - /// Extrinsics data for the current block (maps an extrinsic's index to its data). - ExtrinsicData get(fn extrinsic_data): map hasher(twox_64_concat) u32 => Vec; - - /// The current block number being processed. Set by `execute_block`. - Number get(fn block_number): T::BlockNumber; +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + /// System configuration trait. Implemented by runtime. + pub trait Config: 'static + Eq + Clone { + /// The basic call filter to use in Origin. All origins are built with this filter as base, + /// except Root. + type BaseCallFilter: Filter; + + /// Block & extrinsics weights: base values and limits. + #[pallet::constant] + type BlockWeights: Get; + + /// The maximum length of a block (in bytes). + type BlockLength: Get; + + /// The `Origin` type used by dispatchable calls. + type Origin: + Into, Self::Origin>> + + From> + + Clone + + OriginTrait; + + /// The aggregated `Call` type. + type Call: Dispatchable + Debug; + + /// Account index (aka nonce) type. This stores the number of previous transactions associated + /// with a sender account. + type Index: + Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit + + Copy; + + /// The block number type used by the runtime. + type BlockNumber: + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + + AtLeast32BitUnsigned + Default + Bounded + Copy + sp_std::hash::Hash + + sp_std::str::FromStr + MaybeMallocSizeOf; + + /// The output of the `Hashing` function. + type Hash: + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + Ord + + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + MaybeMallocSizeOf; + + /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). + type Hashing: Hash; + + /// The user account identifier type for the runtime. + type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + + Default; + + /// Converting trait to take a source type and convert to `AccountId`. + /// + /// Used to define the type and conversion mechanism for referencing accounts in transactions. + /// It's perfectly reasonable for this to be an identity conversion (with the source type being + /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient + /// alternatives. + type Lookup: StaticLookup; - /// Hash of the previous block. - ParentHash get(fn parent_hash) build(|_| hash69()): T::Hash; + /// The block header. + type Header: Parameter + traits::Header< + Number=Self::BlockNumber, + Hash=Self::Hash, + >; - /// Digest of the current block, also part of the block header. - Digest get(fn digest): DigestOf; + /// The aggregated event type of the runtime. + type Event: Parameter + Member + From> + Debug; - /// Events deposited for the current block. - Events get(fn events): Vec>; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + #[pallet::constant] + type BlockHashCount: Get; - /// The number of events in the `Events` list. - EventCount get(fn event_count): EventIndex; + /// The weight of runtime database operations the runtime can invoke. + #[pallet::constant] + type DbWeight: Get; - // TODO: https://github.com/paritytech/substrate/issues/2553 - // Possibly, we can improve it by using something like: - // `Option<(BlockNumber, Vec)>`, however in this case we won't be able to use - // `EventTopics::append`. + /// Get the chain's current version. + type Version: Get; - /// Mapping between a topic (represented by T::Hash) and a vector of indexes - /// of events in the `>` list. + /// Provides information about the pallet setup in the runtime. /// - /// All topic vectors have deterministic storage locations depending on the topic. This - /// allows light-clients to leverage the changes trie storage tracking mechanism and - /// in case of changes fetch the list of events of interest. + /// Expects the `PalletInfo` type that is being generated by `construct_runtime!` in the + /// runtime. /// - /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just - /// the `EventIndex` then in case if the topic has the same contents on the next block - /// no notification will be triggered thus the event might be lost. - EventTopics get(fn event_topics): map hasher(blake2_128_concat) T::Hash => Vec<(T::BlockNumber, EventIndex)>; - - /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. - pub LastRuntimeUpgrade build(|_| Some(LastRuntimeUpgradeInfo::from(T::Version::get()))): Option; + /// For tests it is okay to use `()` as type, however it will provide "useless" data. + type PalletInfo: PalletInfo; - /// True if we have upgraded so that `type RefCount` is `u32`. False (default) if not. - UpgradedToU32RefCount build(|_| true): bool; + /// Data to be associated with an account (other than nonce/transaction counter, which this + /// module does regardless). + type AccountData: Member + FullCodec + Clone + Default; - /// The execution phase of the block. - ExecutionPhase: Option; - } - add_extra_genesis { - config(changes_trie_config): Option; - #[serde(with = "sp_core::bytes")] - config(code): Vec; - - build(|config: &GenesisConfig| { - use codec::Encode; - - sp_io::storage::set(well_known_keys::CODE, &config.code); - sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); - - if let Some(ref changes_trie_config) = config.changes_trie_config { - sp_io::storage::set( - well_known_keys::CHANGES_TRIE_CONFIG, - &changes_trie_config.encode(), - ); - } - }); - } -} - -decl_event!( - /// Event for the System module. - pub enum Event where AccountId = ::AccountId { - /// An extrinsic completed successfully. \[info\] - ExtrinsicSuccess(DispatchInfo), - /// An extrinsic failed. \[error, info\] - ExtrinsicFailed(DispatchError, DispatchInfo), - /// `:code` was updated. - CodeUpdated, - /// A new \[account\] was created. - NewAccount(AccountId), - /// An \[account\] was reaped. - KilledAccount(AccountId), - } -); + /// Handler for when a new account has just been created. + type OnNewAccount: OnNewAccount; -decl_error! { - /// Error for the System module - pub enum Error for Module { - /// The name of specification does not match between the current runtime - /// and the new runtime. - InvalidSpecName, - /// The specification version is not allowed to decrease between the current runtime - /// and the new runtime. - SpecVersionNeedsToIncrease, - /// Failed to extract the runtime version from the new runtime. + /// A function that is invoked when an account has been determined to be dead. /// - /// Either calling `Core_version` or decoding `RuntimeVersion` failed. - FailedToExtractRuntimeVersion, - /// Suicide called when the account has non-default composite data. - NonDefaultComposite, - /// There is a non-zero reference count preventing the account from being purged. - NonZeroRefCount, - } -} - -/// Pallet struct placeholder on which is implemented the pallet logic. -/// -/// It is currently an alias for `Module` as old macros still generate/use old name. -pub type Pallet = Module; - -decl_module! { - pub struct Module for enum Call where origin: T::Origin, system=self { - type Error = Error; + /// All resources should be cleaned up associated with the given account. + type OnKilledAccount: OnKilledAccount; - /// The maximum number of blocks to allow in mortal eras. - const BlockHashCount: T::BlockNumber = T::BlockHashCount::get(); - - /// The weight of runtime database operations the runtime can invoke. - const DbWeight: RuntimeDbWeight = T::DbWeight::get(); - - /// The weight configuration (limits & base values) for each class of extrinsics and block. - const BlockWeights: limits::BlockWeights = T::BlockWeights::get(); + type SystemWeightInfo: WeightInfo; /// The designated SS85 prefix of this chain. /// /// This replaces the "ss58Format" property declared in the chain spec. Reason is /// that the runtime should know about the prefix in order to make use of it as /// an identifier of the chain. - const SS58Prefix: u8 = T::SS58Prefix::get(); + #[pallet::constant] + type SS58Prefix: Get; + } + + + #[pallet::pallet] + #[pallet::generate_store(pub (super) trait Store)] + pub struct Pallet(PhantomData); + #[pallet::hooks] + impl Hooks for Pallet { fn on_runtime_upgrade() -> frame_support::weights::Weight { if !UpgradedToU32RefCount::get() { Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| @@ -547,13 +230,17 @@ decl_module! { .validate() .expect("The weights are invalid."); } + } + #[pallet::call] + impl Pallet { /// A dispatch that will fill the block weight up to the given ratio. // TODO: This should only be available for testing, rather than in general usage, but // that's not possible at present (since it's within the decl_module macro). - #[weight = *_ratio * T::BlockWeights::get().max_block] - fn fill_block(origin, _ratio: Perbill) { + #[weight(*_ratio * T::BlockWeights::get().max_block)] + fn fill_block(origin: OriginFor, _ratio: Perbill) -> DispatchResultWithPostInfo { ensure_root(origin)?; + Ok(().into()) } /// Make some on-chain remark. @@ -563,9 +250,10 @@ decl_module! { /// - Base Weight: 0.665 µs, independent of remark length. /// - No DB operations. /// # - #[weight = T::SystemWeightInfo::remark(_remark.len() as u32)] - fn remark(origin, _remark: Vec) { + #[weight(T::SystemWeightInfo::remark(_remark.len() as u32))] + fn remark(origin: OriginFor, _remark: Vec) -> DispatchResultWithPostInfo { ensure_signed(origin)?; + Ok(().into()) } /// Set the number of pages in the WebAssembly environment's heap. @@ -576,10 +264,11 @@ decl_module! { /// - Base Weight: 1.405 µs /// - 1 write to HEAP_PAGES /// # - #[weight = (T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational)] - fn set_heap_pages(origin, pages: u64) { + #[weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))] + fn set_heap_pages(origin: OriginFor, pages: u64) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); + Ok(().into()) } /// Set the new runtime code. @@ -592,13 +281,14 @@ decl_module! { /// The weight of this function is dependent on the runtime, but generally this is very expensive. /// We will treat this as a full block. /// # - #[weight = (T::BlockWeights::get().max_block, DispatchClass::Operational)] - pub fn set_code(origin, code: Vec) { + #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] + pub fn set_code(origin: OriginFor, code: Vec) -> DispatchResultWithPostInfo { ensure_root(origin)?; Self::can_set_code(&code)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); Self::deposit_event(RawEvent::CodeUpdated); + Ok(().into()) } /// Set the new runtime code without doing any checks of the given `code`. @@ -609,11 +299,15 @@ decl_module! { /// - 1 event. /// The weight of this function is dependent on the runtime. We will treat this as a full block. /// # - #[weight = (T::BlockWeights::get().max_block, DispatchClass::Operational)] - pub fn set_code_without_checks(origin, code: Vec) { + #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] + pub fn set_code_without_checks( + origin: OriginFor, + code: Vec + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); Self::deposit_event(RawEvent::CodeUpdated); + Ok(().into()) } /// Set the new changes trie configuration. @@ -626,8 +320,11 @@ decl_module! { /// - DB Weight: /// - Writes: Changes Trie, System Digest /// # - #[weight = (T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational)] - pub fn set_changes_trie_config(origin, changes_trie_config: Option) { + #[weight((T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational))] + pub fn set_changes_trie_config( + origin: OriginFor, + changes_trie_config: Option + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; match changes_trie_config.clone() { Some(changes_trie_config) => storage::unhashed::put_raw( @@ -641,6 +338,7 @@ decl_module! { generic::ChangesTrieSignal::NewConfiguration(changes_trie_config), ); Self::deposit_log(log.into()); + Ok(().into()) } /// Set some items of storage. @@ -651,15 +349,16 @@ decl_module! { /// - Base Weight: 0.568 * i µs /// - Writes: Number of items /// # - #[weight = ( + #[weight(( T::SystemWeightInfo::set_storage(items.len() as u32), DispatchClass::Operational, - )] - fn set_storage(origin, items: Vec) { + ))] + fn set_storage(origin: OriginFor, items: Vec) -> DispatchResultWithPostInfo { ensure_root(origin)?; for i in &items { storage::unhashed::put_raw(&i.0, &i.1); } + Ok(().into()) } /// Kill some items from storage. @@ -670,15 +369,16 @@ decl_module! { /// - Base Weight: .378 * i µs /// - Writes: Number of items /// # - #[weight = ( + #[weight(( T::SystemWeightInfo::kill_storage(keys.len() as u32), DispatchClass::Operational, - )] - fn kill_storage(origin, keys: Vec) { + ))] + fn kill_storage(origin: OriginFor, keys: Vec) -> DispatchResultWithPostInfo { ensure_root(origin)?; for key in &keys { storage::unhashed::kill(&key); } + Ok(().into()) } /// Kill all storage items with a key that starts with the given prefix. @@ -692,13 +392,18 @@ decl_module! { /// - Base Weight: 0.834 * P µs /// - Writes: Number of subkeys + 1 /// # - #[weight = ( + #[weight(( T::SystemWeightInfo::kill_prefix(_subkeys.saturating_add(1)), DispatchClass::Operational, - )] - fn kill_prefix(origin, prefix: Key, _subkeys: u32) { + ))] + fn kill_prefix( + origin: OriginFor, + prefix: Key, + _subkeys: u32 + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::kill_prefix(&prefix); + Ok(().into()) } /// Kill the sending account, assuming there are no references outstanding and the composite @@ -711,666 +416,218 @@ decl_module! { /// Base Weight: 8.626 µs /// No DB Read or Write operations because caller is already in overlay /// # - #[weight = (T::SystemWeightInfo::suicide(), DispatchClass::Operational)] - pub fn suicide(origin) { + #[weight((T::SystemWeightInfo::suicide(), DispatchClass::Operational))] + pub fn suicide(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; let account = Account::::get(&who); ensure!(account.refcount == 0, Error::::NonZeroRefCount); ensure!(account.data == T::AccountData::default(), Error::::NonDefaultComposite); Self::kill_account(&who); + Ok(().into()) } } -} - -pub struct EnsureRoot(sp_std::marker::PhantomData); -impl< - O: Into, O>> + From>, - AccountId, -> EnsureOrigin for EnsureRoot { - type Success = (); - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - RawOrigin::Root => Ok(()), - r => Err(O::from(r)), - }) - } - - #[cfg(feature = "runtime-benchmarks")] - fn successful_origin() -> O { - O::from(RawOrigin::Root) - } -} - -pub struct EnsureSigned(sp_std::marker::PhantomData); -impl< - O: Into, O>> + From>, - AccountId: Default, -> EnsureOrigin for EnsureSigned { - type Success = AccountId; - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - RawOrigin::Signed(who) => Ok(who), - r => Err(O::from(r)), - }) - } - - #[cfg(feature = "runtime-benchmarks")] - fn successful_origin() -> O { - O::from(RawOrigin::Signed(Default::default())) - } -} - -pub struct EnsureSignedBy(sp_std::marker::PhantomData<(Who, AccountId)>); -impl< - O: Into, O>> + From>, - Who: Contains, - AccountId: PartialEq + Clone + Ord + Default, -> EnsureOrigin for EnsureSignedBy { - type Success = AccountId; - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - RawOrigin::Signed(ref who) if Who::contains(who) => Ok(who.clone()), - r => Err(O::from(r)), - }) - } - - #[cfg(feature = "runtime-benchmarks")] - fn successful_origin() -> O { - let members = Who::sorted_members(); - let first_member = match members.get(0) { - Some(account) => account.clone(), - None => Default::default(), - }; - O::from(RawOrigin::Signed(first_member.clone())) - } -} - -pub struct EnsureNone(sp_std::marker::PhantomData); -impl< - O: Into, O>> + From>, - AccountId, -> EnsureOrigin for EnsureNone { - type Success = (); - fn try_origin(o: O) -> Result { - o.into().and_then(|o| match o { - RawOrigin::None => Ok(()), - r => Err(O::from(r)), - }) - } - - #[cfg(feature = "runtime-benchmarks")] - fn successful_origin() -> O { - O::from(RawOrigin::None) - } -} - -pub struct EnsureNever(sp_std::marker::PhantomData); -impl EnsureOrigin for EnsureNever { - type Success = T; - fn try_origin(o: O) -> Result { - Err(o) - } - - #[cfg(feature = "runtime-benchmarks")] - fn successful_origin() -> O { - unimplemented!() - } -} - -/// The "OR gate" implementation of `EnsureOrigin`. -/// -/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first. -pub struct EnsureOneOf(sp_std::marker::PhantomData<(AccountId, L, R)>); -impl< - AccountId, - O: Into, O>> + From>, - L: EnsureOrigin, - R: EnsureOrigin, -> EnsureOrigin for EnsureOneOf { - type Success = Either; - fn try_origin(o: O) -> Result { - L::try_origin(o).map_or_else( - |o| R::try_origin(o).map(|o| Either::Right(o)), - |o| Ok(Either::Left(o)), - ) - } - - #[cfg(feature = "runtime-benchmarks")] - fn successful_origin() -> O { - L::successful_origin() - } -} - -/// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction). -/// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise. -pub fn ensure_signed(o: OuterOrigin) -> Result - where OuterOrigin: Into, OuterOrigin>> -{ - match o.into() { - Ok(RawOrigin::Signed(t)) => Ok(t), - _ => Err(BadOrigin), - } -} - -/// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise. -pub fn ensure_root(o: OuterOrigin) -> Result<(), BadOrigin> - where OuterOrigin: Into, OuterOrigin>> -{ - match o.into() { - Ok(RawOrigin::Root) => Ok(()), - _ => Err(BadOrigin), - } -} - -/// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise. -pub fn ensure_none(o: OuterOrigin) -> Result<(), BadOrigin> - where OuterOrigin: Into, OuterOrigin>> -{ - match o.into() { - Ok(RawOrigin::None) => Ok(()), - _ => Err(BadOrigin), - } -} - -/// A type of block initialization to perform. -pub enum InitKind { - /// Leave inspectable storage entries in state. - /// - /// i.e. `Events` are not being reset. - /// Should only be used for off-chain calls, - /// regular block execution should clear those. - Inspection, - - /// Reset also inspectable storage entries. - /// - /// This should be used for regular block execution. - Full, -} -impl Default for InitKind { - fn default() -> Self { - InitKind::Full - } -} - -/// Reference status; can be either referenced or unreferenced. -pub enum RefStatus { - Referenced, - Unreferenced, -} - -impl Module { - /// Deposits an event into this block's event record. - pub fn deposit_event(event: impl Into) { - Self::deposit_event_indexed(&[], event.into()); - } - - pub fn account_exists(who: &T::AccountId) -> bool { - Account::::contains_key(who) - } - - /// Increment the reference counter on an account. - pub fn inc_ref(who: &T::AccountId) { - Account::::mutate(who, |a| a.refcount = a.refcount.saturating_add(1)); - } - - /// Decrement the reference counter on an account. This *MUST* only be done once for every time - /// you called `inc_ref` on `who`. - pub fn dec_ref(who: &T::AccountId) { - Account::::mutate(who, |a| a.refcount = a.refcount.saturating_sub(1)); - } - - /// The number of outstanding references for the account `who`. - pub fn refs(who: &T::AccountId) -> RefCount { - Account::::get(who).refcount - } - - /// True if the account has no outstanding references. - pub fn allow_death(who: &T::AccountId) -> bool { - Account::::get(who).refcount == 0 + /// Event for the System module. + #[pallet::event] + pub enum Event { + /// An extrinsic completed successfully. \[info\] + ExtrinsicSuccess(DispatchInfo), + /// An extrinsic failed. \[error, info\] + ExtrinsicFailed(DispatchError, DispatchInfo), + /// `:code` was updated. + CodeUpdated, + /// A new \[account\] was created. + NewAccount(T::AccountId), + /// An \[account\] was reaped. + KilledAccount(T::AccountId), } - /// Deposits an event into this block's event record adding this event - /// to the corresponding topic indexes. - /// - /// This will update storage entries that correspond to the specified topics. - /// It is expected that light-clients could subscribe to this topics. - pub fn deposit_event_indexed(topics: &[T::Hash], event: T::Event) { - let block_number = Self::block_number(); - // Don't populate events on genesis. - if block_number.is_zero() { return } - - let phase = ExecutionPhase::get().unwrap_or_default(); - let event = EventRecord { - phase, - event, - topics: topics.iter().cloned().collect::>(), - }; - - // Index of the to be added event. - let event_idx = { - let old_event_count = EventCount::get(); - let new_event_count = match old_event_count.checked_add(1) { - // We've reached the maximum number of events at this block, just - // don't do anything and leave the event_count unaltered. - None => return, - Some(nc) => nc, - }; - EventCount::put(new_event_count); - old_event_count - }; - - Events::::append(&event); - - for topic in topics { - >::append(topic, &(block_number, event_idx)); - } - } + /// Old name generated by `decl_event`. + #[deprecated(note = "use `Event` instead")] + pub type RawEvent = Event; - /// Gets the index of extrinsic that is currently executing. - pub fn extrinsic_index() -> Option { - storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX) + /// Error for the System module + #[pallet::error] + pub enum Error { + /// The name of specification does not match between the current runtime + /// and the new runtime. + InvalidSpecName, + /// The specification version is not allowed to decrease between the current runtime + /// and the new runtime. + SpecVersionNeedsToIncrease, + /// Failed to extract the runtime version from the new runtime. + /// + /// Either calling `Core_version` or decoding `RuntimeVersion` failed. + FailedToExtractRuntimeVersion, + /// Suicide called when the account has non-default composite data. + NonDefaultComposite, + /// There is a non-zero reference count preventing the account from being purged. + NonZeroRefCount, } - /// Gets extrinsics count. - pub fn extrinsic_count() -> u32 { - ExtrinsicCount::get().unwrap_or_default() - } + /// Exposed trait-generic origin type. + #[pallet::origin] + pub type Origin = RawOrigin<::AccountId>; - pub fn all_extrinsics_len() -> u32 { - AllExtrinsicsLen::get().unwrap_or_default() - } + /// The full account information for a particular account ID. + #[pallet::storage] + #[pallet::getter(fn account)] + pub type Account = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + AccountInfo, + ValueQuery, + >; - /// Inform the system module of some additional weight that should be accounted for, in the - /// current block. - /// - /// NOTE: use with extra care; this function is made public only be used for certain modules - /// that need it. A runtime that does not have dynamic calls should never need this and should - /// stick to static weights. A typical use case for this is inner calls or smart contract calls. - /// Furthermore, it only makes sense to use this when it is presumably _cheap_ to provide the - /// argument `weight`; In other words, if this function is to be used to account for some - /// unknown, user provided call's weight, it would only make sense to use it if you are sure you - /// can rapidly compute the weight of the inner call. + /// Total extrinsics count for the current block. + #[pallet::storage] + pub(super) type ExtrinsicCount = StorageValue<_, u32>; + + /// The current weight for the block. + #[pallet::storage] + #[pallet::getter(fn block_weight)] + pub(super) type BlockWeight = StorageValue<_, ConsumedWeight, ValueQuery>; + + /// Total length (in bytes) for all extrinsics put together, for the current block. + #[pallet::storage] + pub(super) type AllExtrinsicsLen = StorageValue<_, u32>; + + /// Map of block numbers to block hashes. + #[pallet::storage] + #[pallet::getter(fn block_hash)] + pub type BlockHash = + StorageMap<_, Twox64Concat, T::BlockNumber, T::Hash, ValueQuery>; + + /// Extrinsics data for the current block (maps an extrinsic's index to its data). + #[pallet::storage] + #[pallet::getter(fn extrinsic_data)] + pub(super) type ExtrinsicData = + StorageMap<_, Twox64Concat, u32, Vec, ValueQuery>; + + /// The current block number being processed. Set by `execute_block`. + #[pallet::storage] + #[pallet::getter(fn block_number)] + pub(super) type Number = StorageValue<_, T::BlockNumber, ValueQuery>; + + /// Hash of the previous block. + #[pallet::storage] + #[pallet::getter(fn parent_hash)] + pub(super) type ParentHash = StorageValue<_, T::Hash, ValueQuery>; + + /// Digest of the current block, also part of the block header. + #[pallet::storage] + #[pallet::getter(fn digest)] + pub(super) type Digest = StorageValue<_, DigestOf, ValueQuery>; + + /// Events deposited for the current block. + #[pallet::storage] + #[pallet::getter(fn events)] + pub(super) type Events = + StorageValue<_, Vec>, ValueQuery>; + + /// The number of events in the `Events` list. + #[pallet::storage] + #[pallet::getter(fn event_count)] + pub(super) type EventCount = StorageValue<_, EventIndex, ValueQuery>; + + /// Mapping between a topic (represented by T::Hash) and a vector of indexes + /// of events in the `>` list. /// - /// Even more dangerous is to note that this function does NOT take any action, if the new sum - /// of block weight is more than the block weight limit. This is what the _unchecked_. + /// All topic vectors have deterministic storage locations depending on the topic. This + /// allows light-clients to leverage the changes trie storage tracking mechanism and + /// in case of changes fetch the list of events of interest. /// - /// Another potential use-case could be for the `on_initialize` and `on_finalize` hooks. - pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) { - BlockWeight::mutate(|current_weight| { - current_weight.add(weight, class); - }); - } - - /// Start the execution of a particular block. - pub fn initialize( - number: &T::BlockNumber, - parent_hash: &T::Hash, - digest: &DigestOf, - kind: InitKind, - ) { - // populate environment - ExecutionPhase::put(Phase::Initialization); - storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32); - >::put(number); - >::put(digest); - >::put(parent_hash); - >::insert(*number - One::one(), parent_hash); - - // Remove previous block data from storage - BlockWeight::kill(); - - // Kill inspectable storage entries in state when `InitKind::Full`. - if let InitKind::Full = kind { - >::kill(); - EventCount::kill(); - >::remove_all(); - } + /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just + /// the `EventIndex` then in case if the topic has the same contents on the next block + /// no notification will be triggered thus the event might be lost. + #[pallet::storage] + #[pallet::getter(fn event_topics)] + pub(super) type EventTopics = + StorageMap<_, Blake2_128Concat, T::Hash, Vec<(T::BlockNumber, EventIndex)>, ValueQuery>; + + /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. + #[pallet::storage] + pub type LastRuntimeUpgrade = StorageValue<_, LastRuntimeUpgradeInfo>; + + /// True if we have upgraded so that `type RefCount` is `u32`. False (default) if not. + #[pallet::storage] + pub(super) type UpgradedToU32RefCount = StorageValue<_, bool, ValueQuery>; + + /// The execution phase of the block. + #[pallet::storage] + pub(super) type ExecutionPhase = StorageValue<_, Phase>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub changes_trie_config: Option, + #[serde(with = "sp_core::bytes")] + pub code: Vec, } - /// Remove temporary "environment" entries in storage, compute the storage root and return the - /// resulting header for this block. - pub fn finalize() -> T::Header { - ExecutionPhase::kill(); - AllExtrinsicsLen::kill(); - - // The following fields - // - // - > - // - > - // - > - // - > - // - > - // - > - // - // stay to be inspected by the client and will be cleared by `Self::initialize`. - let number = >::get(); - let parent_hash = >::get(); - let mut digest = >::get(); - - let extrinsics = (0..ExtrinsicCount::take().unwrap_or_default()) - .map(ExtrinsicData::take) - .collect(); - let extrinsics_root = extrinsics_data_root::(extrinsics); - - // move block hash pruning window by one block - let block_hash_count = T::BlockHashCount::get(); - let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one()); - - // keep genesis hash - if !to_remove.is_zero() { - >::remove(to_remove); - } - - let storage_root = T::Hash::decode(&mut &sp_io::storage::root()[..]) - .expect("Node is configured to use the same hash; qed"); - let storage_changes_root = sp_io::storage::changes_root(&parent_hash.encode()); - - // we can't compute changes trie root earlier && put it to the Digest - // because it will include all currently existing temporaries. - if let Some(storage_changes_root) = storage_changes_root { - let item = generic::DigestItem::ChangesTrieRoot( - T::Hash::decode(&mut &storage_changes_root[..]) - .expect("Node is configured to use the same hash; qed") - ); - digest.push(item); + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + Self { + changes_trie_config: Default::default(), + code: Default::default(), + } } - - ::new(number, extrinsics_root, storage_root, parent_hash, digest) - } - - /// Deposits a log and ensures it matches the block's log data. - /// - /// # - /// - `O(1)` - /// - 1 storage write (codec `O(1)`) - /// # - pub fn deposit_log(item: DigestItemOf) { - >::append(item); - } - - /// Get the basic externalities for this module, useful for tests. - #[cfg(any(feature = "std", test))] - pub fn externalities() -> TestExternalities { - TestExternalities::new(sp_core::storage::Storage { - top: map![ - >::hashed_key_for(T::BlockNumber::zero()) => [69u8; 32].encode(), - >::hashed_key().to_vec() => T::BlockNumber::one().encode(), - >::hashed_key().to_vec() => [69u8; 32].encode() - ], - children_default: map![], - }) - } - - /// Set the block number to something in particular. Can be used as an alternative to - /// `initialize` for tests that don't need to bother with the other environment entries. - #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] - pub fn set_block_number(n: T::BlockNumber) { - >::put(n); - } - - /// Sets the index of extrinsic that is currently executing. - #[cfg(any(feature = "std", test))] - pub fn set_extrinsic_index(extrinsic_index: u32) { - storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &extrinsic_index) - } - - /// Set the parent hash number to something in particular. Can be used as an alternative to - /// `initialize` for tests that don't need to bother with the other environment entries. - #[cfg(any(feature = "std", test))] - pub fn set_parent_hash(n: T::Hash) { - >::put(n); - } - - /// Set the current block weight. This should only be used in some integration tests. - #[cfg(any(feature = "std", test))] - pub fn set_block_consumed_resources(weight: Weight, len: usize) { - BlockWeight::mutate(|current_weight| { - current_weight.set(weight, DispatchClass::Normal) - }); - AllExtrinsicsLen::put(len as u32); - } - - /// Reset events. Can be used as an alternative to - /// `initialize` for tests that don't need to bother with the other environment entries. - #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] - pub fn reset_events() { - >::kill(); - EventCount::kill(); - >::remove_all(); } - /// Return the chain's current runtime version. - pub fn runtime_version() -> RuntimeVersion { T::Version::get() } - - /// Retrieve the account transaction counter from storage. - pub fn account_nonce(who: impl EncodeLike) -> T::Index { - Account::::get(who).nonce - } - - /// Increment a particular account's nonce by 1. - pub fn inc_account_nonce(who: impl EncodeLike) { - Account::::mutate(who, |a| a.nonce += T::Index::one()); - } - - /// Note what the extrinsic data of the current extrinsic index is. - /// - /// This is required to be called before applying an extrinsic. The data will used - /// in [`Self::finalize`] to calculate the correct extrinsics root. - pub fn note_extrinsic(encoded_xt: Vec) { - ExtrinsicData::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt); - } - - /// To be called immediately after an extrinsic has been applied. - pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, mut info: DispatchInfo) { - info.weight = extract_actual_weight(r, &info); - Self::deposit_event( - match r { - Ok(_) => RawEvent::ExtrinsicSuccess(info), - Err(err) => { - sp_runtime::print(err); - RawEvent::ExtrinsicFailed(err.error, info) - }, + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + { + let builder: fn(&Self) -> _ = |_| vec![(T::BlockNumber::zero(), hash69())]; + let data = &builder(self); + let data: &frame_support::sp_std::vec::Vec<(T::BlockNumber, T::Hash)> = data; + data.iter().for_each(|(k, v)| { + as frame_support::storage::StorageMap + >::insert::<&T:: + BlockNumber, &T::Hash>(k, v); + }); } - ); - - let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; - - storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index); - ExecutionPhase::put(Phase::ApplyExtrinsic(next_extrinsic_index)); - } - - /// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block - /// has been called. - pub fn note_finished_extrinsics() { - let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX) - .unwrap_or_default(); - ExtrinsicCount::put(extrinsic_index); - ExecutionPhase::put(Phase::Finalization); - } - - /// To be called immediately after finishing the initialization of the block - /// (e.g., called `on_initialize` for all modules). - pub fn note_finished_initialize() { - ExecutionPhase::put(Phase::ApplyExtrinsic(0)) - } - - /// An account is being created. - pub fn on_created_account(who: T::AccountId) { - T::OnNewAccount::on_new_account(&who); - Self::deposit_event(RawEvent::NewAccount(who)); - } - - /// Do anything that needs to be done after an account has been killed. - fn on_killed_account(who: T::AccountId) { - T::OnKilledAccount::on_killed_account(&who); - Self::deposit_event(RawEvent::KilledAccount(who)); - } - - /// Remove an account from storage. This should only be done when its refs are zero or you'll - /// get storage leaks in other modules. Nonetheless we assume that the calling logic knows best. - /// - /// This is a no-op if the account doesn't already exist. If it does then it will ensure - /// cleanups (those in `on_killed_account`) take place. - fn kill_account(who: &T::AccountId) { - if Account::::contains_key(who) { - let account = Account::::take(who); - if account.refcount > 0 { - debug::debug!( - target: "system", - "WARNING: Referenced account deleted. This is probably a bug." + { + let builder: fn(&Self) -> _ = |_| hash69(); + let data = &builder(self); + let v: &T::Hash = data; + as frame_support::storage::StorageValue>::put::<&T::Hash>( + v, ); } - } - Module::::on_killed_account(who.clone()); - } - - /// Determine whether or not it is possible to update the code. - /// - /// Checks the given code if it is a valid runtime wasm blob by instantianting - /// it and extracting the runtime version of it. It checks that the runtime version - /// of the old and new runtime has the same spec name and that the spec version is increasing. - pub fn can_set_code(code: &[u8]) -> Result<(), sp_runtime::DispatchError> { - let current_version = T::Version::get(); - let new_version = sp_io::misc::runtime_version(&code) - .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) - .ok_or_else(|| Error::::FailedToExtractRuntimeVersion)?; - - if new_version.spec_name != current_version.spec_name { - Err(Error::::InvalidSpecName)? - } - - if new_version.spec_version <= current_version.spec_version { - Err(Error::::SpecVersionNeedsToIncrease)? - } - - Ok(()) - } -} - -/// Event handler which calls on_created_account when it happens. -pub struct CallOnCreatedAccount(PhantomData); -impl Happened for CallOnCreatedAccount { - fn happened(who: &T::AccountId) { - Module::::on_created_account(who.clone()); - } -} - -/// Event handler which calls kill_account when it happens. -pub struct CallKillAccount(PhantomData); -impl Happened for CallKillAccount { - fn happened(who: &T::AccountId) { - Module::::kill_account(who) - } -} - -impl BlockNumberProvider for Module -{ - type BlockNumber = ::BlockNumber; - - fn current_block_number() -> Self::BlockNumber { - Module::::block_number() - } -} - -// Implement StoredMap for a simple single-item, kill-account-on-remove system. This works fine for -// storing a single item which is required to not be empty/default for the account to exist. -// Anything more complex will need more sophisticated logic. -impl StoredMap for Module { - fn get(k: &T::AccountId) -> T::AccountData { - Account::::get(k).data - } - fn is_explicit(k: &T::AccountId) -> bool { - Account::::contains_key(k) - } - fn insert(k: &T::AccountId, data: T::AccountData) { - let existed = Account::::contains_key(k); - Account::::mutate(k, |a| a.data = data); - if !existed { - Self::on_created_account(k.clone()); - } - } - fn remove(k: &T::AccountId) { - Self::kill_account(k) - } - fn mutate(k: &T::AccountId, f: impl FnOnce(&mut T::AccountData) -> R) -> R { - let existed = Account::::contains_key(k); - let r = Account::::mutate(k, |a| f(&mut a.data)); - if !existed { - Self::on_created_account(k.clone()); - } - r - } - fn mutate_exists(k: &T::AccountId, f: impl FnOnce(&mut Option) -> R) -> R { - Self::try_mutate_exists(k, |x| -> Result { Ok(f(x)) }).expect("Infallible; qed") - } - fn try_mutate_exists(k: &T::AccountId, f: impl FnOnce(&mut Option) -> Result) -> Result { - Account::::try_mutate_exists(k, |maybe_value| { - let existed = maybe_value.is_some(); - let (maybe_prefix, mut maybe_data) = split_inner( - maybe_value.take(), - |account| ((account.nonce, account.refcount), account.data) - ); - f(&mut maybe_data).map(|result| { - *maybe_value = maybe_data.map(|data| { - let (nonce, refcount) = maybe_prefix.unwrap_or_default(); - AccountInfo { nonce, refcount, data } - }); - (existed, maybe_value.is_some(), result) - }) - }).map(|(existed, exists, v)| { - if !existed && exists { - Self::on_created_account(k.clone()); - } else if existed && !exists { - Self::on_killed_account(k.clone()); + { + let builder: fn(&Self) -> _ = + |_| Some(LastRuntimeUpgradeInfo::from(T::Version::get())); + let data = builder(self); + let data = Option::as_ref(&data); + let v: Option<&LastRuntimeUpgradeInfo> = data; + if let Some(v) = v { + >::put::<&LastRuntimeUpgradeInfo>(v); + } } - v - }) - } -} - -/// Split an `option` into two constituent options, as defined by a `splitter` function. -pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S)) - -> (Option, Option) -{ - match option { - Some(inner) => { - let (r, s) = splitter(inner); - (Some(r), Some(s)) + { + let builder: fn(&Self) -> _ = |_| true; + let data = &builder(self); + let v: &bool = data; + >::put::<&bool>( + v, + ); + } + let extra_genesis_builder: fn(&Self) = |config: &GenesisConfig| { + use codec::Encode; + sp_io::storage::set(well_known_keys::CODE, &config.code); + sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); + if let Some(ref changes_trie_config) = config.changes_trie_config { + sp_io::storage::set( + well_known_keys::CHANGES_TRIE_CONFIG, + &changes_trie_config.encode(), + ); + } + }; + extra_genesis_builder(self); } - None => (None, None), - } -} - -impl IsDeadAccount for Module { - fn is_dead_account(who: &T::AccountId) -> bool { - !Account::::contains_key(who) - } -} - -pub struct ChainContext(sp_std::marker::PhantomData); -impl Default for ChainContext { - fn default() -> Self { - ChainContext(sp_std::marker::PhantomData) - } -} - -impl Lookup for ChainContext { - type Source = ::Source; - type Target = ::Target; - - fn lookup(&self, s: Self::Source) -> Result { - ::lookup(s) } } - -/// Prelude to be used alongside pallet macro, for ease of use. -pub mod pallet_prelude { - pub use crate::{ensure_signed, ensure_none, ensure_root}; - - /// Type alias for the `Origin` associated type of system config. - pub type OriginFor = ::Origin; - - /// Type alias for the `BlockNumber` associated type of system config. - pub type BlockNumberFor = ::BlockNumber; -} diff --git a/frame/system/src/lib2.rs b/frame/system/src/lib2.rs deleted file mode 100644 index c84ee4ff6bb0b..0000000000000 --- a/frame/system/src/lib2.rs +++ /dev/null @@ -1,633 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! TODO module docs - -#![cfg_attr(not(feature = "std"), no_std)] - -#[cfg(feature = "std")] -use serde::Serialize; -use sp_std::prelude::*; -#[cfg(any(feature = "std", test))] -use sp_std::map; -use sp_std::convert::Infallible; -use sp_std::marker::PhantomData; -use sp_std::fmt::Debug; -use sp_version::RuntimeVersion; -use sp_runtime::{ - RuntimeDebug, Perbill, DispatchError, Either, generic, - traits::{ - self, CheckEqual, AtLeast32Bit, Zero, Lookup, LookupError, - SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, - MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, - Dispatchable, AtLeast32BitUnsigned, Saturating, - }, - offchain::storage_lock::BlockNumberProvider, -}; - -use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; -use frame_support::{ - decl_module, decl_event, decl_storage, decl_error, Parameter, ensure, debug, - storage, - traits::{ - Contains, Get, PalletInfo, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, - StoredMap, EnsureOrigin, OriginTrait, Filter, - }, - weights::{ - Weight, RuntimeDbWeight, DispatchInfo, DispatchClass, - extract_actual_weight, PerDispatchClass, - }, - dispatch::DispatchResultWithPostInfo, -}; -use codec::{Encode, Decode, FullCodec, EncodeLike}; - -#[cfg(any(feature = "std", test))] -use sp_io::TestExternalities; - -pub mod offchain; -pub mod limits; -#[cfg(test)] -pub(crate) mod mock; - -mod extensions; -pub mod weights; -#[cfg(test)] -mod tests; - - -pub use extensions::{ - check_mortality::CheckMortality, check_genesis::CheckGenesis, check_nonce::CheckNonce, - check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion, - check_weight::CheckWeight, -}; -// Backward compatible re-export. -pub use extensions::check_mortality::CheckMortality as CheckEra; -pub use weights::WeightInfo; - -/// Compute the trie root of a list of extrinsics. -pub fn extrinsics_root(extrinsics: &[E]) -> H::Output { - extrinsics_data_root::(extrinsics.iter().map(codec::Encode::encode).collect()) -} - -/// Compute the trie root of a list of extrinsics. -pub fn extrinsics_data_root(xts: Vec>) -> H::Output { - H::ordered_trie_root(xts) -} - -/// An object to track the currently used extrinsic weight in a block. -pub type ConsumedWeight = PerDispatchClass; - -pub use pallet::*; - -#[frame_support::pallet] -pub mod pallet { - use super::*; - use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; - - #[pallet::config] - /// System configuration trait. Implemented by runtime. - pub trait Config: 'static + Eq + Clone { - /// The basic call filter to use in Origin. All origins are built with this filter as base, - /// except Root. - type BaseCallFilter: Filter; - - /// Block & extrinsics weights: base values and limits. - #[pallet::constant] - type BlockWeights: Get; - - /// The maximum length of a block (in bytes). - type BlockLength: Get; - - /// The `Origin` type used by dispatchable calls. - type Origin: - Into, Self::Origin>> - + From> - + Clone - + OriginTrait; - - /// The aggregated `Call` type. - type Call: Dispatchable + Debug; - - /// Account index (aka nonce) type. This stores the number of previous transactions associated - /// with a sender account. - type Index: - Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit - + Copy; - - /// The block number type used by the runtime. - type BlockNumber: - Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + - AtLeast32BitUnsigned + Default + Bounded + Copy + sp_std::hash::Hash + - sp_std::str::FromStr + MaybeMallocSizeOf; - - /// The output of the `Hashing` function. - type Hash: - Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + Ord - + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + MaybeMallocSizeOf; - - /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). - type Hashing: Hash; - - /// The user account identifier type for the runtime. - type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord - + Default; - - /// Converting trait to take a source type and convert to `AccountId`. - /// - /// Used to define the type and conversion mechanism for referencing accounts in transactions. - /// It's perfectly reasonable for this to be an identity conversion (with the source type being - /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient - /// alternatives. - type Lookup: StaticLookup; - - /// The block header. - type Header: Parameter + traits::Header< - Number=Self::BlockNumber, - Hash=Self::Hash, - >; - - /// The aggregated event type of the runtime. - type Event: Parameter + Member + From> + Debug; - - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - #[pallet::constant] - type BlockHashCount: Get; - - /// The weight of runtime database operations the runtime can invoke. - #[pallet::constant] - type DbWeight: Get; - - /// Get the chain's current version. - type Version: Get; - - /// Provides information about the pallet setup in the runtime. - /// - /// Expects the `PalletInfo` type that is being generated by `construct_runtime!` in the - /// runtime. - /// - /// For tests it is okay to use `()` as type, however it will provide "useless" data. - type PalletInfo: PalletInfo; - - /// Data to be associated with an account (other than nonce/transaction counter, which this - /// module does regardless). - type AccountData: Member + FullCodec + Clone + Default; - - /// Handler for when a new account has just been created. - type OnNewAccount: OnNewAccount; - - /// A function that is invoked when an account has been determined to be dead. - /// - /// All resources should be cleaned up associated with the given account. - type OnKilledAccount: OnKilledAccount; - - type SystemWeightInfo: WeightInfo; - - /// The designated SS85 prefix of this chain. - /// - /// This replaces the "ss58Format" property declared in the chain spec. Reason is - /// that the runtime should know about the prefix in order to make use of it as - /// an identifier of the chain. - #[pallet::constant] - type SS58Prefix: Get; - } - - - #[pallet::pallet] - #[pallet::generate_store(pub (super) trait Store)] - pub struct Pallet(PhantomData); - - #[pallet::hooks] - impl Hooks for Pallet { - fn on_runtime_upgrade() -> frame_support::weights::Weight { - if !UpgradedToU32RefCount::get() { - Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| - Some(AccountInfo { nonce, refcount: rc as RefCount, data }) - ); - UpgradedToU32RefCount::put(true); - T::BlockWeights::get().max_block - } else { - 0 - } - } - - fn integrity_test() { - T::BlockWeights::get() - .validate() - .expect("The weights are invalid."); - } - } - - #[pallet::call] - impl Pallet { - /// A dispatch that will fill the block weight up to the given ratio. - // TODO: This should only be available for testing, rather than in general usage, but - // that's not possible at present (since it's within the decl_module macro). - #[weight(*_ratio * T::BlockWeights::get().max_block)] - fn fill_block(origin: OriginFor, _ratio: Perbill) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - Ok(().into()) - } - - /// Make some on-chain remark. - /// - /// # - /// - `O(1)` - /// - Base Weight: 0.665 µs, independent of remark length. - /// - No DB operations. - /// # - #[weight(T::SystemWeightInfo::remark(_remark.len() as u32))] - fn remark(origin: OriginFor, _remark: Vec) -> DispatchResultWithPostInfo { - ensure_signed(origin)?; - Ok(().into()) - } - - /// Set the number of pages in the WebAssembly environment's heap. - /// - /// # - /// - `O(1)` - /// - 1 storage write. - /// - Base Weight: 1.405 µs - /// - 1 write to HEAP_PAGES - /// # - #[weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))] - fn set_heap_pages(origin: OriginFor, pages: u64) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); - Ok(().into()) - } - - /// Set the new runtime code. - /// - /// # - /// - `O(C + S)` where `C` length of `code` and `S` complexity of `can_set_code` - /// - 1 storage write (codec `O(C)`). - /// - 1 call to `can_set_code`: `O(S)` (calls `sp_io::misc::runtime_version` which is expensive). - /// - 1 event. - /// The weight of this function is dependent on the runtime, but generally this is very expensive. - /// We will treat this as a full block. - /// # - #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] - pub fn set_code(origin: OriginFor, code: Vec) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - Self::can_set_code(&code)?; - - storage::unhashed::put_raw(well_known_keys::CODE, &code); - Self::deposit_event(RawEvent::CodeUpdated); - Ok(().into()) - } - - /// Set the new runtime code without doing any checks of the given `code`. - /// - /// # - /// - `O(C)` where `C` length of `code` - /// - 1 storage write (codec `O(C)`). - /// - 1 event. - /// The weight of this function is dependent on the runtime. We will treat this as a full block. - /// # - #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] - pub fn set_code_without_checks( - origin: OriginFor, - code: Vec - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - storage::unhashed::put_raw(well_known_keys::CODE, &code); - Self::deposit_event(RawEvent::CodeUpdated); - Ok(().into()) - } - - /// Set the new changes trie configuration. - /// - /// # - /// - `O(1)` - /// - 1 storage write or delete (codec `O(1)`). - /// - 1 call to `deposit_log`: Uses `append` API, so O(1) - /// - Base Weight: 7.218 µs - /// - DB Weight: - /// - Writes: Changes Trie, System Digest - /// # - #[weight((T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational))] - pub fn set_changes_trie_config( - origin: OriginFor, - changes_trie_config: Option - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - match changes_trie_config.clone() { - Some(changes_trie_config) => storage::unhashed::put_raw( - well_known_keys::CHANGES_TRIE_CONFIG, - &changes_trie_config.encode(), - ), - None => storage::unhashed::kill(well_known_keys::CHANGES_TRIE_CONFIG), - } - - let log = generic::DigestItem::ChangesTrieSignal( - generic::ChangesTrieSignal::NewConfiguration(changes_trie_config), - ); - Self::deposit_log(log.into()); - Ok(().into()) - } - - /// Set some items of storage. - /// - /// # - /// - `O(I)` where `I` length of `items` - /// - `I` storage writes (`O(1)`). - /// - Base Weight: 0.568 * i µs - /// - Writes: Number of items - /// # - #[weight(( - T::SystemWeightInfo::set_storage(items.len() as u32), - DispatchClass::Operational, - ))] - fn set_storage(origin: OriginFor, items: Vec) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - for i in &items { - storage::unhashed::put_raw(&i.0, &i.1); - } - Ok(().into()) - } - - /// Kill some items from storage. - /// - /// # - /// - `O(IK)` where `I` length of `keys` and `K` length of one key - /// - `I` storage deletions. - /// - Base Weight: .378 * i µs - /// - Writes: Number of items - /// # - #[weight(( - T::SystemWeightInfo::kill_storage(keys.len() as u32), - DispatchClass::Operational, - ))] - fn kill_storage(origin: OriginFor, keys: Vec) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - for key in &keys { - storage::unhashed::kill(&key); - } - Ok(().into()) - } - - /// Kill all storage items with a key that starts with the given prefix. - /// - /// **NOTE:** We rely on the Root origin to provide us the number of subkeys under - /// the prefix we are removing to accurately calculate the weight of this function. - /// - /// # - /// - `O(P)` where `P` amount of keys with prefix `prefix` - /// - `P` storage deletions. - /// - Base Weight: 0.834 * P µs - /// - Writes: Number of subkeys + 1 - /// # - #[weight(( - T::SystemWeightInfo::kill_prefix(_subkeys.saturating_add(1)), - DispatchClass::Operational, - ))] - fn kill_prefix( - origin: OriginFor, - prefix: Key, - _subkeys: u32 - ) -> DispatchResultWithPostInfo { - ensure_root(origin)?; - storage::unhashed::kill_prefix(&prefix); - Ok(().into()) - } - - /// Kill the sending account, assuming there are no references outstanding and the composite - /// data is equal to its default value. - /// - /// # - /// - `O(1)` - /// - 1 storage read and deletion. - /// -------------------- - /// Base Weight: 8.626 µs - /// No DB Read or Write operations because caller is already in overlay - /// # - #[weight((T::SystemWeightInfo::suicide(), DispatchClass::Operational))] - pub fn suicide(origin: OriginFor) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; - let account = Account::::get(&who); - ensure!(account.refcount == 0, Error::::NonZeroRefCount); - ensure!(account.data == T::AccountData::default(), Error::::NonDefaultComposite); - Self::kill_account(&who); - Ok(().into()) - } - } - - /// Event for the System module. - #[pallet::event] - pub enum Event { - /// An extrinsic completed successfully. \[info\] - ExtrinsicSuccess(DispatchInfo), - /// An extrinsic failed. \[error, info\] - ExtrinsicFailed(DispatchError, DispatchInfo), - /// `:code` was updated. - CodeUpdated, - /// A new \[account\] was created. - NewAccount(T::AccountId), - /// An \[account\] was reaped. - KilledAccount(T::AccountId), - } - - /// Old name generated by `decl_event`. - #[deprecated(note = "use `Event` instead")] - pub type RawEvent = Event; - - /// Error for the System module - #[pallet::error] - pub enum Error { - /// The name of specification does not match between the current runtime - /// and the new runtime. - InvalidSpecName, - /// The specification version is not allowed to decrease between the current runtime - /// and the new runtime. - SpecVersionNeedsToIncrease, - /// Failed to extract the runtime version from the new runtime. - /// - /// Either calling `Core_version` or decoding `RuntimeVersion` failed. - FailedToExtractRuntimeVersion, - /// Suicide called when the account has non-default composite data. - NonDefaultComposite, - /// There is a non-zero reference count preventing the account from being purged. - NonZeroRefCount, - } - - /// Exposed trait-generic origin type. - #[pallet::origin] - pub type Origin = RawOrigin<::AccountId>; - - /// The full account information for a particular account ID. - #[pallet::storage] - #[pallet::getter(fn account)] - pub type Account = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - AccountInfo, - ValueQuery, - >; - - /// Total extrinsics count for the current block. - #[pallet::storage] - pub(super) type ExtrinsicCount = StorageValue<_, u32>; - - /// The current weight for the block. - #[pallet::storage] - #[pallet::getter(fn block_weight)] - pub(super) type BlockWeight = StorageValue<_, ConsumedWeight, ValueQuery>; - - /// Total length (in bytes) for all extrinsics put together, for the current block. - #[pallet::storage] - pub(super) type AllExtrinsicsLen = StorageValue<_, u32>; - - /// Map of block numbers to block hashes. - #[pallet::storage] - #[pallet::getter(fn block_hash)] - pub type BlockHash = - StorageMap<_, Twox64Concat, T::BlockNumber, T::Hash, ValueQuery>; - - /// Extrinsics data for the current block (maps an extrinsic's index to its data). - #[pallet::storage] - #[pallet::getter(fn extrinsic_data)] - pub(super) type ExtrinsicData = - StorageMap<_, Twox64Concat, u32, Vec, ValueQuery>; - - /// The current block number being processed. Set by `execute_block`. - #[pallet::storage] - #[pallet::getter(fn block_number)] - pub(super) type Number = StorageValue<_, T::BlockNumber, ValueQuery>; - - /// Hash of the previous block. - #[pallet::storage] - #[pallet::getter(fn parent_hash)] - pub(super) type ParentHash = StorageValue<_, T::Hash, ValueQuery>; - - /// Digest of the current block, also part of the block header. - #[pallet::storage] - #[pallet::getter(fn digest)] - pub(super) type Digest = StorageValue<_, DigestOf, ValueQuery>; - - /// Events deposited for the current block. - #[pallet::storage] - #[pallet::getter(fn events)] - pub(super) type Events = - StorageValue<_, Vec>, ValueQuery>; - - /// The number of events in the `Events` list. - #[pallet::storage] - #[pallet::getter(fn event_count)] - pub(super) type EventCount = StorageValue<_, EventIndex, ValueQuery>; - - /// Mapping between a topic (represented by T::Hash) and a vector of indexes - /// of events in the `>` list. - /// - /// All topic vectors have deterministic storage locations depending on the topic. This - /// allows light-clients to leverage the changes trie storage tracking mechanism and - /// in case of changes fetch the list of events of interest. - /// - /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just - /// the `EventIndex` then in case if the topic has the same contents on the next block - /// no notification will be triggered thus the event might be lost. - #[pallet::storage] - #[pallet::getter(fn event_topics)] - pub(super) type EventTopics = - StorageMap<_, Blake2_128Concat, T::Hash, Vec<(T::BlockNumber, EventIndex)>, ValueQuery>; - - /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. - #[pallet::storage] - pub type LastRuntimeUpgrade = StorageValue<_, LastRuntimeUpgradeInfo>; - - /// True if we have upgraded so that `type RefCount` is `u32`. False (default) if not. - #[pallet::storage] - pub(super) type UpgradedToU32RefCount = StorageValue<_, bool, ValueQuery>; - - /// The execution phase of the block. - #[pallet::storage] - pub(super) type ExecutionPhase = StorageValue<_, Phase>; - - #[pallet::genesis_config] - pub struct GenesisConfig { - pub changes_trie_config: Option, - #[serde(with = "sp_core::bytes")] - pub code: Vec, - } - - #[cfg(feature = "std")] - impl Default for GenesisConfig { - fn default() -> Self { - Self { - changes_trie_config: Default::default(), - code: Default::default(), - } - } - } - - #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { - fn build(&self) { - { - let builder: fn(&Self) -> _ = |_| vec![(T::BlockNumber::zero(), hash69())]; - let data = &builder(self); - let data: &frame_support::sp_std::vec::Vec<(T::BlockNumber, T::Hash)> = data; - data.iter().for_each(|(k, v)| { - as frame_support::storage::StorageMap - >::insert::<&T:: - BlockNumber, &T::Hash>(k, v); - }); - } - { - let builder: fn(&Self) -> _ = |_| hash69(); - let data = &builder(self); - let v: &T::Hash = data; - as frame_support::storage::StorageValue>::put::<&T::Hash>( - v, - ); - } - { - let builder: fn(&Self) -> _ = - |_| Some(LastRuntimeUpgradeInfo::from(T::Version::get())); - let data = builder(self); - let data = Option::as_ref(&data); - let v: Option<&LastRuntimeUpgradeInfo> = data; - if let Some(v) = v { - >::put::<&LastRuntimeUpgradeInfo>(v); - } - } - { - let builder: fn(&Self) -> _ = |_| true; - let data = &builder(self); - let v: &bool = data; - >::put::<&bool>( - v, - ); - } - let extra_genesis_builder: fn(&Self) = |config: &GenesisConfig| { - use codec::Encode; - sp_io::storage::set(well_known_keys::CODE, &config.code); - sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); - if let Some(ref changes_trie_config) = config.changes_trie_config { - sp_io::storage::set( - well_known_keys::CHANGES_TRIE_CONFIG, - &changes_trie_config.encode(), - ); - } - }; - extra_genesis_builder(self); - } - } -} From 32c3acae303649f852f09a2a213e2ccb5c780b92 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:31:40 +0000 Subject: [PATCH 15/52] Add required Event IsType constraint --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index c84ee4ff6bb0b..7af4f2ec1071e 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -162,7 +162,7 @@ pub mod pallet { >; /// The aggregated event type of the runtime. - type Event: Parameter + Member + From> + Debug; + type Event: Parameter + Member + From> + Debug + IsType<::Event>; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). #[pallet::constant] From d4fcfc104a343fb745d59dc3950a284b1deeece5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:32:42 +0000 Subject: [PATCH 16/52] Add disable supertrait check --- frame/system/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 7af4f2ec1071e..bb214a213ae6b 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -99,8 +99,9 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - #[pallet::config] /// System configuration trait. Implemented by runtime. + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] pub trait Config: 'static + Eq + Clone { /// The basic call filter to use in Origin. All origins are built with this filter as base, /// except Root. From 68b03166e9c487f3df4cae60f9a433ec6ff4cdc8 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:34:56 +0000 Subject: [PATCH 17/52] Fix leftover Trait trait --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index bb214a213ae6b..98d891b1a1428 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -213,7 +213,7 @@ pub mod pallet { pub struct Pallet(PhantomData); #[pallet::hooks] - impl Hooks for Pallet { + impl Hooks for Pallet { fn on_runtime_upgrade() -> frame_support::weights::Weight { if !UpgradedToU32RefCount::get() { Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| From 2f8152a06398ec414bfa2c055b9e5cc7d7131d60 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:36:41 +0000 Subject: [PATCH 18/52] Add missing pallet prefix for weight attributes --- frame/system/src/lib.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 98d891b1a1428..54a3e5f088ed9 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -238,7 +238,7 @@ pub mod pallet { /// A dispatch that will fill the block weight up to the given ratio. // TODO: This should only be available for testing, rather than in general usage, but // that's not possible at present (since it's within the decl_module macro). - #[weight(*_ratio * T::BlockWeights::get().max_block)] + #[pallet::weight(*_ratio * T::BlockWeights::get().max_block)] fn fill_block(origin: OriginFor, _ratio: Perbill) -> DispatchResultWithPostInfo { ensure_root(origin)?; Ok(().into()) @@ -251,7 +251,7 @@ pub mod pallet { /// - Base Weight: 0.665 µs, independent of remark length. /// - No DB operations. /// # - #[weight(T::SystemWeightInfo::remark(_remark.len() as u32))] + #[pallet::weight(T::SystemWeightInfo::remark(_remark.len() as u32))] fn remark(origin: OriginFor, _remark: Vec) -> DispatchResultWithPostInfo { ensure_signed(origin)?; Ok(().into()) @@ -265,7 +265,7 @@ pub mod pallet { /// - Base Weight: 1.405 µs /// - 1 write to HEAP_PAGES /// # - #[weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))] + #[pallet::weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))] fn set_heap_pages(origin: OriginFor, pages: u64) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); @@ -282,7 +282,7 @@ pub mod pallet { /// The weight of this function is dependent on the runtime, but generally this is very expensive. /// We will treat this as a full block. /// # - #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] + #[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] pub fn set_code(origin: OriginFor, code: Vec) -> DispatchResultWithPostInfo { ensure_root(origin)?; Self::can_set_code(&code)?; @@ -300,7 +300,7 @@ pub mod pallet { /// - 1 event. /// The weight of this function is dependent on the runtime. We will treat this as a full block. /// # - #[weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] + #[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] pub fn set_code_without_checks( origin: OriginFor, code: Vec @@ -321,7 +321,7 @@ pub mod pallet { /// - DB Weight: /// - Writes: Changes Trie, System Digest /// # - #[weight((T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational))] + #[pallet::weight((T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational))] pub fn set_changes_trie_config( origin: OriginFor, changes_trie_config: Option @@ -350,7 +350,7 @@ pub mod pallet { /// - Base Weight: 0.568 * i µs /// - Writes: Number of items /// # - #[weight(( + #[pallet::weight(( T::SystemWeightInfo::set_storage(items.len() as u32), DispatchClass::Operational, ))] @@ -370,7 +370,7 @@ pub mod pallet { /// - Base Weight: .378 * i µs /// - Writes: Number of items /// # - #[weight(( + #[pallet::weight(( T::SystemWeightInfo::kill_storage(keys.len() as u32), DispatchClass::Operational, ))] @@ -393,7 +393,7 @@ pub mod pallet { /// - Base Weight: 0.834 * P µs /// - Writes: Number of subkeys + 1 /// # - #[weight(( + #[pallet::weight(( T::SystemWeightInfo::kill_prefix(_subkeys.saturating_add(1)), DispatchClass::Operational, ))] @@ -417,7 +417,7 @@ pub mod pallet { /// Base Weight: 8.626 µs /// No DB Read or Write operations because caller is already in overlay /// # - #[weight((T::SystemWeightInfo::suicide(), DispatchClass::Operational))] + #[pallet::weight((T::SystemWeightInfo::suicide(), DispatchClass::Operational))] pub fn suicide(origin: OriginFor) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; let account = Account::::get(&who); From 7eb1fd355d30be4fa2875ec6481e2ae76d10ba94 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:38:06 +0000 Subject: [PATCH 19/52] Add missing Error type parameter --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 54a3e5f088ed9..38724bea6de81 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -449,7 +449,7 @@ pub mod pallet { /// Error for the System module #[pallet::error] - pub enum Error { + pub enum Error { /// The name of specification does not match between the current runtime /// and the new runtime. InvalidSpecName, From 1de98d7028a44f6686745815f237b7d33cd036e5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 11:39:45 +0000 Subject: [PATCH 20/52] Add missing Hooks type parameter --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 38724bea6de81..ed270f3cd17d1 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -213,7 +213,7 @@ pub mod pallet { pub struct Pallet(PhantomData); #[pallet::hooks] - impl Hooks for Pallet { + impl Hooks for Pallet { fn on_runtime_upgrade() -> frame_support::weights::Weight { if !UpgradedToU32RefCount::get() { Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| From 36295ac38d53f0cc0c4241e3cf8437ae2312369d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 12:01:39 +0000 Subject: [PATCH 21/52] Private call visibility, restore original helper types and helpers etc --- frame/system/src/lib.rs | 788 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 780 insertions(+), 8 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index ed270f3cd17d1..75086e6059961 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -96,8 +96,9 @@ pub use pallet::*; #[frame_support::pallet] pub mod pallet { use super::*; + use super::pallet_prelude::*; + use crate as frame_system; use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; /// System configuration trait. Implemented by runtime. #[pallet::config] @@ -207,7 +208,6 @@ pub mod pallet { type SS58Prefix: Get; } - #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] pub struct Pallet(PhantomData); @@ -239,7 +239,7 @@ pub mod pallet { // TODO: This should only be available for testing, rather than in general usage, but // that's not possible at present (since it's within the decl_module macro). #[pallet::weight(*_ratio * T::BlockWeights::get().max_block)] - fn fill_block(origin: OriginFor, _ratio: Perbill) -> DispatchResultWithPostInfo { + pub(crate) fn fill_block(origin: OriginFor, _ratio: Perbill) -> DispatchResultWithPostInfo { ensure_root(origin)?; Ok(().into()) } @@ -252,7 +252,7 @@ pub mod pallet { /// - No DB operations. /// # #[pallet::weight(T::SystemWeightInfo::remark(_remark.len() as u32))] - fn remark(origin: OriginFor, _remark: Vec) -> DispatchResultWithPostInfo { + pub(crate) fn remark(origin: OriginFor, _remark: Vec) -> DispatchResultWithPostInfo { ensure_signed(origin)?; Ok(().into()) } @@ -266,7 +266,7 @@ pub mod pallet { /// - 1 write to HEAP_PAGES /// # #[pallet::weight((T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational))] - fn set_heap_pages(origin: OriginFor, pages: u64) -> DispatchResultWithPostInfo { + pub(crate) fn set_heap_pages(origin: OriginFor, pages: u64) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); Ok(().into()) @@ -354,7 +354,7 @@ pub mod pallet { T::SystemWeightInfo::set_storage(items.len() as u32), DispatchClass::Operational, ))] - fn set_storage(origin: OriginFor, items: Vec) -> DispatchResultWithPostInfo { + pub(crate) fn set_storage(origin: OriginFor, items: Vec) -> DispatchResultWithPostInfo { ensure_root(origin)?; for i in &items { storage::unhashed::put_raw(&i.0, &i.1); @@ -374,7 +374,7 @@ pub mod pallet { T::SystemWeightInfo::kill_storage(keys.len() as u32), DispatchClass::Operational, ))] - fn kill_storage(origin: OriginFor, keys: Vec) -> DispatchResultWithPostInfo { + pub(crate) fn kill_storage(origin: OriginFor, keys: Vec) -> DispatchResultWithPostInfo { ensure_root(origin)?; for key in &keys { storage::unhashed::kill(&key); @@ -397,7 +397,7 @@ pub mod pallet { T::SystemWeightInfo::kill_prefix(_subkeys.saturating_add(1)), DispatchClass::Operational, ))] - fn kill_prefix( + pub(crate) fn kill_prefix( origin: OriginFor, prefix: Key, _subkeys: u32 @@ -632,3 +632,775 @@ pub mod pallet { } } } + +pub type DigestOf = generic::Digest<::Hash>; +pub type DigestItemOf = generic::DigestItem<::Hash>; + +pub type Key = Vec; +pub type KeyValue = (Vec, Vec); + +/// A phase of a block's execution. +#[derive(Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] +pub enum Phase { + /// Applying an extrinsic. + ApplyExtrinsic(u32), + /// Finalizing the block. + Finalization, + /// Initializing the block. + Initialization, +} + +impl Default for Phase { + fn default() -> Self { + Self::Initialization + } +} + +/// Record of an event happening. +#[derive(Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] +pub struct EventRecord { + /// The phase of the block it happened in. + pub phase: Phase, + /// The event itself. + pub event: E, + /// The list of the topics this event has. + pub topics: Vec, +} + +/// Origin for the System module. +#[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode)] +pub enum RawOrigin { + /// The system itself ordained this dispatch to happen: this is the highest privilege level. + Root, + /// It is signed by some public key and we provide the `AccountId`. + Signed(AccountId), + /// It is signed by nobody, can be either: + /// * included and agreed upon by the validators anyway, + /// * or unsigned transaction validated by a module. + None, +} + +impl From> for RawOrigin { + fn from(s: Option) -> RawOrigin { + match s { + Some(who) => RawOrigin::Signed(who), + None => RawOrigin::None, + } + } +} + +/// Exposed trait-generic origin type. +pub type Origin = RawOrigin<::AccountId>; + +// Create a Hash with 69 for each byte, +// only used to build genesis config. +#[cfg(feature = "std")] +fn hash69 + Default>() -> T { + let mut h = T::default(); + h.as_mut().iter_mut().for_each(|byte| *byte = 69); + h +} + +/// This type alias represents an index of an event. +/// +/// We use `u32` here because this index is used as index for `Events` +/// which can't contain more than `u32::max_value()` items. +type EventIndex = u32; + +/// Type used to encode the number of references an account has. +pub type RefCount = u32; + +/// Information of an account. +#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] +pub struct AccountInfo { + /// The number of transactions this account has sent. + pub nonce: Index, + /// The number of other modules that currently depend on this account's existence. The account + /// cannot be reaped until this is zero. + pub refcount: RefCount, + /// The additional data that belongs to this account. Used to store the balance(s) in a lot of + /// chains. + pub data: AccountData, +} + +/// Stores the `spec_version` and `spec_name` of when the last runtime upgrade +/// happened. +#[derive(sp_runtime::RuntimeDebug, Encode, Decode)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct LastRuntimeUpgradeInfo { + pub spec_version: codec::Compact, + pub spec_name: sp_runtime::RuntimeString, +} + +impl LastRuntimeUpgradeInfo { + /// Returns if the runtime was upgraded in comparison of `self` and `current`. + /// + /// Checks if either the `spec_version` increased or the `spec_name` changed. + pub fn was_upgraded(&self, current: &sp_version::RuntimeVersion) -> bool { + current.spec_version > self.spec_version.0 || current.spec_name != self.spec_name + } +} + +impl From for LastRuntimeUpgradeInfo { + fn from(version: sp_version::RuntimeVersion) -> Self { + Self { + spec_version: version.spec_version.into(), + spec_name: version.spec_name, + } + } +} + +pub struct EnsureRoot(sp_std::marker::PhantomData); +impl< + O: Into, O>> + From>, + AccountId, +> EnsureOrigin for EnsureRoot { + type Success = (); + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + RawOrigin::Root => Ok(()), + r => Err(O::from(r)), + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Root) + } +} + +pub struct EnsureSigned(sp_std::marker::PhantomData); +impl< + O: Into, O>> + From>, + AccountId: Default, +> EnsureOrigin for EnsureSigned { + type Success = AccountId; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + RawOrigin::Signed(who) => Ok(who), + r => Err(O::from(r)), + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::Signed(Default::default())) + } +} + +pub struct EnsureSignedBy(sp_std::marker::PhantomData<(Who, AccountId)>); +impl< + O: Into, O>> + From>, + Who: Contains, + AccountId: PartialEq + Clone + Ord + Default, +> EnsureOrigin for EnsureSignedBy { + type Success = AccountId; + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + RawOrigin::Signed(ref who) if Who::contains(who) => Ok(who.clone()), + r => Err(O::from(r)), + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + let members = Who::sorted_members(); + let first_member = match members.get(0) { + Some(account) => account.clone(), + None => Default::default(), + }; + O::from(RawOrigin::Signed(first_member.clone())) + } +} + +pub struct EnsureNone(sp_std::marker::PhantomData); +impl< + O: Into, O>> + From>, + AccountId, +> EnsureOrigin for EnsureNone { + type Success = (); + fn try_origin(o: O) -> Result { + o.into().and_then(|o| match o { + RawOrigin::None => Ok(()), + r => Err(O::from(r)), + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + O::from(RawOrigin::None) + } +} + +pub struct EnsureNever(sp_std::marker::PhantomData); +impl EnsureOrigin for EnsureNever { + type Success = T; + fn try_origin(o: O) -> Result { + Err(o) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + unimplemented!() + } +} + +/// The "OR gate" implementation of `EnsureOrigin`. +/// +/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first. +pub struct EnsureOneOf(sp_std::marker::PhantomData<(AccountId, L, R)>); +impl< + AccountId, + O: Into, O>> + From>, + L: EnsureOrigin, + R: EnsureOrigin, +> EnsureOrigin for EnsureOneOf { + type Success = Either; + fn try_origin(o: O) -> Result { + L::try_origin(o).map_or_else( + |o| R::try_origin(o).map(|o| Either::Right(o)), + |o| Ok(Either::Left(o)), + ) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + L::successful_origin() + } +} + +/// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction). +/// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise. +pub fn ensure_signed(o: OuterOrigin) -> Result + where OuterOrigin: Into, OuterOrigin>> +{ + match o.into() { + Ok(RawOrigin::Signed(t)) => Ok(t), + _ => Err(BadOrigin), + } +} + +/// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise. +pub fn ensure_root(o: OuterOrigin) -> Result<(), BadOrigin> + where OuterOrigin: Into, OuterOrigin>> +{ + match o.into() { + Ok(RawOrigin::Root) => Ok(()), + _ => Err(BadOrigin), + } +} + +/// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise. +pub fn ensure_none(o: OuterOrigin) -> Result<(), BadOrigin> + where OuterOrigin: Into, OuterOrigin>> +{ + match o.into() { + Ok(RawOrigin::None) => Ok(()), + _ => Err(BadOrigin), + } +} + +/// A type of block initialization to perform. +pub enum InitKind { + /// Leave inspectable storage entries in state. + /// + /// i.e. `Events` are not being reset. + /// Should only be used for off-chain calls, + /// regular block execution should clear those. + Inspection, + + /// Reset also inspectable storage entries. + /// + /// This should be used for regular block execution. + Full, +} + +impl Default for InitKind { + fn default() -> Self { + InitKind::Full + } +} + +/// Reference status; can be either referenced or unreferenced. +pub enum RefStatus { + Referenced, + Unreferenced, +} + +impl Module { + /// Deposits an event into this block's event record. + pub fn deposit_event(event: impl Into) { + Self::deposit_event_indexed(&[], event.into()); + } + + pub fn account_exists(who: &T::AccountId) -> bool { + Account::::contains_key(who) + } + + /// Increment the reference counter on an account. + pub fn inc_ref(who: &T::AccountId) { + Account::::mutate(who, |a| a.refcount = a.refcount.saturating_add(1)); + } + + /// Decrement the reference counter on an account. This *MUST* only be done once for every time + /// you called `inc_ref` on `who`. + pub fn dec_ref(who: &T::AccountId) { + Account::::mutate(who, |a| a.refcount = a.refcount.saturating_sub(1)); + } + + /// The number of outstanding references for the account `who`. + pub fn refs(who: &T::AccountId) -> RefCount { + Account::::get(who).refcount + } + + /// True if the account has no outstanding references. + pub fn allow_death(who: &T::AccountId) -> bool { + Account::::get(who).refcount == 0 + } + + /// Deposits an event into this block's event record adding this event + /// to the corresponding topic indexes. + /// + /// This will update storage entries that correspond to the specified topics. + /// It is expected that light-clients could subscribe to this topics. + pub fn deposit_event_indexed(topics: &[T::Hash], event: T::Event) { + let block_number = Self::block_number(); + // Don't populate events on genesis. + if block_number.is_zero() { return } + + let phase = ExecutionPhase::get().unwrap_or_default(); + let event = EventRecord { + phase, + event, + topics: topics.iter().cloned().collect::>(), + }; + + // Index of the to be added event. + let event_idx = { + let old_event_count = EventCount::get(); + let new_event_count = match old_event_count.checked_add(1) { + // We've reached the maximum number of events at this block, just + // don't do anything and leave the event_count unaltered. + None => return, + Some(nc) => nc, + }; + EventCount::put(new_event_count); + old_event_count + }; + + Events::::append(&event); + + for topic in topics { + >::append(topic, &(block_number, event_idx)); + } + } + + /// Gets the index of extrinsic that is currently executing. + pub fn extrinsic_index() -> Option { + storage::unhashed::get(well_known_keys::EXTRINSIC_INDEX) + } + + /// Gets extrinsics count. + pub fn extrinsic_count() -> u32 { + ExtrinsicCount::get().unwrap_or_default() + } + + pub fn all_extrinsics_len() -> u32 { + AllExtrinsicsLen::get().unwrap_or_default() + } + + /// Inform the system module of some additional weight that should be accounted for, in the + /// current block. + /// + /// NOTE: use with extra care; this function is made public only be used for certain modules + /// that need it. A runtime that does not have dynamic calls should never need this and should + /// stick to static weights. A typical use case for this is inner calls or smart contract calls. + /// Furthermore, it only makes sense to use this when it is presumably _cheap_ to provide the + /// argument `weight`; In other words, if this function is to be used to account for some + /// unknown, user provided call's weight, it would only make sense to use it if you are sure you + /// can rapidly compute the weight of the inner call. + /// + /// Even more dangerous is to note that this function does NOT take any action, if the new sum + /// of block weight is more than the block weight limit. This is what the _unchecked_. + /// + /// Another potential use-case could be for the `on_initialize` and `on_finalize` hooks. + pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) { + BlockWeight::mutate(|current_weight| { + current_weight.add(weight, class); + }); + } + + /// Start the execution of a particular block. + pub fn initialize( + number: &T::BlockNumber, + parent_hash: &T::Hash, + digest: &DigestOf, + kind: InitKind, + ) { + // populate environment + ExecutionPhase::put(Phase::Initialization); + storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32); + >::put(number); + >::put(digest); + >::put(parent_hash); + >::insert(*number - One::one(), parent_hash); + + // Remove previous block data from storage + BlockWeight::kill(); + + // Kill inspectable storage entries in state when `InitKind::Full`. + if let InitKind::Full = kind { + >::kill(); + EventCount::kill(); + >::remove_all(); + } + } + + /// Remove temporary "environment" entries in storage, compute the storage root and return the + /// resulting header for this block. + pub fn finalize() -> T::Header { + ExecutionPhase::kill(); + AllExtrinsicsLen::kill(); + + // The following fields + // + // - > + // - > + // - > + // - > + // - > + // - > + // + // stay to be inspected by the client and will be cleared by `Self::initialize`. + let number = >::get(); + let parent_hash = >::get(); + let mut digest = >::get(); + + let extrinsics = (0..ExtrinsicCount::take().unwrap_or_default()) + .map(ExtrinsicData::take) + .collect(); + let extrinsics_root = extrinsics_data_root::(extrinsics); + + // move block hash pruning window by one block + let block_hash_count = T::BlockHashCount::get(); + let to_remove = number.saturating_sub(block_hash_count).saturating_sub(One::one()); + + // keep genesis hash + if !to_remove.is_zero() { + >::remove(to_remove); + } + + let storage_root = T::Hash::decode(&mut &sp_io::storage::root()[..]) + .expect("Node is configured to use the same hash; qed"); + let storage_changes_root = sp_io::storage::changes_root(&parent_hash.encode()); + + // we can't compute changes trie root earlier && put it to the Digest + // because it will include all currently existing temporaries. + if let Some(storage_changes_root) = storage_changes_root { + let item = generic::DigestItem::ChangesTrieRoot( + T::Hash::decode(&mut &storage_changes_root[..]) + .expect("Node is configured to use the same hash; qed") + ); + digest.push(item); + } + + ::new(number, extrinsics_root, storage_root, parent_hash, digest) + } + + /// Deposits a log and ensures it matches the block's log data. + /// + /// # + /// - `O(1)` + /// - 1 storage write (codec `O(1)`) + /// # + pub fn deposit_log(item: DigestItemOf) { + >::append(item); + } + + /// Get the basic externalities for this module, useful for tests. + #[cfg(any(feature = "std", test))] + pub fn externalities() -> TestExternalities { + TestExternalities::new(sp_core::storage::Storage { + top: map![ + >::hashed_key_for(T::BlockNumber::zero()) => [69u8; 32].encode(), + >::hashed_key().to_vec() => T::BlockNumber::one().encode(), + >::hashed_key().to_vec() => [69u8; 32].encode() + ], + children_default: map![], + }) + } + + /// Set the block number to something in particular. Can be used as an alternative to + /// `initialize` for tests that don't need to bother with the other environment entries. + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] + pub fn set_block_number(n: T::BlockNumber) { + >::put(n); + } + + /// Sets the index of extrinsic that is currently executing. + #[cfg(any(feature = "std", test))] + pub fn set_extrinsic_index(extrinsic_index: u32) { + storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &extrinsic_index) + } + + /// Set the parent hash number to something in particular. Can be used as an alternative to + /// `initialize` for tests that don't need to bother with the other environment entries. + #[cfg(any(feature = "std", test))] + pub fn set_parent_hash(n: T::Hash) { + >::put(n); + } + + /// Set the current block weight. This should only be used in some integration tests. + #[cfg(any(feature = "std", test))] + pub fn set_block_consumed_resources(weight: Weight, len: usize) { + BlockWeight::mutate(|current_weight| { + current_weight.set(weight, DispatchClass::Normal) + }); + AllExtrinsicsLen::put(len as u32); + } + + /// Reset events. Can be used as an alternative to + /// `initialize` for tests that don't need to bother with the other environment entries. + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] + pub fn reset_events() { + >::kill(); + EventCount::kill(); + >::remove_all(); + } + + /// Return the chain's current runtime version. + pub fn runtime_version() -> RuntimeVersion { T::Version::get() } + + /// Retrieve the account transaction counter from storage. + pub fn account_nonce(who: impl EncodeLike) -> T::Index { + Account::::get(who).nonce + } + + /// Increment a particular account's nonce by 1. + pub fn inc_account_nonce(who: impl EncodeLike) { + Account::::mutate(who, |a| a.nonce += T::Index::one()); + } + + /// Note what the extrinsic data of the current extrinsic index is. + /// + /// This is required to be called before applying an extrinsic. The data will used + /// in [`Self::finalize`] to calculate the correct extrinsics root. + pub fn note_extrinsic(encoded_xt: Vec) { + ExtrinsicData::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt); + } + + /// To be called immediately after an extrinsic has been applied. + pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, mut info: DispatchInfo) { + info.weight = extract_actual_weight(r, &info); + Self::deposit_event( + match r { + Ok(_) => RawEvent::ExtrinsicSuccess(info), + Err(err) => { + sp_runtime::print(err); + RawEvent::ExtrinsicFailed(err.error, info) + }, + } + ); + + let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; + + storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index); + ExecutionPhase::put(Phase::ApplyExtrinsic(next_extrinsic_index)); + } + + /// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block + /// has been called. + pub fn note_finished_extrinsics() { + let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX) + .unwrap_or_default(); + ExtrinsicCount::put(extrinsic_index); + ExecutionPhase::put(Phase::Finalization); + } + + /// To be called immediately after finishing the initialization of the block + /// (e.g., called `on_initialize` for all modules). + pub fn note_finished_initialize() { + ExecutionPhase::put(Phase::ApplyExtrinsic(0)) + } + + /// An account is being created. + pub fn on_created_account(who: T::AccountId) { + T::OnNewAccount::on_new_account(&who); + Self::deposit_event(RawEvent::NewAccount(who)); + } + + /// Do anything that needs to be done after an account has been killed. + fn on_killed_account(who: T::AccountId) { + T::OnKilledAccount::on_killed_account(&who); + Self::deposit_event(RawEvent::KilledAccount(who)); + } + + /// Remove an account from storage. This should only be done when its refs are zero or you'll + /// get storage leaks in other modules. Nonetheless we assume that the calling logic knows best. + /// + /// This is a no-op if the account doesn't already exist. If it does then it will ensure + /// cleanups (those in `on_killed_account`) take place. + fn kill_account(who: &T::AccountId) { + if Account::::contains_key(who) { + let account = Account::::take(who); + if account.refcount > 0 { + debug::debug!( + target: "system", + "WARNING: Referenced account deleted. This is probably a bug." + ); + } + } + Module::::on_killed_account(who.clone()); + } + + /// Determine whether or not it is possible to update the code. + /// + /// Checks the given code if it is a valid runtime wasm blob by instantianting + /// it and extracting the runtime version of it. It checks that the runtime version + /// of the old and new runtime has the same spec name and that the spec version is increasing. + pub fn can_set_code(code: &[u8]) -> Result<(), sp_runtime::DispatchError> { + let current_version = T::Version::get(); + let new_version = sp_io::misc::runtime_version(&code) + .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) + .ok_or_else(|| Error::::FailedToExtractRuntimeVersion)?; + + if new_version.spec_name != current_version.spec_name { + Err(Error::::InvalidSpecName)? + } + + if new_version.spec_version <= current_version.spec_version { + Err(Error::::SpecVersionNeedsToIncrease)? + } + + Ok(()) + } +} + +/// Event handler which calls on_created_account when it happens. +pub struct CallOnCreatedAccount(PhantomData); +impl Happened for CallOnCreatedAccount { + fn happened(who: &T::AccountId) { + Module::::on_created_account(who.clone()); + } +} + +/// Event handler which calls kill_account when it happens. +pub struct CallKillAccount(PhantomData); +impl Happened for CallKillAccount { + fn happened(who: &T::AccountId) { + Module::::kill_account(who) + } +} + +impl BlockNumberProvider for Module +{ + type BlockNumber = ::BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + Module::::block_number() + } +} + +// Implement StoredMap for a simple single-item, kill-account-on-remove system. This works fine for +// storing a single item which is required to not be empty/default for the account to exist. +// Anything more complex will need more sophisticated logic. +impl StoredMap for Module { + fn get(k: &T::AccountId) -> T::AccountData { + Account::::get(k).data + } + fn is_explicit(k: &T::AccountId) -> bool { + Account::::contains_key(k) + } + fn insert(k: &T::AccountId, data: T::AccountData) { + let existed = Account::::contains_key(k); + Account::::mutate(k, |a| a.data = data); + if !existed { + Self::on_created_account(k.clone()); + } + } + fn remove(k: &T::AccountId) { + Self::kill_account(k) + } + fn mutate(k: &T::AccountId, f: impl FnOnce(&mut T::AccountData) -> R) -> R { + let existed = Account::::contains_key(k); + let r = Account::::mutate(k, |a| f(&mut a.data)); + if !existed { + Self::on_created_account(k.clone()); + } + r + } + fn mutate_exists(k: &T::AccountId, f: impl FnOnce(&mut Option) -> R) -> R { + Self::try_mutate_exists(k, |x| -> Result { Ok(f(x)) }).expect("Infallible; qed") + } + fn try_mutate_exists(k: &T::AccountId, f: impl FnOnce(&mut Option) -> Result) -> Result { + Account::::try_mutate_exists(k, |maybe_value| { + let existed = maybe_value.is_some(); + let (maybe_prefix, mut maybe_data) = split_inner( + maybe_value.take(), + |account| ((account.nonce, account.refcount), account.data) + ); + f(&mut maybe_data).map(|result| { + *maybe_value = maybe_data.map(|data| { + let (nonce, refcount) = maybe_prefix.unwrap_or_default(); + AccountInfo { nonce, refcount, data } + }); + (existed, maybe_value.is_some(), result) + }) + }).map(|(existed, exists, v)| { + if !existed && exists { + Self::on_created_account(k.clone()); + } else if existed && !exists { + Self::on_killed_account(k.clone()); + } + v + }) + } +} + +/// Split an `option` into two constituent options, as defined by a `splitter` function. +pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S)) + -> (Option, Option) +{ + match option { + Some(inner) => { + let (r, s) = splitter(inner); + (Some(r), Some(s)) + } + None => (None, None), + } +} + +impl IsDeadAccount for Module { + fn is_dead_account(who: &T::AccountId) -> bool { + !Account::::contains_key(who) + } +} + +pub struct ChainContext(sp_std::marker::PhantomData); +impl Default for ChainContext { + fn default() -> Self { + ChainContext(sp_std::marker::PhantomData) + } +} + +impl Lookup for ChainContext { + type Source = ::Source; + type Target = ::Target; + + fn lookup(&self, s: Self::Source) -> Result { + ::lookup(s) + } +} + +/// Prelude to be used alongside pallet macro, for ease of use. +pub mod pallet_prelude { + pub use crate::{ensure_signed, ensure_none, ensure_root}; + + /// Type alias for the `Origin` associated type of system config. + pub type OriginFor = ::Origin; + + /// Type alias for the `BlockNumber` associated type of system config. + pub type BlockNumberFor = ::BlockNumber; +} From 4983150a68fd6f44d93f02ba496bcc966c35fef4 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 14:23:22 +0000 Subject: [PATCH 22/52] Fix hooks type parameter --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 75086e6059961..ed829be0cfe4f 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -213,7 +213,7 @@ pub mod pallet { pub struct Pallet(PhantomData); #[pallet::hooks] - impl Hooks for Pallet { + impl Hooks> for Pallet { fn on_runtime_upgrade() -> frame_support::weights::Weight { if !UpgradedToU32RefCount::get() { Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| From a82525ec1219426d069a9de11bc8f72986758b24 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 14:24:29 +0000 Subject: [PATCH 23/52] Rename RawEvent to Event --- frame/system/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index ed829be0cfe4f..23a8176736700 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -288,7 +288,7 @@ pub mod pallet { Self::can_set_code(&code)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); - Self::deposit_event(RawEvent::CodeUpdated); + Self::deposit_event(Event::CodeUpdated); Ok(().into()) } @@ -307,7 +307,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); - Self::deposit_event(RawEvent::CodeUpdated); + Self::deposit_event(Event::CodeUpdated); Ok(().into()) } @@ -1196,10 +1196,10 @@ impl Module { info.weight = extract_actual_weight(r, &info); Self::deposit_event( match r { - Ok(_) => RawEvent::ExtrinsicSuccess(info), + Ok(_) => Event::ExtrinsicSuccess(info), Err(err) => { sp_runtime::print(err); - RawEvent::ExtrinsicFailed(err.error, info) + Event::ExtrinsicFailed(err.error, info) }, } ); @@ -1228,13 +1228,13 @@ impl Module { /// An account is being created. pub fn on_created_account(who: T::AccountId) { T::OnNewAccount::on_new_account(&who); - Self::deposit_event(RawEvent::NewAccount(who)); + Self::deposit_event(Event::NewAccount(who)); } /// Do anything that needs to be done after an account has been killed. fn on_killed_account(who: T::AccountId) { T::OnKilledAccount::on_killed_account(&who); - Self::deposit_event(RawEvent::KilledAccount(who)); + Self::deposit_event(Event::KilledAccount(who)); } /// Remove an account from storage. This should only be done when its refs are zero or you'll From 5fead5145e68d914156148dfd59cc1f90399b45d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 14:31:32 +0000 Subject: [PATCH 24/52] Add missing storage type annotations --- frame/executive/src/lib.rs | 4 +- frame/system/src/extensions/check_weight.rs | 6 +-- frame/system/src/lib.rs | 50 ++++++++++----------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index fdde914b07e04..7047fa0bd2894 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -261,11 +261,11 @@ where /// Returns if the runtime was upgraded since the last time this function was called. fn runtime_upgraded() -> bool { - let last = frame_system::LastRuntimeUpgrade::get(); + let last = frame_system::LastRuntimeUpgrade::::get(); let current = >::get(); if last.map(|v| v.was_upgraded(¤t)).unwrap_or(true) { - frame_system::LastRuntimeUpgrade::put( + frame_system::LastRuntimeUpgrade::::put( frame_system::LastRuntimeUpgradeInfo::from(current), ); true diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index c84c29518593f..39c57b49667ff 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -115,8 +115,8 @@ impl CheckWeight where let next_weight = Self::check_block_weight(info)?; Self::check_extrinsic_weight(info)?; - crate::AllExtrinsicsLen::put(next_len); - crate::BlockWeight::put(next_weight); + crate::AllExtrinsicsLen::::put(next_len); + crate::BlockWeight::::put(next_weight); Ok(()) } @@ -257,7 +257,7 @@ impl SignedExtension for CheckWeight where let unspent = post_info.calc_unspent(info); if unspent > 0 { - crate::BlockWeight::mutate(|current_weight| { + crate::BlockWeight::::mutate(|current_weight| { current_weight.sub(unspent, info.class); }) } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 23a8176736700..c6acd2a5668f0 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -215,11 +215,11 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_runtime_upgrade() -> frame_support::weights::Weight { - if !UpgradedToU32RefCount::get() { + if !UpgradedToU32RefCount::::get() { Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| Some(AccountInfo { nonce, refcount: rc as RefCount, data }) ); - UpgradedToU32RefCount::put(true); + UpgradedToU32RefCount::::put(true); T::BlockWeights::get().max_block } else { 0 @@ -604,7 +604,7 @@ pub mod pallet { let data = Option::as_ref(&data); let v: Option<&LastRuntimeUpgradeInfo> = data; if let Some(v) = v { - as frame_support::storage::StorageValue< LastRuntimeUpgradeInfo, >>::put::<&LastRuntimeUpgradeInfo>(v); } @@ -613,7 +613,7 @@ pub mod pallet { let builder: fn(&Self) -> _ = |_| true; let data = &builder(self); let v: &bool = data; - >::put::<&bool>( + as frame_support::storage::StorageValue>::put::<&bool>( v, ); } @@ -970,7 +970,7 @@ impl Module { // Don't populate events on genesis. if block_number.is_zero() { return } - let phase = ExecutionPhase::get().unwrap_or_default(); + let phase = ExecutionPhase::::get().unwrap_or_default(); let event = EventRecord { phase, event, @@ -979,14 +979,14 @@ impl Module { // Index of the to be added event. let event_idx = { - let old_event_count = EventCount::get(); + let old_event_count = EventCount::::get(); let new_event_count = match old_event_count.checked_add(1) { // We've reached the maximum number of events at this block, just // don't do anything and leave the event_count unaltered. None => return, Some(nc) => nc, }; - EventCount::put(new_event_count); + EventCount::::put(new_event_count); old_event_count }; @@ -1004,11 +1004,11 @@ impl Module { /// Gets extrinsics count. pub fn extrinsic_count() -> u32 { - ExtrinsicCount::get().unwrap_or_default() + ExtrinsicCount::::get().unwrap_or_default() } pub fn all_extrinsics_len() -> u32 { - AllExtrinsicsLen::get().unwrap_or_default() + AllExtrinsicsLen::::get().unwrap_or_default() } /// Inform the system module of some additional weight that should be accounted for, in the @@ -1027,7 +1027,7 @@ impl Module { /// /// Another potential use-case could be for the `on_initialize` and `on_finalize` hooks. pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) { - BlockWeight::mutate(|current_weight| { + BlockWeight::::mutate(|current_weight| { current_weight.add(weight, class); }); } @@ -1040,7 +1040,7 @@ impl Module { kind: InitKind, ) { // populate environment - ExecutionPhase::put(Phase::Initialization); + ExecutionPhase::::put(Phase::Initialization); storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &0u32); >::put(number); >::put(digest); @@ -1048,12 +1048,12 @@ impl Module { >::insert(*number - One::one(), parent_hash); // Remove previous block data from storage - BlockWeight::kill(); + BlockWeight::::kill(); // Kill inspectable storage entries in state when `InitKind::Full`. if let InitKind::Full = kind { >::kill(); - EventCount::kill(); + EventCount::::kill(); >::remove_all(); } } @@ -1061,8 +1061,8 @@ impl Module { /// Remove temporary "environment" entries in storage, compute the storage root and return the /// resulting header for this block. pub fn finalize() -> T::Header { - ExecutionPhase::kill(); - AllExtrinsicsLen::kill(); + ExecutionPhase::::kill(); + AllExtrinsicsLen::::kill(); // The following fields // @@ -1078,8 +1078,8 @@ impl Module { let parent_hash = >::get(); let mut digest = >::get(); - let extrinsics = (0..ExtrinsicCount::take().unwrap_or_default()) - .map(ExtrinsicData::take) + let extrinsics = (0..ExtrinsicCount::::take().unwrap_or_default()) + .map(ExtrinsicData::::take) .collect(); let extrinsics_root = extrinsics_data_root::(extrinsics); @@ -1155,10 +1155,10 @@ impl Module { /// Set the current block weight. This should only be used in some integration tests. #[cfg(any(feature = "std", test))] pub fn set_block_consumed_resources(weight: Weight, len: usize) { - BlockWeight::mutate(|current_weight| { + BlockWeight::::mutate(|current_weight| { current_weight.set(weight, DispatchClass::Normal) }); - AllExtrinsicsLen::put(len as u32); + AllExtrinsicsLen::::put(len as u32); } /// Reset events. Can be used as an alternative to @@ -1166,7 +1166,7 @@ impl Module { #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] pub fn reset_events() { >::kill(); - EventCount::kill(); + EventCount::::kill(); >::remove_all(); } @@ -1188,7 +1188,7 @@ impl Module { /// This is required to be called before applying an extrinsic. The data will used /// in [`Self::finalize`] to calculate the correct extrinsics root. pub fn note_extrinsic(encoded_xt: Vec) { - ExtrinsicData::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt); + ExtrinsicData::::insert(Self::extrinsic_index().unwrap_or_default(), encoded_xt); } /// To be called immediately after an extrinsic has been applied. @@ -1207,7 +1207,7 @@ impl Module { let next_extrinsic_index = Self::extrinsic_index().unwrap_or_default() + 1u32; storage::unhashed::put(well_known_keys::EXTRINSIC_INDEX, &next_extrinsic_index); - ExecutionPhase::put(Phase::ApplyExtrinsic(next_extrinsic_index)); + ExecutionPhase::::put(Phase::ApplyExtrinsic(next_extrinsic_index)); } /// To be called immediately after `note_applied_extrinsic` of the last extrinsic of the block @@ -1215,14 +1215,14 @@ impl Module { pub fn note_finished_extrinsics() { let extrinsic_index: u32 = storage::unhashed::take(well_known_keys::EXTRINSIC_INDEX) .unwrap_or_default(); - ExtrinsicCount::put(extrinsic_index); - ExecutionPhase::put(Phase::Finalization); + ExtrinsicCount::::put(extrinsic_index); + ExecutionPhase::::put(Phase::Finalization); } /// To be called immediately after finishing the initialization of the block /// (e.g., called `on_initialize` for all modules). pub fn note_finished_initialize() { - ExecutionPhase::put(Phase::ApplyExtrinsic(0)) + ExecutionPhase::::put(Phase::ApplyExtrinsic(0)) } /// An account is being created. From 1c436f3bac89a30dcfc7065bdb4f4e4c386123df Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 14:33:21 +0000 Subject: [PATCH 25/52] Remove unused imports --- frame/system/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index c6acd2a5668f0..34d9cbba2bf23 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -41,8 +41,7 @@ use sp_runtime::{ use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; use frame_support::{ - decl_module, decl_event, decl_storage, decl_error, Parameter, ensure, debug, - storage, + Parameter, ensure, debug, storage, traits::{ Contains, Get, PalletInfo, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, StoredMap, EnsureOrigin, OriginTrait, Filter, @@ -445,7 +444,7 @@ pub mod pallet { /// Old name generated by `decl_event`. #[deprecated(note = "use `Event` instead")] - pub type RawEvent = Event; + pub type RawEvent = Event; /// Error for the System module #[pallet::error] From d68661ae653c84be6afd52bce1a3efa57d4a3316 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 15:02:07 +0000 Subject: [PATCH 26/52] Add GenesisConfig helpers for compat --- frame/system/src/lib.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 34d9cbba2bf23..a06ae475d944f 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -54,6 +54,8 @@ use frame_support::{ }; use codec::{Encode, Decode, FullCodec, EncodeLike}; +#[cfg(feature = "std")] +use frame_support::traits::GenesisBuild; #[cfg(any(feature = "std", test))] use sp_io::TestExternalities; @@ -632,6 +634,26 @@ pub mod pallet { } } +#[cfg(feature = "std")] +impl GenesisConfig { + /// Direct implementation of `GenesisBuild::build_storage`. + /// + /// Kept in order not to break dependency. + pub fn build_storage(&self) -> Result { + >::build_storage(self) + } + + /// Direct implementation of `GenesisBuild::assimilate_storage`. + /// + /// Kept in order not to break dependency. + pub fn assimilate_storage( + &self, + storage: &mut sp_runtime::Storage + ) -> Result<(), String> { + >::assimilate_storage(self, storage) + } +} + pub type DigestOf = generic::Digest<::Hash>; pub type DigestItemOf = generic::DigestItem<::Hash>; From 74325196790d8250f4242e14dd0da276eb3eecf6 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 15:04:40 +0000 Subject: [PATCH 27/52] Fix unused import warnings --- frame/executive/src/lib.rs | 2 +- frame/session/benchmarking/src/lib.rs | 2 +- frame/system/benchmarking/src/lib.rs | 2 +- frame/system/src/extensions/check_mortality.rs | 1 - frame/system/src/extensions/check_nonce.rs | 1 - frame/system/src/extensions/check_weight.rs | 1 - frame/system/src/offchain.rs | 2 +- 7 files changed, 4 insertions(+), 7 deletions(-) diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 7047fa0bd2894..e86558f7ab245 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -117,7 +117,7 @@ use sp_std::{prelude::*, marker::PhantomData}; use frame_support::{ - StorageValue, StorageMap, weights::{GetDispatchInfo, DispatchInfo, DispatchClass}, + weights::{GetDispatchInfo, DispatchInfo, DispatchClass}, traits::{OnInitialize, OnFinalize, OnRuntimeUpgrade, OffchainWorker}, dispatch::PostDispatchInfo, }; diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index 8f1911c125b85..06dfa3da34943 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -28,7 +28,7 @@ use sp_std::vec; use frame_benchmarking::benchmarks; use frame_support::{ codec::Decode, - storage::{StorageValue, StorageMap}, + storage::StorageValue, traits::{KeyOwnerProofSystem, OnInitialize}, }; use frame_system::RawOrigin; diff --git a/frame/system/benchmarking/src/lib.rs b/frame/system/benchmarking/src/lib.rs index 57ae998862959..b5641bdf817a3 100644 --- a/frame/system/benchmarking/src/lib.rs +++ b/frame/system/benchmarking/src/lib.rs @@ -26,7 +26,7 @@ use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; use sp_runtime::traits::Hash; use frame_benchmarking::{benchmarks, whitelisted_caller}; use frame_support::{ - storage::{self, StorageMap}, + storage, traits::Get, weights::DispatchClass, }; diff --git a/frame/system/src/extensions/check_mortality.rs b/frame/system/src/extensions/check_mortality.rs index 8e5fd36e6217a..f1951baba5d50 100644 --- a/frame/system/src/extensions/check_mortality.rs +++ b/frame/system/src/extensions/check_mortality.rs @@ -17,7 +17,6 @@ use codec::{Encode, Decode}; use crate::{Config, Module, BlockHash}; -use frame_support::StorageMap; use sp_runtime::{ generic::Era, traits::{SignedExtension, DispatchInfoOf, SaturatedConversion}, diff --git a/frame/system/src/extensions/check_nonce.rs b/frame/system/src/extensions/check_nonce.rs index 0c610506d6616..f1ea265930c25 100644 --- a/frame/system/src/extensions/check_nonce.rs +++ b/frame/system/src/extensions/check_nonce.rs @@ -19,7 +19,6 @@ use codec::{Encode, Decode}; use crate::Config; use frame_support::{ weights::DispatchInfo, - StorageMap, }; use sp_runtime::{ traits::{SignedExtension, DispatchInfoOf, Dispatchable, One}, diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index 39c57b49667ff..6d70a1324dc4e 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -28,7 +28,6 @@ use sp_runtime::{ use frame_support::{ traits::{Get}, weights::{PostDispatchInfo, DispatchInfo, DispatchClass, priority::FrameTransactionPriority}, - StorageValue, }; /// Block resource (weight) limit check. diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index db417c028675d..05a5882ee3982 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -63,7 +63,7 @@ use sp_std::convert::{TryInto, TryFrom}; use sp_std::prelude::{Box, Vec}; use sp_runtime::app_crypto::RuntimeAppPublic; use sp_runtime::traits::{Extrinsic as ExtrinsicT, IdentifyAccount, One}; -use frame_support::{debug, storage::StorageMap, RuntimeDebug}; +use frame_support::{debug, RuntimeDebug}; /// Marker struct used to flag using all supported keys to sign a payload. pub struct ForAll {} From d2a2d5b6c002e13c5f6f66dc13ee76ad64355ba7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 16:00:16 +0000 Subject: [PATCH 28/52] Update frame/support/procedural/src/storage/print_pallet_upgrade.rs Co-authored-by: Guillaume Thiolliere --- frame/support/procedural/src/storage/print_pallet_upgrade.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/frame/support/procedural/src/storage/print_pallet_upgrade.rs index 9189724d7860f..e0eac516442af 100644 --- a/frame/support/procedural/src/storage/print_pallet_upgrade.rs +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -324,7 +324,7 @@ pub mod pallet {{ pub struct Pallet{decl_gen}(PhantomData{use_gen_tuple}); #[pallet::hooks] - impl{impl_gen} Hooks for Pallet{use_gen} + impl{impl_gen} Hooks> for Pallet{use_gen} // TODO_MAYBE_WHERE_CLAUSE {{ // TODO_ON_FINALIZE From b88b122dbc5f127613c0b17242adad1f4655caee Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:07:33 +0000 Subject: [PATCH 29/52] Fix test errors and warnings --- frame/balances/src/tests.rs | 8 ++++---- frame/balances/src/tests_local.rs | 4 ++-- frame/contracts/src/tests.rs | 14 +++++++------- frame/executive/src/lib.rs | 10 +++++----- frame/system/src/extensions/check_weight.rs | 20 ++++++++++---------- frame/system/src/tests.rs | 2 +- frame/transaction-payment/src/lib.rs | 2 +- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 1c120272dd0b6..0d48c74f6affe 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -746,7 +746,7 @@ macro_rules! decl_tests { assert_eq!( events(), [ - Event::system(system::RawEvent::NewAccount(1)), + Event::system(system::Event::NewAccount(1)), Event::balances(RawEvent::Endowed(1, 100)), Event::balances(RawEvent::BalanceSet(1, 100, 0)), ] @@ -758,7 +758,7 @@ macro_rules! decl_tests { events(), [ Event::balances(RawEvent::DustLost(1, 99)), - Event::system(system::RawEvent::KilledAccount(1)) + Event::system(system::Event::KilledAccount(1)) ] ); }); @@ -775,7 +775,7 @@ macro_rules! decl_tests { assert_eq!( events(), [ - Event::system(system::RawEvent::NewAccount(1)), + Event::system(system::Event::NewAccount(1)), Event::balances(RawEvent::Endowed(1, 100)), Event::balances(RawEvent::BalanceSet(1, 100, 0)), ] @@ -791,7 +791,7 @@ macro_rules! decl_tests { assert_eq!( events(), [ - Event::system(system::RawEvent::KilledAccount(1)) + Event::system(system::Event::KilledAccount(1)) ] ); }); diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index 887b280945f1a..50d0a8580f4a7 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -170,7 +170,7 @@ fn emit_events_with_no_existential_deposit_suicide_with_dust() { assert_eq!( events(), [ - Event::system(system::RawEvent::NewAccount(1)), + Event::system(system::Event::NewAccount(1)), Event::balances(RawEvent::Endowed(1, 100)), Event::balances(RawEvent::BalanceSet(1, 100, 0)), ] @@ -187,7 +187,7 @@ fn emit_events_with_no_existential_deposit_suicide_with_dust() { events(), [ Event::balances(RawEvent::DustLost(1, 1)), - Event::system(system::RawEvent::KilledAccount(1)) + Event::system(system::Event::KilledAccount(1)) ] ); }); diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 78b1f7e30f82d..5028740ac3d1d 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -473,7 +473,7 @@ fn instantiate_and_call_and_deposit_event() { pretty_assertions::assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(ALICE.clone())), + event: MetaEvent::system(frame_system::Event::NewAccount(ALICE.clone())), topics: vec![], }, EventRecord { @@ -490,7 +490,7 @@ fn instantiate_and_call_and_deposit_event() { }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(addr.clone())), + event: MetaEvent::system(frame_system::Event::NewAccount(addr.clone())), topics: vec![], }, EventRecord { @@ -651,7 +651,7 @@ fn test_set_rent_code_and_hash() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(ALICE)), + event: MetaEvent::system(frame_system::Event::NewAccount(ALICE)), topics: vec![], }, EventRecord { @@ -1233,7 +1233,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(ALICE)), + event: MetaEvent::system(frame_system::Event::NewAccount(ALICE)), topics: vec![], }, EventRecord { @@ -1388,7 +1388,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), + event: MetaEvent::system(frame_system::Event::NewAccount(CHARLIE)), topics: vec![], }, EventRecord { @@ -1398,7 +1398,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: }, EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(addr_django.clone())), + event: MetaEvent::system(frame_system::Event::NewAccount(addr_django.clone())), topics: vec![], }, EventRecord { @@ -1438,7 +1438,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(System::events(), vec![ EventRecord { phase: Phase::Initialization, - event: MetaEvent::system(system::RawEvent::KilledAccount(addr_django.clone())), + event: MetaEvent::system(system::Event::KilledAccount(addr_django.clone())), topics: vec![], }, EventRecord { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index e86558f7ab245..ac073f35eead3 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -998,7 +998,7 @@ mod tests { new_test_ext(1).execute_with(|| { RUNTIME_VERSION.with(|v| *v.borrow_mut() = Default::default()); // It should be added at genesis - assert!(frame_system::LastRuntimeUpgrade::exists()); + assert!(frame_system::LastRuntimeUpgrade::::exists()); assert!(!Executive::runtime_upgraded()); RUNTIME_VERSION.with(|v| *v.borrow_mut() = sp_version::RuntimeVersion { @@ -1008,7 +1008,7 @@ mod tests { assert!(Executive::runtime_upgraded()); assert_eq!( Some(LastRuntimeUpgradeInfo { spec_version: 1.into(), spec_name: "".into() }), - frame_system::LastRuntimeUpgrade::get(), + frame_system::LastRuntimeUpgrade::::get(), ); RUNTIME_VERSION.with(|v| *v.borrow_mut() = sp_version::RuntimeVersion { @@ -1019,7 +1019,7 @@ mod tests { assert!(Executive::runtime_upgraded()); assert_eq!( Some(LastRuntimeUpgradeInfo { spec_version: 1.into(), spec_name: "test".into() }), - frame_system::LastRuntimeUpgrade::get(), + frame_system::LastRuntimeUpgrade::::get(), ); RUNTIME_VERSION.with(|v| *v.borrow_mut() = sp_version::RuntimeVersion { @@ -1030,11 +1030,11 @@ mod tests { }); assert!(!Executive::runtime_upgraded()); - frame_system::LastRuntimeUpgrade::take(); + frame_system::LastRuntimeUpgrade::::take(); assert!(Executive::runtime_upgraded()); assert_eq!( Some(LastRuntimeUpgradeInfo { spec_version: 1.into(), spec_name: "test".into() }), - frame_system::LastRuntimeUpgrade::get(), + frame_system::LastRuntimeUpgrade::::get(), ); }) } diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index 6d70a1324dc4e..70116f4b6524b 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -464,7 +464,7 @@ mod tests { let normal_limit = normal_weight_limit(); // given almost full block - BlockWeight::mutate(|current_weight| { + BlockWeight::::mutate(|current_weight| { current_weight.set(normal_limit, DispatchClass::Normal) }); // will not fit. @@ -474,7 +474,7 @@ mod tests { // likewise for length limit. let len = 100_usize; - AllExtrinsicsLen::put(normal_length_limit()); + AllExtrinsicsLen::::put(normal_length_limit()); assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok()); }) @@ -507,7 +507,7 @@ mod tests { let normal = DispatchInfo::default(); let normal_limit = normal_weight_limit() as usize; let reset_check_weight = |tx, s, f| { - AllExtrinsicsLen::put(0); + AllExtrinsicsLen::::put(0); let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, tx, s); if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } }; @@ -543,7 +543,7 @@ mod tests { let len = 0_usize; let reset_check_weight = |i, f, s| { - BlockWeight::mutate(|current_weight| { + BlockWeight::::mutate(|current_weight| { current_weight.set(s, DispatchClass::Normal) }); let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, i, len); @@ -569,20 +569,20 @@ mod tests { let base_extrinsic = block_weights().get(DispatchClass::Normal).base_extrinsic; // We allow 75% for normal transaction, so we put 25% - extrinsic base weight - BlockWeight::mutate(|current_weight| { + BlockWeight::::mutate(|current_weight| { current_weight.set(0, DispatchClass::Mandatory); current_weight.set(256 - base_extrinsic, DispatchClass::Normal); }); let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); - assert_eq!(BlockWeight::get().total(), info.weight + 256); + assert_eq!(BlockWeight::::get().total(), info.weight + 256); assert!( CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(())) .is_ok() ); assert_eq!( - BlockWeight::get().total(), + BlockWeight::::get().total(), post_info.actual_weight.unwrap() + 256, ); }) @@ -598,14 +598,14 @@ mod tests { }; let len = 0_usize; - BlockWeight::mutate(|current_weight| { + BlockWeight::::mutate(|current_weight| { current_weight.set(0, DispatchClass::Mandatory); current_weight.set(128, DispatchClass::Normal); }); let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!( - BlockWeight::get().total(), + BlockWeight::::get().total(), info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, ); @@ -614,7 +614,7 @@ mod tests { .is_ok() ); assert_eq!( - BlockWeight::get().total(), + BlockWeight::::get().total(), info.weight + 128 + block_weights().get(DispatchClass::Normal).base_extrinsic, ); }) diff --git a/frame/system/src/tests.rs b/frame/system/src/tests.rs index ca91630110366..e477044e009df 100644 --- a/frame/system/src/tests.rs +++ b/frame/system/src/tests.rs @@ -349,7 +349,7 @@ fn set_code_checks_works() { vec![1, 2, 3, 4], ); - assert_eq!(expected.map_err(DispatchError::from), res); + assert_eq!(expected.map_err(DispatchErrorWithPostInfo::from), res); }); } } diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 932aaf43dc9d6..995dcc0a3d466 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -1138,7 +1138,7 @@ mod tests { })); // Killed Event assert!(System::events().iter().any(|event| { - event.event == Event::system(system::RawEvent::KilledAccount(2)) + event.event == Event::system(system::Event::KilledAccount(2)) })); }); } From 73a8225a0471e84c3609bc01ad1bb7d7153a81b7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:24:41 +0000 Subject: [PATCH 30/52] Fix remaining errors and warnings --- bin/node/executor/tests/basic.rs | 10 +++++----- bin/node/executor/tests/fees.rs | 2 +- bin/node/executor/tests/submit_transaction.rs | 1 - frame/system/src/tests.rs | 9 ++++++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 2b644fad2915b..5d045ae852304 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -329,7 +329,7 @@ fn full_native_block_import_works() { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( + event: Event::frame_system(frame_system::Event::ExtrinsicSuccess( DispatchInfo { weight: timestamp_weight, class: DispatchClass::Mandatory, ..Default::default() } )), topics: vec![], @@ -350,7 +350,7 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( + event: Event::frame_system(frame_system::Event::ExtrinsicSuccess( DispatchInfo { weight: transfer_weight, ..Default::default() } )), topics: vec![], @@ -381,7 +381,7 @@ fn full_native_block_import_works() { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( + event: Event::frame_system(frame_system::Event::ExtrinsicSuccess( DispatchInfo { weight: timestamp_weight, class: DispatchClass::Mandatory, ..Default::default() } )), topics: vec![], @@ -404,7 +404,7 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( + event: Event::frame_system(frame_system::Event::ExtrinsicSuccess( DispatchInfo { weight: transfer_weight, ..Default::default() } )), topics: vec![], @@ -427,7 +427,7 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(2), - event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( + event: Event::frame_system(frame_system::Event::ExtrinsicSuccess( DispatchInfo { weight: transfer_weight, ..Default::default() } )), topics: vec![], diff --git a/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index 07460e54680d9..c9bc77c694c99 100644 --- a/bin/node/executor/tests/fees.rs +++ b/bin/node/executor/tests/fees.rs @@ -17,7 +17,7 @@ use codec::{Encode, Joiner}; use frame_support::{ - StorageValue, StorageMap, + StorageValue, traits::Currency, weights::{GetDispatchInfo, constants::ExtrinsicBaseWeight, IdentityFee, WeightToFeePolynomial}, }; diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index f3cb90cbecdd2..4a776b5c15d27 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -217,7 +217,6 @@ fn should_submit_signed_twice_from_all_accounts() { #[test] fn submitted_transaction_should_be_valid() { use codec::Encode; - use frame_support::storage::StorageMap; use sp_runtime::transaction_validity::{TransactionSource, TransactionTag}; use sp_runtime::traits::StaticLookup; diff --git a/frame/system/src/tests.rs b/frame/system/src/tests.rs index e477044e009df..52b12ee091d1f 100644 --- a/frame/system/src/tests.rs +++ b/frame/system/src/tests.rs @@ -18,8 +18,11 @@ use crate::*; use mock::{*, Origin}; use sp_core::H256; -use sp_runtime::{DispatchError, traits::{Header, BlakeTwo256}}; -use frame_support::weights::WithPostDispatchInfo; +use sp_runtime::{DispatchError, DispatchErrorWithPostInfo, traits::{Header, BlakeTwo256}}; +use frame_support::{ + weights::WithPostDispatchInfo, + dispatch::PostDispatchInfo, +}; #[test] fn origin_works() { @@ -327,7 +330,7 @@ fn set_code_checks_works() { ("test", 1, 2, Err(Error::::SpecVersionNeedsToIncrease)), ("test", 1, 1, Err(Error::::SpecVersionNeedsToIncrease)), ("test2", 1, 1, Err(Error::::InvalidSpecName)), - ("test", 2, 1, Ok(())), + ("test", 2, 1, Ok(PostDispatchInfo::default())), ("test", 0, 1, Err(Error::::SpecVersionNeedsToIncrease)), ("test", 1, 0, Err(Error::::SpecVersionNeedsToIncrease)), ]; From 0b48bb182576eabc1067cfc0302807e12996f55f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:28:08 +0000 Subject: [PATCH 31/52] Apply review suggestion: fix formatting Co-authored-by: Guillaume Thiolliere --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index a06ae475d944f..72b4576ade302 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1382,7 +1382,7 @@ impl StoredMap for Module { /// Split an `option` into two constituent options, as defined by a `splitter` function. pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S)) - -> (Option, Option) + -> (Option, Option) { match option { Some(inner) => { From 8fc23c8b80fa7ef7633aee4ca887fff43e33d6f9 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:29:09 +0000 Subject: [PATCH 32/52] Apply review suggestion: annotate BlockLength as constant Co-authored-by: Guillaume Thiolliere --- frame/system/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 72b4576ade302..2de76b7ccdd3d 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -114,6 +114,7 @@ pub mod pallet { type BlockWeights: Get; /// The maximum length of a block (in bytes). + #[pallet::constant] type BlockLength: Get; /// The `Origin` type used by dispatchable calls. From d71ef585f11c95f42278b1b70be7a6c6228b66ae Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:29:31 +0000 Subject: [PATCH 33/52] Apply review suggestion: add triling comma Co-authored-by: Guillaume Thiolliere --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 2de76b7ccdd3d..deb49a7933fbb 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -305,7 +305,7 @@ pub mod pallet { #[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))] pub fn set_code_without_checks( origin: OriginFor, - code: Vec + code: Vec, ) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); From 3f2dc74060e8c43563e0d0d2b66a6f15937402f3 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:29:50 +0000 Subject: [PATCH 34/52] Apply review suggestion: add triling comma Co-authored-by: Guillaume Thiolliere --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index deb49a7933fbb..b6e3340f462a8 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -326,7 +326,7 @@ pub mod pallet { #[pallet::weight((T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational))] pub fn set_changes_trie_config( origin: OriginFor, - changes_trie_config: Option + changes_trie_config: Option, ) -> DispatchResultWithPostInfo { ensure_root(origin)?; match changes_trie_config.clone() { From ba04282733d5c17bc89ea7b046c7435db826afb4 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:30:11 +0000 Subject: [PATCH 35/52] Apply review suggestion: add trailing comma Co-authored-by: Guillaume Thiolliere --- frame/system/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index b6e3340f462a8..c662e26a36524 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -402,7 +402,7 @@ pub mod pallet { pub(crate) fn kill_prefix( origin: OriginFor, prefix: Key, - _subkeys: u32 + _subkeys: u32, ) -> DispatchResultWithPostInfo { ensure_root(origin)?; storage::unhashed::kill_prefix(&prefix); From e46b920c7b7662a3c309dfbed3ea45f7f78dff8a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:32:23 +0000 Subject: [PATCH 36/52] Apply review suggestion: fix storage type indentation --- frame/system/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index c662e26a36524..e242fac130c2c 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -500,13 +500,13 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn block_hash)] pub type BlockHash = - StorageMap<_, Twox64Concat, T::BlockNumber, T::Hash, ValueQuery>; + StorageMap<_, Twox64Concat, T::BlockNumber, T::Hash, ValueQuery>; /// Extrinsics data for the current block (maps an extrinsic's index to its data). #[pallet::storage] #[pallet::getter(fn extrinsic_data)] pub(super) type ExtrinsicData = - StorageMap<_, Twox64Concat, u32, Vec, ValueQuery>; + StorageMap<_, Twox64Concat, u32, Vec, ValueQuery>; /// The current block number being processed. Set by `execute_block`. #[pallet::storage] @@ -527,7 +527,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn events)] pub(super) type Events = - StorageValue<_, Vec>, ValueQuery>; + StorageValue<_, Vec>, ValueQuery>; /// The number of events in the `Events` list. #[pallet::storage] @@ -547,7 +547,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn event_topics)] pub(super) type EventTopics = - StorageMap<_, Blake2_128Concat, T::Hash, Vec<(T::BlockNumber, EventIndex)>, ValueQuery>; + StorageMap<_, Blake2_128Concat, T::Hash, Vec<(T::BlockNumber, EventIndex)>, ValueQuery>; /// Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. #[pallet::storage] From 71e689aee652cfa1219907ceaa8a90d607c6237e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 14 Jan 2021 17:34:18 +0000 Subject: [PATCH 37/52] Apply review suggestion: remove redundant Origin type alias --- frame/system/src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index e242fac130c2c..8cd20cdb03bd2 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -713,9 +713,6 @@ impl From> for RawOrigin { } } -/// Exposed trait-generic origin type. -pub type Origin = RawOrigin<::AccountId>; - // Create a Hash with 69 for each byte, // only used to build genesis config. #[cfg(feature = "std")] From 6aa7b989dd1b7b9bd90ee3d3378ec47de62dad53 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 10:06:54 +0000 Subject: [PATCH 38/52] Add missing codec derives for BlockLength --- frame/system/src/limits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/system/src/limits.rs b/frame/system/src/limits.rs index 3d59bd2b7fa22..c24d671cdd7ab 100644 --- a/frame/system/src/limits.rs +++ b/frame/system/src/limits.rs @@ -29,7 +29,7 @@ use frame_support::weights::{Weight, DispatchClass, constants, PerDispatchClass, use sp_runtime::{RuntimeDebug, Perbill}; /// Block length limit configuration. -#[derive(RuntimeDebug, Clone)] +#[derive(RuntimeDebug, Clone, codec::Encode, codec::Decode)] pub struct BlockLength { /// Maximal total length in bytes for each extrinsic class. /// From aeced3fa283073f67398ca8f808937bcb13f5a94 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 10:23:36 +0000 Subject: [PATCH 39/52] Restore module docs --- frame/system/src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 8cd20cdb03bd2..c5db9b2cbb908 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -15,7 +15,52 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! TODO module docs +//! # System Pallet +//! +//! The System pallet provides low-level access to core types and cross-cutting utilities. +//! It acts as the base layer for other pallets to interact with the Substrate framework components. +//! +//! - [`Config`] +//! +//! ## Overview +//! +//! The System pallet defines the core data types used in a Substrate runtime. +//! It also provides several utility functions (see [`Pallet`]) for other FRAME pallets. +//! +//! In addition, it manages the storage items for extrinsics data, indexes, event records, and digest items, +//! among other things that support the execution of the current block. +//! +//! It also handles low-level tasks like depositing logs, basic set up and take down of +//! temporary storage entries, and access to previous block hashes. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! The System module does not implement any dispatchable functions. +//! +//! ### Public Functions +//! +//! See the [`Pallet`] struct for details of publicly available functions. +//! +//! ### Signed Extensions +//! +//! The System module defines the following extensions: +//! +//! - [`CheckWeight`]: Checks the weight and length of the block and ensure that it does not +//! exceed the limits. +//! - [`CheckNonce`]: Checks the nonce of the transaction. Contains a single payload of type +//! `T::Index`. +//! - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`. +//! - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the +//! signed payload of the transaction. +//! - [`CheckSpecVersion`]: Checks that the runtime version is the same as the one used to sign the +//! transaction. +//! - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign the +//! transaction. +//! +//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed +//! extensions included in a chain. #![cfg_attr(not(feature = "std"), no_std)] From 3949b5af407dc6916cec9f853aecdcb56546de4b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 10:25:03 +0000 Subject: [PATCH 40/52] Module -> Pallet renamel --- frame/system/src/lib.rs | 46 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index c5db9b2cbb908..adae757df32c3 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -37,7 +37,7 @@ //! //! ### Dispatchable Functions //! -//! The System module does not implement any dispatchable functions. +//! The System pallet does not implement any dispatchable functions. //! //! ### Public Functions //! @@ -45,7 +45,7 @@ //! //! ### Signed Extensions //! -//! The System module defines the following extensions: +//! The System pallet defines the following extensions: //! //! - [`CheckWeight`]: Checks the weight and length of the block and ensure that it does not //! exceed the limits. @@ -200,7 +200,7 @@ pub mod pallet { /// /// Used to define the type and conversion mechanism for referencing accounts in transactions. /// It's perfectly reasonable for this to be an identity conversion (with the source type being - /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient + /// `AccountId`), but other pallets (e.g. Indices pallet) may provide more functional/efficient /// alternatives. type Lookup: StaticLookup; @@ -233,7 +233,7 @@ pub mod pallet { type PalletInfo: PalletInfo; /// Data to be associated with an account (other than nonce/transaction counter, which this - /// module does regardless). + /// pallet does regardless). type AccountData: Member + FullCodec + Clone + Default; /// Handler for when a new account has just been created. @@ -284,7 +284,7 @@ pub mod pallet { impl Pallet { /// A dispatch that will fill the block weight up to the given ratio. // TODO: This should only be available for testing, rather than in general usage, but - // that's not possible at present (since it's within the decl_module macro). + // that's not possible at present (since it's within the pallet macro). #[pallet::weight(*_ratio * T::BlockWeights::get().max_block)] pub(crate) fn fill_block(origin: OriginFor, _ratio: Perbill) -> DispatchResultWithPostInfo { ensure_root(origin)?; @@ -475,7 +475,7 @@ pub mod pallet { } } - /// Event for the System module. + /// Event for the System pallet. #[pallet::event] pub enum Event { /// An extrinsic completed successfully. \[info\] @@ -494,7 +494,7 @@ pub mod pallet { #[deprecated(note = "use `Event` instead")] pub type RawEvent = Event; - /// Error for the System module + /// Error for the System pallet #[pallet::error] pub enum Error { /// The name of specification does not match between the current runtime @@ -736,7 +736,7 @@ pub struct EventRecord { pub topics: Vec, } -/// Origin for the System module. +/// Origin for the System pallet. #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode)] pub enum RawOrigin { /// The system itself ordained this dispatch to happen: this is the highest privilege level. @@ -745,7 +745,7 @@ pub enum RawOrigin { Signed(AccountId), /// It is signed by nobody, can be either: /// * included and agreed upon by the validators anyway, - /// * or unsigned transaction validated by a module. + /// * or unsigned transaction validated by a pallet. None, } @@ -781,7 +781,7 @@ pub type RefCount = u32; pub struct AccountInfo { /// The number of transactions this account has sent. pub nonce: Index, - /// The number of other modules that currently depend on this account's existence. The account + /// The number of other pallets that currently depend on this account's existence. The account /// cannot be reaped until this is zero. pub refcount: RefCount, /// The additional data that belongs to this account. Used to store the balance(s) in a lot of @@ -993,7 +993,7 @@ pub enum RefStatus { Unreferenced, } -impl Module { +impl Pallet { /// Deposits an event into this block's event record. pub fn deposit_event(event: impl Into) { Self::deposit_event_indexed(&[], event.into()); @@ -1075,10 +1075,10 @@ impl Module { AllExtrinsicsLen::::get().unwrap_or_default() } - /// Inform the system module of some additional weight that should be accounted for, in the + /// Inform the system pallet of some additional weight that should be accounted for, in the /// current block. /// - /// NOTE: use with extra care; this function is made public only be used for certain modules + /// NOTE: use with extra care; this function is made public only be used for certain pallets /// that need it. A runtime that does not have dynamic calls should never need this and should /// stick to static weights. A typical use case for this is inner calls or smart contract calls. /// Furthermore, it only makes sense to use this when it is presumably _cheap_ to provide the @@ -1183,7 +1183,7 @@ impl Module { >::append(item); } - /// Get the basic externalities for this module, useful for tests. + /// Get the basic externalities for this pallet, useful for tests. #[cfg(any(feature = "std", test))] pub fn externalities() -> TestExternalities { TestExternalities::new(sp_core::storage::Storage { @@ -1284,7 +1284,7 @@ impl Module { } /// To be called immediately after finishing the initialization of the block - /// (e.g., called `on_initialize` for all modules). + /// (e.g., called `on_initialize` for all pallets). pub fn note_finished_initialize() { ExecutionPhase::::put(Phase::ApplyExtrinsic(0)) } @@ -1302,7 +1302,7 @@ impl Module { } /// Remove an account from storage. This should only be done when its refs are zero or you'll - /// get storage leaks in other modules. Nonetheless we assume that the calling logic knows best. + /// get storage leaks in other pallets. Nonetheless we assume that the calling logic knows best. /// /// This is a no-op if the account doesn't already exist. If it does then it will ensure /// cleanups (those in `on_killed_account`) take place. @@ -1316,7 +1316,7 @@ impl Module { ); } } - Module::::on_killed_account(who.clone()); + Pallet::::on_killed_account(who.clone()); } /// Determine whether or not it is possible to update the code. @@ -1346,7 +1346,7 @@ impl Module { pub struct CallOnCreatedAccount(PhantomData); impl Happened for CallOnCreatedAccount { fn happened(who: &T::AccountId) { - Module::::on_created_account(who.clone()); + Pallet::::on_created_account(who.clone()); } } @@ -1354,23 +1354,23 @@ impl Happened for CallOnCreatedAccount { pub struct CallKillAccount(PhantomData); impl Happened for CallKillAccount { fn happened(who: &T::AccountId) { - Module::::kill_account(who) + Pallet::::kill_account(who) } } -impl BlockNumberProvider for Module +impl BlockNumberProvider for Pallet { type BlockNumber = ::BlockNumber; fn current_block_number() -> Self::BlockNumber { - Module::::block_number() + Pallet::::block_number() } } // Implement StoredMap for a simple single-item, kill-account-on-remove system. This works fine for // storing a single item which is required to not be empty/default for the account to exist. // Anything more complex will need more sophisticated logic. -impl StoredMap for Module { +impl StoredMap for Pallet { fn get(k: &T::AccountId) -> T::AccountData { Account::::get(k).data } @@ -1436,7 +1436,7 @@ pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S } } -impl IsDeadAccount for Module { +impl IsDeadAccount for Pallet { fn is_dead_account(who: &T::AccountId) -> bool { !Account::::contains_key(who) } From a3b727f03488b414fc3ec37122198591db036ba5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 10:37:07 +0000 Subject: [PATCH 41/52] Revert "Update frame/support/procedural/src/storage/print_pallet_upgrade.rs" This reverts commit d2a2d5b6 --- frame/support/procedural/src/storage/print_pallet_upgrade.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/frame/support/procedural/src/storage/print_pallet_upgrade.rs index e0eac516442af..9189724d7860f 100644 --- a/frame/support/procedural/src/storage/print_pallet_upgrade.rs +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -324,7 +324,7 @@ pub mod pallet {{ pub struct Pallet{decl_gen}(PhantomData{use_gen_tuple}); #[pallet::hooks] - impl{impl_gen} Hooks> for Pallet{use_gen} + impl{impl_gen} Hooks for Pallet{use_gen} // TODO_MAYBE_WHERE_CLAUSE {{ // TODO_ON_FINALIZE From 0831f0929794df4e007795b401b4b99f98924d74 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 10:42:44 +0000 Subject: [PATCH 42/52] Apply review suggestion: merge crate imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alexander Theißen --- frame/system/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index adae757df32c3..9467d7d3121b5 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -141,9 +141,7 @@ pub use pallet::*; #[frame_support::pallet] pub mod pallet { - use super::*; - use super::pallet_prelude::*; - use crate as frame_system; + use crate::{*, pallet_prelude::*, self as frame_system}; use frame_support::pallet_prelude::*; /// System configuration trait. Implemented by runtime. From 8a0197e6f24084cf1f44be455a3d5b26d7de5d69 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 10:50:05 +0000 Subject: [PATCH 43/52] Revert "Upgrade template rename interface to hooks" This reverts commit 306f0239 --- frame/support/procedural/src/storage/print_pallet_upgrade.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/frame/support/procedural/src/storage/print_pallet_upgrade.rs index 9189724d7860f..100bb9b35913c 100644 --- a/frame/support/procedural/src/storage/print_pallet_upgrade.rs +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -323,8 +323,8 @@ pub mod pallet {{ #[pallet::generate_store({store_vis} trait Store)] pub struct Pallet{decl_gen}(PhantomData{use_gen_tuple}); - #[pallet::hooks] - impl{impl_gen} Hooks for Pallet{use_gen} + #[pallet::interface] + impl{impl_gen} Hooks> for Pallet{use_gen} // TODO_MAYBE_WHERE_CLAUSE {{ // TODO_ON_FINALIZE From 1709098b2d6940e580b11ab03b0c3822e8fab8a8 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 11:16:30 +0000 Subject: [PATCH 44/52] Single line import --- frame/system/src/extensions/check_nonce.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frame/system/src/extensions/check_nonce.rs b/frame/system/src/extensions/check_nonce.rs index f1ea265930c25..9893c5c16203b 100644 --- a/frame/system/src/extensions/check_nonce.rs +++ b/frame/system/src/extensions/check_nonce.rs @@ -17,9 +17,7 @@ use codec::{Encode, Decode}; use crate::Config; -use frame_support::{ - weights::DispatchInfo, -}; +use frame_support::weights::DispatchInfo; use sp_runtime::{ traits::{SignedExtension, DispatchInfoOf, Dispatchable, One}, transaction_validity::{ From 004fa675159d0bb0b27933d937242769ce338e0f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 11:41:23 +0000 Subject: [PATCH 45/52] Refactor generated genesis build --- frame/system/src/lib.rs | 58 +++++++---------------------------------- 1 file changed, 9 insertions(+), 49 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 9467d7d3121b5..70231b980f455 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -624,56 +624,16 @@ pub mod pallet { #[pallet::genesis_build] impl GenesisBuild for GenesisConfig { fn build(&self) { - { - let builder: fn(&Self) -> _ = |_| vec![(T::BlockNumber::zero(), hash69())]; - let data = &builder(self); - let data: &frame_support::sp_std::vec::Vec<(T::BlockNumber, T::Hash)> = data; - data.iter().for_each(|(k, v)| { - as frame_support::storage::StorageMap - >::insert::<&T:: - BlockNumber, &T::Hash>(k, v); - }); - } - { - let builder: fn(&Self) -> _ = |_| hash69(); - let data = &builder(self); - let v: &T::Hash = data; - as frame_support::storage::StorageValue>::put::<&T::Hash>( - v, - ); - } - { - let builder: fn(&Self) -> _ = - |_| Some(LastRuntimeUpgradeInfo::from(T::Version::get())); - let data = builder(self); - let data = Option::as_ref(&data); - let v: Option<&LastRuntimeUpgradeInfo> = data; - if let Some(v) = v { - as frame_support::storage::StorageValue< - LastRuntimeUpgradeInfo, - >>::put::<&LastRuntimeUpgradeInfo>(v); - } + >::insert::<_, T::Hash>(T::BlockNumber::zero(), hash69()); + >::put::(hash69()); + >::put(LastRuntimeUpgradeInfo::from(T::Version::get())); + >::put(true); + + sp_io::storage::set(well_known_keys::CODE, &self.code); + sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); + if let Some(ref changes_trie_config) = self.changes_trie_config { + sp_io::storage::set(well_known_keys::CHANGES_TRIE_CONFIG, &changes_trie_config.encode()); } - { - let builder: fn(&Self) -> _ = |_| true; - let data = &builder(self); - let v: &bool = data; - as frame_support::storage::StorageValue>::put::<&bool>( - v, - ); - } - let extra_genesis_builder: fn(&Self) = |config: &GenesisConfig| { - use codec::Encode; - sp_io::storage::set(well_known_keys::CODE, &config.code); - sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); - if let Some(ref changes_trie_config) = config.changes_trie_config { - sp_io::storage::set( - well_known_keys::CHANGES_TRIE_CONFIG, - &changes_trie_config.encode(), - ); - } - }; - extra_genesis_builder(self); } } } From 455cb43356aa2c4d6a6554091dd548d4bfbefc9b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 11:58:42 +0000 Subject: [PATCH 46/52] Import sp_io::storage --- frame/system/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 70231b980f455..ce44e3b4dfb4f 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -629,10 +629,10 @@ pub mod pallet { >::put(LastRuntimeUpgradeInfo::from(T::Version::get())); >::put(true); - sp_io::storage::set(well_known_keys::CODE, &self.code); - sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); + storage::set(well_known_keys::CODE, &self.code); + storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); if let Some(ref changes_trie_config) = self.changes_trie_config { - sp_io::storage::set(well_known_keys::CHANGES_TRIE_CONFIG, &changes_trie_config.encode()); + storage::set(well_known_keys::CHANGES_TRIE_CONFIG, &changes_trie_config.encode()); } } } From 33476a19a6ae20fc15f679d0c34ca642eee463f5 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 12:02:01 +0000 Subject: [PATCH 47/52] Revert previous, fully qualify sp_io::storage --- frame/system/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index ce44e3b4dfb4f..70231b980f455 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -629,10 +629,10 @@ pub mod pallet { >::put(LastRuntimeUpgradeInfo::from(T::Version::get())); >::put(true); - storage::set(well_known_keys::CODE, &self.code); - storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); + sp_io::storage::set(well_known_keys::CODE, &self.code); + sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); if let Some(ref changes_trie_config) = self.changes_trie_config { - storage::set(well_known_keys::CHANGES_TRIE_CONFIG, &changes_trie_config.encode()); + sp_io::storage::set(well_known_keys::CHANGES_TRIE_CONFIG, &changes_trie_config.encode()); } } } From b994fc7d77f2735c93d5b84a6beeded46f1ff5e7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 15 Jan 2021 15:43:48 +0000 Subject: [PATCH 48/52] Fix ui tests --- .../call_argument_invalid_bound_2.stderr | 39 +++++++++++++++++++ .../pallet_ui/store_trait_leak_private.stderr | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr index e366061b1c25e..86968221cf30c 100644 --- a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr @@ -3,9 +3,48 @@ error[E0277]: the trait bound `pallet::Call: Decode` is not satisfied | 17 | #[pallet::call] | ^^^^ the trait `Decode` is not implemented for `pallet::Call` + | + ::: $WORKSPACE/frame/support/src/dispatch.rs + | + | type Call: UnfilteredDispatchable + Codec + Clone + PartialEq + Eq; + | ----- required by this bound in `frame_support::Callable::Call` error[E0277]: the trait bound `pallet::Call: pallet::_::_parity_scale_codec::Encode` is not satisfied --> $DIR/call_argument_invalid_bound_2.rs:17:12 | 17 | #[pallet::call] | ^^^^ the trait `pallet::_::_parity_scale_codec::Encode` is not implemented for `pallet::Call` + | + ::: $WORKSPACE/frame/support/src/dispatch.rs + | + | type Call: UnfilteredDispatchable + Codec + Clone + PartialEq + Eq; + | ----- required by this bound in `frame_support::Callable::Call` + +error[E0369]: binary operation `==` cannot be applied to type `&::Bar` + --> $DIR/call_argument_invalid_bound_2.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ + | +help: consider further restricting this bound + | +17 | #[pallet::call + std::cmp::PartialEq] + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `::Bar: Clone` is not satisfied + --> $DIR/call_argument_invalid_bound_2.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ the trait `Clone` is not implemented for `::Bar` + | + = note: required by `clone` + +error[E0277]: `::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/call_argument_invalid_bound_2.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ `::Bar` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `::Bar` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&::Bar` + = note: required for the cast to the object type `dyn std::fmt::Debug` diff --git a/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr b/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr index f8ba5ecdc21b3..d8c62faa303ee 100644 --- a/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr +++ b/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr @@ -5,4 +5,4 @@ error[E0446]: private type `_GeneratedPrefixForStorageFoo` in public interfac | ^^^^^ can't leak private type ... 20 | #[pallet::storage] - | - `_GeneratedPrefixForStorageFoo` declared as private + | ------- `_GeneratedPrefixForStorageFoo` declared as private From cb4439dcaa2d76bffeb57ea85f63ec3e3d61338d Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 18 Jan 2021 16:03:11 +0000 Subject: [PATCH 49/52] Fix errors after merge, missing changes --- frame/system/src/lib.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index a42d40068128b..0167d156c7ac3 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -85,7 +85,7 @@ use sp_runtime::{ use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; use frame_support::{ - Parameter, ensure, debug, storage, + Parameter, debug, storage, traits::{ Contains, Get, PalletInfo, OnNewAccount, OnKilledAccount, HandleLifetime, StoredMap, EnsureOrigin, OriginTrait, Filter, @@ -576,6 +576,11 @@ pub mod pallet { #[pallet::storage] pub(super) type UpgradedToU32RefCount = StorageValue<_, bool, ValueQuery>; + /// True if we have upgraded so that AccountInfo contains two types of `RefCount`. False + /// (default) if not. + #[pallet::storage] + pub(super) type UpgradedToDualRefCount = StorageValue<_, bool, ValueQuery>; + /// The execution phase of the block. #[pallet::storage] pub(super) type ExecutionPhase = StorageValue<_, Phase>; @@ -614,6 +619,25 @@ pub mod pallet { } } +mod migrations { + use super::*; + + #[allow(dead_code)] + pub fn migrate_all() -> frame_support::weights::Weight { + Account::::translate::<(T::Index, u8, T::AccountData), _>(|_key, (nonce, rc, data)| + Some(AccountInfo { nonce, consumers: rc as RefCount, providers: 1, data }) + ); + T::BlockWeights::get().max_block + } + + pub fn migrate_to_dual_ref_count() -> frame_support::weights::Weight { + Account::::translate::<(T::Index, RefCount, T::AccountData), _>(|_key, (nonce, rc, data)| + Some(AccountInfo { nonce, consumers: rc as RefCount, providers: 1, data }) + ); + T::BlockWeights::get().max_block + } +} + #[cfg(feature = "std")] impl GenesisConfig { /// Direct implementation of `GenesisBuild::build_storage`. From 3f95d260431b3c107fa3eeaddea1c8287541fe5f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 19 Jan 2021 12:16:34 +0000 Subject: [PATCH 50/52] Set UpgradedToDualRefCount to true in genesis build --- frame/system/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 0167d156c7ac3..eb23b85293341 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -609,6 +609,7 @@ pub mod pallet { >::put::(hash69()); >::put(LastRuntimeUpgradeInfo::from(T::Version::get())); >::put(true); + >::put(true); sp_io::storage::set(well_known_keys::CODE, &self.code); sp_io::storage::set(well_known_keys::EXTRINSIC_INDEX, &0u32.encode()); From aeb9ea1b8187aa93d613659f66e360885ef9d374 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 19 Jan 2021 12:19:19 +0000 Subject: [PATCH 51/52] Annotated Runtime version with constant, exposing it via metadata --- frame/system/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index eb23b85293341..75094f0976ff7 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -219,6 +219,7 @@ pub mod pallet { type DbWeight: Get; /// Get the chain's current version. + #[pallet::constant] type Version: Get; /// Provides information about the pallet setup in the runtime. From 23d42c7d684a1fc3efb74ce36d1bf9dbf1b3ccca Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 20 Jan 2021 10:13:05 +0000 Subject: [PATCH 52/52] Add metadata attribute --- frame/system/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 75094f0976ff7..cdb26623734fd 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -452,6 +452,7 @@ pub mod pallet { /// Event for the System pallet. #[pallet::event] + #[pallet::metadata(T::AccountId = "AccountId")] pub enum Event { /// An extrinsic completed successfully. \[info\] ExtrinsicSuccess(DispatchInfo),