From b67c86690c23f88ec5097ca72ff9a4b1d3c976e9 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 27 Oct 2020 15:49:31 +0100 Subject: [PATCH 01/36] rename system Config to system Trait. command used: ``` find frame/ bin/ test-utils/ utils/ -name *.rs -exec sed -i 's/system::Trait>::/system::Config>::/g' {} \; find frame/ bin/ test-utils/ utils/ -name *.rs -exec sed -i 's/impl frame_system::Trait for /impl frame_system::Config for /g' {} \; find frame/ bin/ test-utils/ utils/ -name *.rs -exec sed -i 's/impl system::Trait for /impl system::Config for /g' {} \; ``` plus some manual ones especially for frame-support tests and frame-system --- bin/node-template/pallets/template/src/lib.rs | 4 +- .../pallets/template/src/mock.rs | 2 +- bin/node-template/runtime/src/lib.rs | 2 +- bin/node/executor/tests/basic.rs | 2 +- bin/node/runtime/src/lib.rs | 4 +- frame/assets/src/lib.rs | 6 +-- frame/atomic-swap/src/lib.rs | 4 +- frame/atomic-swap/src/tests.rs | 2 +- frame/aura/src/mock.rs | 2 +- frame/authority-discovery/src/lib.rs | 2 +- frame/authorship/src/lib.rs | 2 +- frame/babe/src/lib.rs | 4 +- frame/babe/src/mock.rs | 4 +- frame/balances/src/lib.rs | 12 ++--- frame/balances/src/tests.rs | 2 +- frame/balances/src/tests_composite.rs | 2 +- frame/balances/src/tests_local.rs | 2 +- frame/benchmarking/src/tests.rs | 2 +- frame/collective/src/benchmarking.rs | 2 +- frame/collective/src/lib.rs | 12 ++--- frame/contracts/src/exec.rs | 10 ++-- frame/contracts/src/lib.rs | 18 ++++---- frame/contracts/src/tests.rs | 2 +- frame/contracts/src/wasm/runtime.rs | 8 ++-- frame/democracy/src/benchmarking.rs | 2 +- frame/democracy/src/lib.rs | 12 ++--- frame/democracy/src/tests.rs | 4 +- frame/elections-phragmen/src/benchmarking.rs | 2 +- frame/elections-phragmen/src/lib.rs | 10 ++-- frame/elections/src/lib.rs | 8 ++-- frame/elections/src/mock.rs | 2 +- frame/evm/src/lib.rs | 6 +-- frame/evm/src/tests.rs | 2 +- frame/example-offchain-worker/src/lib.rs | 4 +- frame/example-offchain-worker/src/tests.rs | 6 +-- frame/example-parallel/src/lib.rs | 2 +- frame/example-parallel/src/tests.rs | 2 +- frame/example/src/lib.rs | 8 ++-- frame/executive/src/lib.rs | 18 ++++---- frame/grandpa/src/lib.rs | 2 +- frame/grandpa/src/mock.rs | 2 +- frame/identity/src/benchmarking.rs | 14 +++--- frame/identity/src/lib.rs | 8 ++-- frame/identity/src/tests.rs | 2 +- frame/im-online/src/lib.rs | 4 +- frame/im-online/src/mock.rs | 2 +- frame/indices/src/lib.rs | 8 ++-- frame/indices/src/mock.rs | 2 +- frame/membership/src/lib.rs | 6 +-- frame/multisig/src/lib.rs | 8 ++-- frame/multisig/src/tests.rs | 2 +- frame/nicks/src/lib.rs | 10 ++-- frame/node-authorization/src/lib.rs | 6 +-- frame/offences/benchmarking/src/lib.rs | 8 ++-- frame/offences/benchmarking/src/mock.rs | 2 +- frame/offences/src/lib.rs | 6 +-- frame/offences/src/mock.rs | 2 +- frame/proxy/src/benchmarking.rs | 2 +- frame/proxy/src/lib.rs | 10 ++-- frame/proxy/src/tests.rs | 2 +- frame/randomness-collective-flip/src/lib.rs | 2 +- frame/recovery/src/lib.rs | 6 +-- frame/recovery/src/mock.rs | 2 +- frame/scheduler/src/lib.rs | 36 +++++++-------- frame/scored-pool/src/lib.rs | 8 ++-- frame/scored-pool/src/mock.rs | 2 +- frame/session/benchmarking/src/mock.rs | 2 +- frame/session/src/lib.rs | 2 +- frame/session/src/mock.rs | 2 +- frame/society/src/lib.rs | 8 ++-- frame/society/src/mock.rs | 2 +- frame/staking/fuzzer/src/mock.rs | 2 +- frame/staking/src/lib.rs | 38 +++++++-------- frame/staking/src/mock.rs | 2 +- frame/staking/src/tests.rs | 26 +++++------ frame/sudo/src/lib.rs | 4 +- frame/sudo/src/mock.rs | 8 ++-- frame/support/src/dispatch.rs | 46 ++++++++++--------- frame/support/src/event.rs | 24 ++++++---- frame/support/src/lib.rs | 9 ++-- frame/support/src/metadata.rs | 18 +++++--- frame/support/src/origin.rs | 24 +++++----- .../src/storage/generator/double_map.rs | 5 +- frame/support/src/storage/generator/map.rs | 5 +- frame/support/src/storage/generator/mod.rs | 7 ++- frame/support/src/weights.rs | 7 ++- frame/support/test/src/lib.rs | 6 ++- frame/support/test/tests/construct_runtime.rs | 8 ++-- frame/support/test/tests/decl_storage.rs | 8 ++-- frame/support/test/tests/genesisconfig.rs | 2 +- frame/support/test/tests/instance.rs | 14 +++--- frame/support/test/tests/issue2219.rs | 6 +-- frame/support/test/tests/pallet_version.rs | 6 +-- .../support/test/tests/storage_transaction.rs | 2 +- frame/support/test/tests/system.rs | 10 ++-- frame/system/benches/bench.rs | 4 +- frame/system/benchmarking/src/mock.rs | 2 +- frame/system/src/extensions/check_genesis.rs | 4 +- .../src/extensions/check_spec_version.rs | 4 +- .../system/src/extensions/check_tx_version.rs | 4 +- frame/system/src/extensions/check_weight.rs | 40 ++++++++-------- frame/system/src/lib.rs | 17 ++++--- frame/system/src/mock.rs | 8 ++-- frame/timestamp/src/lib.rs | 2 +- frame/transaction-payment/src/lib.rs | 14 +++--- frame/transaction-payment/src/payment.rs | 12 ++--- frame/treasury/src/lib.rs | 12 ++--- frame/treasury/src/tests.rs | 2 +- frame/utility/src/benchmarking.rs | 2 +- frame/utility/src/lib.rs | 2 +- frame/utility/src/tests.rs | 4 +- frame/vesting/src/benchmarking.rs | 2 +- frame/vesting/src/lib.rs | 10 ++-- test-utils/runtime/src/lib.rs | 2 +- utils/frame/rpc/support/src/lib.rs | 2 +- 115 files changed, 430 insertions(+), 386 deletions(-) diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index 729a71278aa9f..d2c27cd3d2a58 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -16,7 +16,7 @@ mod tests; /// Configure the pallet by specifying the parameters and types on which it depends. pub trait Trait: frame_system::Trait { /// Because this pallet emits events, it depends on the runtime's definition of an event. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } // The pallet's runtime storage items. @@ -35,7 +35,7 @@ decl_storage! { // Pallets use events to inform users when important changes are made. // https://substrate.dev/docs/en/knowledgebase/runtime/events decl_event!( - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// Event documentation should end with an array that provides descriptive names for event /// parameters. [something, who] SomethingStored(u32, AccountId), diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index a3dff240e4847..3adf313f0dd17 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -21,7 +21,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } -impl system::Trait for Test { +impl system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index d67a5bde96457..c59c5ef3bebcf 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -140,7 +140,7 @@ parameter_types! { // Configure FRAME pallets to include in runtime. -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { /// The basic call filter to use in dispatchable. type BaseCallFilter = (); /// The identifier used to distinguish between accounts. diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 723e3a7e4ba62..023be601d5925 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -581,7 +581,7 @@ const CODE_TRANSFER: &str = r#" #[test] fn deploying_wasm_contract_should_work() { let transfer_code = wat::parse_str(CODE_TRANSFER).unwrap(); - let transfer_ch = ::Hashing::hash(&transfer_code); + let transfer_ch = ::Hashing::hash(&transfer_code); let addr = ::DetermineContractAddress::contract_address_for( &transfer_ch, diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index bfa412e882031..446fdca8b0828 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -156,7 +156,7 @@ parameter_types! { const_assert!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct()); -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Call = Call; @@ -401,7 +401,7 @@ parameter_types! { impl pallet_session::Trait for Runtime { type Event = Event; - type ValidatorId = ::AccountId; + type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_staking::StashOf; type ShouldEndSession = Babe; type NextSessionRotation = Babe; diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index e5ad2ae352eb8..230aca1a0e067 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -141,7 +141,7 @@ use sp_runtime::traits::One; /// The module configuration trait. pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The units in which we record balances. type Balance: Member + Parameter + AtLeast32BitUnsigned + Default + Copy; @@ -226,7 +226,7 @@ decl_module! { decl_event! { pub enum Event where - ::AccountId, + ::AccountId, ::Balance, ::AssetId, { @@ -298,7 +298,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/atomic-swap/src/lib.rs b/frame/atomic-swap/src/lib.rs index 31f0c0f426525..cf91098b07941 100644 --- a/frame/atomic-swap/src/lib.rs +++ b/frame/atomic-swap/src/lib.rs @@ -138,7 +138,7 @@ impl SwapAction for BalanceSwapAction> + Into<::Event>; + type Event: From> + Into<::Event>; /// Swap action. type SwapAction: SwapAction + Parameter; /// Limit of proof size. @@ -186,7 +186,7 @@ decl_error! { decl_event!( /// Event of atomic swap pallet. pub enum Event where - AccountId = ::AccountId, + AccountId = ::AccountId, PendingSwap = PendingSwap, { /// Swap created. \[account, proof, swap\] diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs index 060411c8815da..55c73cfb3c068 100644 --- a/frame/atomic-swap/src/tests.rs +++ b/frame/atomic-swap/src/tests.rs @@ -24,7 +24,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index a3875727e47c2..f78c00b701c99 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -45,7 +45,7 @@ parameter_types! { pub const MinimumPeriod: u64 = 1; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 09be533474fca..b571c1e8c2e3d 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -143,7 +143,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 0a10c8849571b..492b96e0238dd 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -417,7 +417,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 8cab698fda093..db37a5c2fe208 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -311,7 +311,7 @@ decl_module! { } } -impl RandomnessT<::Hash> for Module { +impl RandomnessT<::Hash> for Module { /// Some BABE blocks have VRF outputs where the block producer has exactly one bit of influence, /// either they make the block or they do not make the block and thus someone else makes the /// next block. Yet, this randomness is not fresh in all BABE blocks. @@ -332,7 +332,7 @@ impl RandomnessT<::Hash> for Module { subject.reserve(VRF_OUTPUT_LENGTH); subject.extend_from_slice(&Self::randomness()[..]); - ::Hashing::hash(&subject[..]) + ::Hashing::hash(&subject[..]) } } diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 9f00a4ddfc3cd..3ec59d5f267fa 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -65,7 +65,7 @@ parameter_types! { pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -109,7 +109,7 @@ impl_opaque_keys! { impl pallet_session::Trait for Test { type Event = (); - type ValidatorId = ::AccountId; + type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_staking::StashOf; type ShouldEndSession = Babe; type NextSessionRotation = Babe; diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 141a360f7e180..758d85dea172b 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -103,8 +103,8 @@ //! # type Currency: Currency; //! # } //! -//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +//! pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +//! pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; //! //! # fn main() {} //! ``` @@ -118,8 +118,8 @@ //! type Currency: LockableCurrency; //! } //! # struct StakingLedger { -//! # stash: ::AccountId, -//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, +//! # stash: ::AccountId, +//! # total: <::Currency as frame_support::traits::Currency<::AccountId>>::Balance, //! # phantom: std::marker::PhantomData, //! # } //! # const STAKING_ID: [u8; 8] = *b"staking "; @@ -207,7 +207,7 @@ pub trait Trait: frame_system::Trait { type DustRemoval: OnUnbalanced>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The minimum amount required to keep an account open. type ExistentialDeposit: Get; @@ -233,7 +233,7 @@ impl, I: Instance> Subtrait for T { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, >::Balance { /// An account was created with some free balance. \[account, free_balance\] diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index b8cf90dad9222..4dc9ddc45fd16 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -55,7 +55,7 @@ macro_rules! decl_tests { pub type System = frame_system::Module<$test>; pub type Balances = Module<$test>; - pub const CALL: &<$test as frame_system::Trait>::Call = &$crate::tests::CallWithDispatchInfo; + pub const CALL: &<$test as frame_system::Config>::Call = &$crate::tests::CallWithDispatchInfo; /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 88b73b47273eb..42b773698c256 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -67,7 +67,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index 319fb3640b4c7..ecde6ba9b964e 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -67,7 +67,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 0429d98e18618..6653b597d2b42 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -72,7 +72,7 @@ pub trait Trait: frame_system::Trait + OtherTrait #[derive(Clone, Eq, PartialEq)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index d4e80d515941f..1383e2ab29ec5 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -35,7 +35,7 @@ const MAX_BYTES: u32 = 1_024; fn assert_last_event, I: Instance>(generic_event: >::Event) { let events = System::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index b7d561672b82f..6d3e37f2e0b18 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -132,7 +132,7 @@ pub trait Trait: frame_system::Trait { + GetDispatchInfo; /// The outer event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The time-out for council motions. type MotionDuration: Get; @@ -166,7 +166,7 @@ pub enum RawOrigin { } /// Origin for the collective module. -pub type Origin = RawOrigin<::AccountId, I>; +pub type Origin = RawOrigin<::AccountId, I>; #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] /// Info for keeping track of a motion being voted on. @@ -209,8 +209,8 @@ decl_storage! { decl_event! { pub enum Event where - ::Hash, - ::AccountId, + ::Hash, + ::AccountId, { /// A motion (given hash) has been proposed (by given account) with a threshold (given /// `MemberCount`). @@ -276,7 +276,7 @@ fn get_result_weight(result: DispatchResultWithPostInfo) -> Option { // Note that councillor operations are assigned to the operational class. decl_module! { - pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { + pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { type Error = Error; fn deposit_event() = default; @@ -952,7 +952,7 @@ mod tests { pub const MaxProposals: u32 = 100; pub const MaxMembers: u32 = 100; } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index f93f262d821e9..b772c15c7c9d6 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -29,14 +29,14 @@ use frame_support::{ }; use pallet_contracts_primitives::{ErrorOrigin, ExecError, ExecReturnValue, ExecResult, ReturnFlags}; -pub type AccountIdOf = ::AccountId; +pub type AccountIdOf = ::AccountId; pub type MomentOf = <::Time as Time>::Moment; -pub type SeedOf = ::Hash; -pub type BlockNumberOf = ::BlockNumber; +pub type SeedOf = ::Hash; +pub type BlockNumberOf = ::BlockNumber; pub type StorageKey = [u8; 32]; /// A type that represents a topic of an event. At the moment a hash is used. -pub type TopicOf = ::Hash; +pub type TopicOf = ::Hash; /// Describes whether we deal with a contract or a plain account. pub enum TransactorKind { @@ -770,7 +770,7 @@ mod tests { fn insert(&mut self, f: impl Fn(MockCtx) -> ExecResult + 'a) -> CodeHash { // Generate code hashes as monotonically increasing values. - let code_hash = ::Hash::from_low_u64_be(self.counter); + let code_hash = ::Hash::from_low_u64_be(self.counter); self.counter += 1; self.map.insert(code_hash, MockExecutable::new(f)); diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index f43bfd0ebdb6f..6ecb659593f7c 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -122,7 +122,7 @@ use pallet_contracts_primitives::{ }; use frame_support::weights::Weight; -pub type CodeHash = ::Hash; +pub type CodeHash = ::Hash; pub type TrieId = Vec; /// A function that generates an `AccountId` for a contract upon instantiation. @@ -191,7 +191,7 @@ impl ContractInfo { } pub type AliveContractInfo = - RawAliveContractInfo, BalanceOf, ::BlockNumber>; + RawAliveContractInfo, BalanceOf, ::BlockNumber>; /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account. @@ -231,7 +231,7 @@ pub(crate) fn child_trie_info(trie_id: &[u8]) -> ChildInfo { } pub type TombstoneContractInfo = - RawTombstoneContractInfo<::Hash, ::Hashing>; + RawTombstoneContractInfo<::Hash, ::Hashing>; #[derive(Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct RawTombstoneContractInfo(H, PhantomData); @@ -294,9 +294,9 @@ where } pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; pub type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; parameter_types! { /// A reasonable default value for [`Trait::SignedClaimedHandicap`]. @@ -325,7 +325,7 @@ pub trait Trait: frame_system::Trait { type Currency: Currency; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// A function type to get the contract address given the instantiator. type DetermineContractAddress: ContractAddressFor, Self::AccountId>; @@ -460,7 +460,7 @@ decl_error! { decl_module! { /// Contracts module. - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { type Error = Error; /// Number of block delay an extrinsic claim surcharge has. @@ -694,8 +694,8 @@ decl_event! { pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash + ::AccountId, + ::Hash { /// Contract deployed by address at the specified address. \[owner, contract\] Instantiated(AccountId, AccountId), diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index c2d9ed6642559..3084e3e56d320 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -116,7 +116,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index c7de93ece70ff..b192880ddd9cd 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -660,7 +660,7 @@ define_env!(Env, , value_len: u32 ) -> ReturnCode => { charge_gas(ctx, RuntimeToken::Transfer)?; - let callee: <::T as frame_system::Trait>::AccountId = + let callee: <::T as frame_system::Config>::AccountId = read_sandbox_memory_as(ctx, account_ptr, account_len)?; let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; @@ -713,7 +713,7 @@ define_env!(Env, , output_len_ptr: u32 ) -> ReturnCode => { charge_gas(ctx, RuntimeToken::CallBase(input_data_len))?; - let callee: <::T as frame_system::Trait>::AccountId = + let callee: <::T as frame_system::Config>::AccountId = read_sandbox_memory_as(ctx, callee_ptr, callee_len)?; let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; let input_data = read_sandbox_memory(ctx, input_data_ptr, input_data_len)?; @@ -867,7 +867,7 @@ define_env!(Env, , beneficiary_len: u32 ) => { charge_gas(ctx, RuntimeToken::Terminate)?; - let beneficiary: <::T as frame_system::Trait>::AccountId = + let beneficiary: <::T as frame_system::Config>::AccountId = read_sandbox_memory_as(ctx, beneficiary_ptr, beneficiary_len)?; if let Ok(_) = ctx.ext.terminate(&beneficiary) { @@ -1118,7 +1118,7 @@ define_env!(Env, , delta_count: u32 ) => { charge_gas(ctx, RuntimeToken::RestoreTo(delta_count))?; - let dest: <::T as frame_system::Trait>::AccountId = + let dest: <::T as frame_system::Config>::AccountId = read_sandbox_memory_as(ctx, dest_ptr, dest_len)?; let code_hash: CodeHash<::T> = read_sandbox_memory_as(ctx, code_hash_ptr, code_hash_len)?; diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index b5de1a91c17ad..974abcee94141 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -36,7 +36,7 @@ const MAX_BYTES: u32 = 16_384; fn assert_last_event(generic_event: ::Event) { let events = System::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index fa8d07fd78db7..eaf1d161a327a 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -199,13 +199,13 @@ pub type PropIndex = u32; /// A referendum index. pub type ReferendumIndex = u32; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: frame_system::Trait + Sized { type Proposal: Parameter + Dispatchable + From>; - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Currency type for this module. type Currency: ReservableCurrency @@ -413,9 +413,9 @@ decl_storage! { decl_event! { pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash, - ::BlockNumber, + ::AccountId, + ::Hash, + ::BlockNumber, { /// A motion has been proposed by a public account. \[proposal_index, deposit\] Proposed(PropIndex, Balance), diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index bcc7099bb34a4..9a2280ece68c9 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -93,7 +93,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = BaseFilter; type Origin = Origin; type Index = u64; @@ -252,7 +252,7 @@ fn set_balance_proposal(value: u64) -> Vec { fn set_balance_proposal_is_correctly_filtered_out() { for i in 0..10 { let call = Call::decode(&mut &set_balance_proposal(i)[..]).unwrap(); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); } } diff --git a/frame/elections-phragmen/src/benchmarking.rs b/frame/elections-phragmen/src/benchmarking.rs index e7c3719480b70..d6a2399312d29 100644 --- a/frame/elections-phragmen/src/benchmarking.rs +++ b/frame/elections-phragmen/src/benchmarking.rs @@ -30,7 +30,7 @@ const BALANCE_FACTOR: u32 = 250; const MAX_VOTERS: u32 = 500; const MAX_CANDIDATES: u32 = 200; -type Lookup = <::Lookup as StaticLookup>::Source; +type Lookup = <::Lookup as StaticLookup>::Source; macro_rules! whitelist { ($acc:ident) => { diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index be47b5adcce5e..fed727b11c5c8 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -112,9 +112,9 @@ pub use weights::WeightInfo; pub const MAXIMUM_VOTE: usize = 16; type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; /// An indication that the renouncing account currently has which of the below roles. #[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug)] @@ -142,7 +142,7 @@ pub struct DefunctVoter { pub trait Trait: frame_system::Trait { /// The overarching event type.c - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Identifier for the elections-phragmen pallet's lock type ModuleId: Get; @@ -667,7 +667,7 @@ decl_module! { decl_event!( pub enum Event where Balance = BalanceOf, - ::AccountId, + ::AccountId, { /// A new term with \[new_members\]. This indicates that enough candidates existed to run the /// election, not that enough have has been elected. The inner value must be examined for @@ -1077,7 +1077,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index dccc42f24417b..5e4fb010265c2 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -139,9 +139,9 @@ pub const VOTER_SET_SIZE: usize = 64; /// NUmber of approvals grouped in one chunk. pub const APPROVAL_SET_SIZE: usize = 8; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; /// Index used to access chunks. type SetIndex = u32; @@ -153,7 +153,7 @@ type ApprovalFlag = u32; const APPROVAL_FLAG_LEN: usize = 32; pub trait Trait: frame_system::Trait { - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Identifier for the elections pallet's lock type ModuleId: Get; @@ -706,7 +706,7 @@ decl_module! { } decl_event!( - pub enum Event where ::AccountId { + pub enum Event where ::AccountId { /// Reaped \[voter, reaper\]. VoterReaped(AccountId, AccountId), /// Slashed \[reaper\]. diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index deec77da7b837..939446e3b7c50 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -38,7 +38,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = Call; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index e7812a55482fd..a4919b787702b 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -79,7 +79,7 @@ use evm::executor::StackExecutor; use evm::backend::ApplyBackend; /// Type alias for currency balance. -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Trait that outputs the current transaction gas price. pub trait FeeCalculator { @@ -236,7 +236,7 @@ pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { type Currency: Currency; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Precompiles associated with this EVM engine. type Precompiles: Precompiles; /// Chain ID of EVM. @@ -290,7 +290,7 @@ decl_storage! { decl_event! { /// EVM events pub enum Event where - ::AccountId, + ::AccountId, { /// Ethereum events from contracts. Log(Log), diff --git a/frame/evm/src/tests.rs b/frame/evm/src/tests.rs index d05fdca1407e5..f53bf32cb68f1 100644 --- a/frame/evm/src/tests.rs +++ b/frame/evm/src/tests.rs @@ -31,7 +31,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index b64e3f8dd83f5..8f9dceda10326 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -108,7 +108,7 @@ pub trait Trait: CreateSignedTransaction> { type AuthorityId: AppCrypto; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching dispatch call type. type Call: From>; @@ -165,7 +165,7 @@ decl_storage! { decl_event!( /// Events generated by the module. - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// Event generated when new price is accepted to contribute to the average. /// \[price, who\] NewPrice(u32, AccountId), diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index 204b366964f47..31a77cc055bcb 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -56,7 +56,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); @@ -282,7 +282,7 @@ fn should_submit_unsigned_transaction_on_chain_for_any_account() { let signature_valid = ::Public, - ::BlockNumber + ::BlockNumber > as SignedPayload>::verify::(&price_payload, signature); assert!(signature_valid); @@ -335,7 +335,7 @@ fn should_submit_unsigned_transaction_on_chain_for_all_accounts() { let signature_valid = ::Public, - ::BlockNumber + ::BlockNumber > as SignedPayload>::verify::(&price_payload, signature); assert!(signature_valid); diff --git a/frame/example-parallel/src/lib.rs b/frame/example-parallel/src/lib.rs index 4b7ce72b4d40e..78fdece6a2033 100644 --- a/frame/example-parallel/src/lib.rs +++ b/frame/example-parallel/src/lib.rs @@ -36,7 +36,7 @@ mod tests; pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// The overarching dispatch call type. type Call: From>; } diff --git a/frame/example-parallel/src/tests.rs b/frame/example-parallel/src/tests.rs index 1da8c60388266..78481f5bdaf67 100644 --- a/frame/example-parallel/src/tests.rs +++ b/frame/example-parallel/src/tests.rs @@ -39,7 +39,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 103bcfe696868..293d51e6a6c91 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -322,7 +322,7 @@ type BalanceOf = ::Balance; /// `frame_system::Trait` should always be included in our implied traits. pub trait Trait: pallet_balances::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } decl_storage! { @@ -612,11 +612,11 @@ impl sp_std::fmt::Debug for WatchDummy { impl SignedExtension for WatchDummy where - ::Call: IsSubType>, + ::Call: IsSubType>, { const IDENTIFIER: &'static str = "WatchDummy"; type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = (); type Pre = (); @@ -744,7 +744,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index ccb5c2d262871..c3ab029e34c68 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -594,7 +594,7 @@ mod tests { write: 100, }; } - impl frame_system::Trait for Runtime { + impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -668,8 +668,8 @@ mod tests { type TestXt = sp_runtime::testing::TestXt; type TestBlock = Block; type TestUncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic< - ::AccountId, - ::Call, + ::AccountId, + ::Call, (), SignedExtra, >; @@ -715,7 +715,7 @@ mod tests { balances: vec![(1, 211)], }.assimilate_storage(&mut t).unwrap(); let xt = TestXt::new(Call::Balances(BalancesCall::transfer(2, 69)), sign_extra(1, 0, 0)); - let weight = xt.get_dispatch_info().weight + ::ExtrinsicBaseWeight::get(); + let weight = xt.get_dispatch_info().weight + ::ExtrinsicBaseWeight::get(); let fee: Balance = ::WeightToFee::calc(&weight); let mut t = sp_io::TestExternalities::new(t); @@ -818,7 +818,7 @@ mod tests { let encoded = xt.encode(); let encoded_len = encoded.len() as Weight; // on_initialize weight + block execution weight - let base_block_weight = 175 + ::BlockExecutionWeight::get(); + let base_block_weight = 175 + ::BlockExecutionWeight::get(); let limit = AvailableBlockRatio::get() * MaximumBlockWeight::get() - base_block_weight; let num_to_exhaust_block = limit / (encoded_len + 5); t.execute_with(|| { @@ -861,7 +861,7 @@ mod tests { let mut t = new_test_ext(1); t.execute_with(|| { // Block execution weight + on_initialize weight from custom module - let base_block_weight = 175 + ::BlockExecutionWeight::get(); + let base_block_weight = 175 + ::BlockExecutionWeight::get(); Executive::initialize_block(&Header::new( 1, @@ -879,7 +879,7 @@ mod tests { assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); // default weight for `TestXt` == encoded length. - let extrinsic_weight = len as Weight + ::ExtrinsicBaseWeight::get(); + let extrinsic_weight = len as Weight + ::ExtrinsicBaseWeight::get(); assert_eq!( >::block_weight().total(), base_block_weight + 3 * extrinsic_weight, @@ -946,7 +946,7 @@ mod tests { sign_extra(1, 0, 0), ); let weight = xt.get_dispatch_info().weight - + ::ExtrinsicBaseWeight::get(); + + ::ExtrinsicBaseWeight::get(); let fee: Balance = ::WeightToFee::calc(&weight); Executive::initialize_block(&Header::new( @@ -1106,7 +1106,7 @@ mod tests { let runtime_upgrade_weight = ::on_runtime_upgrade(); let frame_system_on_initialize_weight = frame_system::Module::::on_initialize(block_number); let on_initialize_weight = >::on_initialize(block_number); - let base_block_weight = ::BlockExecutionWeight::get(); + let base_block_weight = ::BlockExecutionWeight::get(); // Weights are recorded correctly assert_eq!( diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index fe836ac913cb6..80b0d29168c35 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -69,7 +69,7 @@ pub use equivocation::{ pub trait Trait: frame_system::Trait { /// The event type of this module. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// The function call. type Call: From>; diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index d3461eec12dc4..e7f5e80c7e2e1 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -79,7 +79,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index d7876514452e2..36335608a6002 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -31,7 +31,7 @@ const SEED: u32 = 0; fn assert_last_event(generic_event: ::Event) { let events = frame_system::Module::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); @@ -121,7 +121,7 @@ benchmarks! { // Create their main identity with x additional fields let info = create_identity_info::(x); let caller: T::AccountId = whitelisted_caller(); - let caller_origin = ::Origin::from(RawOrigin::Signed(caller)); + let caller_origin = ::Origin::from(RawOrigin::Signed(caller)); Identity::::set_identity(caller_origin, info)?; }; } @@ -143,7 +143,7 @@ benchmarks! { // The target user let caller: T::AccountId = whitelisted_caller(); let caller_lookup: ::Source = T::Lookup::unlookup(caller.clone()); - let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); // Add an initial identity @@ -200,7 +200,7 @@ benchmarks! { clear_identity { let caller: T::AccountId = whitelisted_caller(); - let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); + let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); let caller_lookup = ::unlookup(caller.clone()); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); @@ -237,7 +237,7 @@ benchmarks! { cancel_request { let caller: T::AccountId = whitelisted_caller(); - let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); + let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); let r in ...; @@ -300,7 +300,7 @@ benchmarks! { provide_judgement { // The user let user: T::AccountId = account("user", r, SEED); - let user_origin = ::Origin::from(RawOrigin::Signed(user.clone())); + let user_origin = ::Origin::from(RawOrigin::Signed(user.clone())); let user_lookup = ::unlookup(user.clone()); let _ = T::Currency::make_free_balance_be(&user, BalanceOf::::max_value()); @@ -328,7 +328,7 @@ benchmarks! { let x in _ .. _ => {}; let target: T::AccountId = account("target", 0, SEED); - let target_origin: ::Origin = RawOrigin::Signed(target.clone()).into(); + let target_origin: ::Origin = RawOrigin::Signed(target.clone()).into(); let target_lookup: ::Source = T::Lookup::unlookup(target.clone()); let _ = T::Currency::make_free_balance_be(&target, BalanceOf::::max_value()); diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 0ee6563a5611d..0e139282882d5 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -91,12 +91,12 @@ use frame_support::{ use frame_system::ensure_signed; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency trait. type Currency: ReservableCurrency; @@ -428,7 +428,7 @@ decl_storage! { } decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// A name was set or reset (which will remove all judgements). \[who\] IdentitySet(AccountId), /// A name was cleared, and the given balance returned. \[who, deposit\] diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index 0637ac6aafc5f..e69b5db03e826 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -42,7 +42,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 2d3693d127207..61bfb879cab60 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -232,7 +232,7 @@ pub trait Trait: SendTransactionTypes> + pallet_session::historical:: type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// An expected duration of the session. /// @@ -393,7 +393,7 @@ decl_module! { } } -type OffchainResult = Result::BlockNumber>>; +type OffchainResult = Result::BlockNumber>>; /// Keep track of number of authored blocks per authority, uncles are counted as /// well since they're a valid proof of being online. diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index dae4bb3447e56..e25df03a6adfa 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -109,7 +109,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index fd2eb956f9231..cf7578e1f6fc6 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -38,8 +38,8 @@ use frame_system::{ensure_signed, ensure_root}; use self::address::Address as RawAddress; pub use weights::WeightInfo; -pub type Address = RawAddress<::AccountId, ::AccountIndex>; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type Address = RawAddress<::AccountId, ::AccountIndex>; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// The module's config trait. pub trait Trait: frame_system::Trait { @@ -54,7 +54,7 @@ pub trait Trait: frame_system::Trait { type Deposit: Get>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; @@ -77,7 +77,7 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, ::AccountIndex { /// A account index was assigned. \[index, who\] diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index cfbd2e38c3d3f..b145569411fa8 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -49,7 +49,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = (); diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 492fda88dd170..7956730ce391a 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -32,7 +32,7 @@ use frame_system::ensure_signed; pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Required origin for adding a member (though can always be Root). type AddOrigin: EnsureOrigin; @@ -80,7 +80,7 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, >::Event, { /// The given member was added; see the transaction for who. @@ -299,7 +299,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs index 873508259a8d7..02bd287186ab0 100644 --- a/frame/multisig/src/lib.rs +++ b/frame/multisig/src/lib.rs @@ -62,14 +62,14 @@ use frame_system::{self as system, ensure_signed, RawOrigin}; use sp_runtime::{DispatchError, DispatchResult, traits::{Dispatchable, Zero}}; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Just a bunch of bytes, but they should decode to a valid `Call`. pub type OpaqueCall = Vec; /// Configuration trait. pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable @@ -169,8 +169,8 @@ decl_error! { decl_event! { /// Events type. pub enum Event where - AccountId = ::AccountId, - BlockNumber = ::BlockNumber, + AccountId = ::AccountId, + BlockNumber = ::BlockNumber, CallHash = [u8; 32] { /// A new multisig operation has begun. \[approving, multisig, call_hash\] diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index ca15e04597eaa..c78aef67ca3de 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -59,7 +59,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = TestBaseCallFilter; type Origin = Origin; type Index = u64; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index ddeadfb7680fe..fdabc5e0ca3be 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -51,12 +51,12 @@ use frame_support::{ }; use frame_system::ensure_signed; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency trait. type Currency: ReservableCurrency; @@ -85,7 +85,7 @@ decl_storage! { } decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// A name was set. \[who\] NameSet(AccountId), /// A name was forcibly set. \[target\] @@ -262,7 +262,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 91f89ad1d9100..35891790bc895 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -78,7 +78,7 @@ impl WeightInfo for () { pub trait Trait: frame_system::Trait { /// The event type of this module. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The maximum number of well known nodes that are allowed to set type MaxWellKnownNodes: Get; @@ -123,7 +123,7 @@ decl_storage! { decl_event! { pub enum Event where - ::AccountId, + ::AccountId, { /// The given well known node was added. NodeAdded(PeerId, AccountId), @@ -453,7 +453,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index 47055eab73d4a..3e250f1158150 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -24,7 +24,7 @@ mod mock; use sp_std::prelude::*; use sp_std::vec; -use frame_system::{RawOrigin, Module as System, Trait as SystemTrait}; +use frame_system::{RawOrigin, Module as System, Config as SystemConfig}; use frame_benchmarking::{benchmarks, account}; use frame_support::traits::{Currency, OnInitialize}; @@ -77,8 +77,8 @@ impl IdTupleConvert for T where } } -type LookupSourceOf = <::Lookup as StaticLookup>::Source; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type LookupSourceOf = <::Lookup as StaticLookup>::Source; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; struct Offender { pub controller: T::AccountId, @@ -176,7 +176,7 @@ fn make_offenders(num_offenders: u32, num_nominators: u32) -> Result< } #[cfg(test)] -fn check_events::Event>>(expected: I) { +fn check_events::Event>>(expected: I) { let events = System::::events() .into_iter() .map(|frame_system::EventRecord { event, .. }| event).collect::>(); let expected = expected.collect::>(); diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 527e0ede81ab9..79022333b4928 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -40,7 +40,7 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index e72498273cec0..609dddd670508 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -42,11 +42,11 @@ use codec::{Encode, Decode}; type OpaqueTimeSlot = Vec; /// A type alias for a report identifier. -type ReportIdOf = ::Hash; +type ReportIdOf = ::Hash; /// Type of data stored as a deferred offence pub type DeferredOffenceOf = ( - Vec::AccountId, ::IdentificationTuple>>, + Vec::AccountId, ::IdentificationTuple>>, Vec, SessionIndex, ); @@ -68,7 +68,7 @@ impl WeightInfo for () { /// Offences trait pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// Full identification of the validator. type IdentificationTuple: Parameter + Ord; /// A handler called for every offence report. diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 58ee97a9bcbb5..fee2b65e56c79 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -95,7 +95,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/proxy/src/benchmarking.rs b/frame/proxy/src/benchmarking.rs index 5f1d79741dd8e..4262bed46070d 100644 --- a/frame/proxy/src/benchmarking.rs +++ b/frame/proxy/src/benchmarking.rs @@ -29,7 +29,7 @@ const SEED: u32 = 0; fn assert_last_event(generic_event: ::Event) { let events = frame_system::Module::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs index 75ab3902dc8db..45fbb199fb91e 100644 --- a/frame/proxy/src/lib.rs +++ b/frame/proxy/src/lib.rs @@ -55,17 +55,17 @@ use frame_system::{self as system, ensure_signed}; use frame_support::dispatch::DispatchError; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Configuration trait. pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable + GetDispatchInfo + From> + IsSubType> - + IsType<::Call>; + + IsType<::Call>; /// The currency mechanism. type Currency: ReservableCurrency; @@ -174,7 +174,7 @@ decl_error! { decl_event! { /// Events type. pub enum Event where - AccountId = ::AccountId, + AccountId = ::AccountId, ProxyType = ::ProxyType, Hash = CallHashOf, { @@ -684,7 +684,7 @@ impl Module { ) { // This is a freshly authenticated new account, the origin restrictions doesn't apply. let mut origin: T::Origin = frame_system::RawOrigin::Signed(real).into(); - origin.add_filter(move |c: &::Call| { + origin.add_filter(move |c: &::Call| { let c = ::Call::from_ref(c); // We make sure the proxy call does access this pallet to change modify proxies. match c.is_sub_type() { diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index bcf3b678ed644..c47dd4e0b8a9e 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -61,7 +61,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = BaseFilter; type Origin = Origin; type Index = u64; diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index c1747669dab07..33bcd941b2d2a 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -157,7 +157,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index c97824497fded..8b4091d238641 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -172,12 +172,12 @@ mod mock; mod tests; type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; /// Configuration trait. pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable + GetDispatchInfo; @@ -262,7 +262,7 @@ decl_storage! { decl_event! { /// Events type. pub enum Event where - AccountId = ::AccountId, + AccountId = ::AccountId, { /// A recovery process has been set up for an \[account\]. RecoveryCreated(AccountId), diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 35373562487f7..0eef19d9dd894 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -58,7 +58,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = Call; diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index c467678a466de..a9a16429390b7 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -73,11 +73,11 @@ pub use weights::WeightInfo; /// `system::Trait` should always be included in our implied traits. pub trait Trait: system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The aggregated origin which the dispatch will take. type Origin: OriginTrait + From + IsType<::Origin>; + Self::PalletsOrigin> + From + IsType<::Origin>; /// The caller origin, overarching type of all pallets origins. type PalletsOrigin: From> + Codec + Clone + Eq; @@ -90,7 +90,7 @@ pub trait Trait: system::Trait { type MaximumWeight: Get; /// Required origin to schedule or cancel calls. - type ScheduleOrigin: EnsureOrigin<::Origin>; + type ScheduleOrigin: EnsureOrigin<::Origin>; /// The maximum number of scheduled calls in the queue for a single block. /// Not strictly enforced, but used for weight estimation. @@ -166,7 +166,7 @@ decl_storage! { } decl_event!( - pub enum Event where ::BlockNumber { + pub enum Event where ::BlockNumber { /// Scheduled some task. \[when, index\] Scheduled(BlockNumber, u32), /// Canceled some task. \[when, index\] @@ -191,7 +191,7 @@ decl_error! { decl_module! { /// Scheduler module declaration. - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { type Error = Error; fn deposit_event() = default; @@ -747,7 +747,7 @@ mod tests { LOG.with(|log| log.borrow().clone()) } pub trait Trait: system::Trait { - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; } decl_event! { pub enum Event { @@ -757,8 +757,8 @@ mod tests { decl_module! { pub struct Module for enum Call where - origin: ::Origin, - ::Origin: OriginTrait + origin: ::Origin, + ::Origin: OriginTrait { fn deposit_event() = default; @@ -816,7 +816,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl system::Trait for Test { + impl system::Config for Test { type BaseCallFilter = BaseFilter; type Origin = Origin; type Call = Call; @@ -889,7 +889,7 @@ mod tests { fn basic_scheduling_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_ok!(Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call)); run_to_block(3); assert!(logger::log().is_empty()); @@ -905,7 +905,7 @@ mod tests { new_test_ext().execute_with(|| { run_to_block(2); let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); // This will schedule the call 3 blocks after the next block... so block 3 + 3 = 6 assert_ok!(Scheduler::do_schedule(DispatchTime::After(3), None, 127, root(), call)); run_to_block(5); @@ -922,7 +922,7 @@ mod tests { new_test_ext().execute_with(|| { run_to_block(2); let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_ok!(Scheduler::do_schedule(DispatchTime::After(0), None, 127, root(), call)); // Will trigger on the next block. run_to_block(3); @@ -960,7 +960,7 @@ mod tests { fn reschedule_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call).unwrap(), (4, 0)); run_to_block(3); @@ -985,7 +985,7 @@ mod tests { fn reschedule_named_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule_named( 1u32.encode(), DispatchTime::At(4), None, 127, root(), call ).unwrap(), (4, 0)); @@ -1012,7 +1012,7 @@ mod tests { fn reschedule_named_perodic_works() { new_test_ext().execute_with(|| { let call = Call::Logger(logger::Call::log(42, 1000)); - assert!(!::BaseCallFilter::filter(&call)); + assert!(!::BaseCallFilter::filter(&call)); assert_eq!(Scheduler::do_schedule_named( 1u32.encode(), DispatchTime::At(4), Some((3, 3)), 127, root(), call ).unwrap(), (4, 0)); @@ -1203,10 +1203,10 @@ mod tests { #[test] fn on_initialize_weight_is_correct() { new_test_ext().execute_with(|| { - let base_weight: Weight = ::DbWeight::get().reads_writes(1, 2); + let base_weight: Weight = ::DbWeight::get().reads_writes(1, 2); let base_multiplier = 0; - let named_multiplier = ::DbWeight::get().writes(1); - let periodic_multiplier = ::DbWeight::get().reads_writes(1, 1); + let named_multiplier = ::DbWeight::get().writes(1); + let periodic_multiplier = ::DbWeight::get().reads_writes(1, 1); // Named assert_ok!( diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 90d4aca4e42a4..69431c36bbc5d 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -103,8 +103,8 @@ use frame_support::{ use frame_system::{ensure_root, ensure_signed}; use sp_runtime::traits::{AtLeast32Bit, MaybeSerializeDeserialize, Zero, StaticLookup}; -type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -type PoolT = Vec<(::AccountId, Option<>::Score>)>; +type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +type PoolT = Vec<(::AccountId, Option<>::Score>)>; /// The enum is supplied when refreshing the members set. /// Depending on the enum variant the corresponding associated @@ -125,7 +125,7 @@ pub trait Trait: frame_system::Trait { AtLeast32Bit + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; // The deposit which is reserved from candidates if they want to // start a candidacy. The deposit gets returned when the candidacy is @@ -204,7 +204,7 @@ decl_storage! { decl_event!( pub enum Event where - ::AccountId, + ::AccountId, { /// The given member was removed. See the transaction for who. MemberRemoved, diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 59c0dc66cca60..4fab30e418299 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -49,7 +49,7 @@ ord_parameter_types! { pub const ScoreOrigin: u64 = 3; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index 6a9cfc5f98a1b..766e3bd236246 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -45,7 +45,7 @@ impl_outer_dispatch! { #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index c0a8fc29165bd..7386f49a51e89 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -354,7 +354,7 @@ impl ValidatorRegistration for Module { pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// A stable ID for a validator. type ValidatorId: Member + Parameter; diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 1d787ac53b438..c1bf006d9f345 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -172,7 +172,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index cbfe5a00de240..7d052e8b360d4 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -268,13 +268,13 @@ use frame_support::traits::{ }; use frame_system::{self as system, ensure_signed, ensure_root}; -type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; /// The module's configuration trait. pub trait Trait: system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The societies's module id type ModuleId: Get; @@ -1108,7 +1108,7 @@ decl_error! { decl_event! { /// Events for this module. pub enum Event where - AccountId = ::AccountId, + AccountId = ::AccountId, Balance = BalanceOf { /// The society is founded by the given identity. \[founder\] diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 212bcfd404ff1..58d0a7e113a44 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -60,7 +60,7 @@ ord_parameter_types! { pub const SuspensionJudgementSetAccount: u128 = 2; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index 96df7674e9f44..b21a818e07fcf 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -43,7 +43,7 @@ impl_outer_dispatch! { #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type DbWeight = (); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index e5aaae6bbb8f9..7953ecbbcf0f0 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -385,12 +385,12 @@ pub type OffchainAccuracy = PerU16; /// The balance type of this module. pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; + <::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = - <::Currency as Currency<::AccountId>>::PositiveImbalance; + <::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; /// Information regarding the active era (era in used in session). #[derive(Encode, Decode, RuntimeDebug)] @@ -746,22 +746,22 @@ pub trait SessionInterface: frame_system::Trait { fn prune_historical_up_to(up_to: SessionIndex); } -impl SessionInterface<::AccountId> for T where - T: pallet_session::Trait::AccountId>, +impl SessionInterface<::AccountId> for T where + T: pallet_session::Trait::AccountId>, T: pallet_session::historical::Trait< - FullIdentification = Exposure<::AccountId, BalanceOf>, + FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, - T::SessionManager: pallet_session::SessionManager<::AccountId>, + T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: - Convert<::AccountId, Option<::AccountId>>, + Convert<::AccountId, Option<::AccountId>>, { - fn disable_validator(validator: &::AccountId) -> Result { + fn disable_validator(validator: &::AccountId) -> Result { >::disable(validator) } - fn validators() -> Vec<::AccountId> { + fn validators() -> Vec<::AccountId> { >::validators() } @@ -792,7 +792,7 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { type RewardRemainder: OnUnbalanced>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Handler for the unbalanced reduction when slashing a staker. type Slash: OnUnbalanced>; @@ -1121,7 +1121,7 @@ decl_storage! { } decl_event!( - pub enum Event where Balance = BalanceOf, ::AccountId { + pub enum Event where Balance = BalanceOf, ::AccountId { /// The era payout has been set; the first balance is the validator-payout; the second is /// the remainder from the maximum amount of reward. /// \[era_index, validator_payout, remainder\] @@ -3170,16 +3170,16 @@ impl Convert> impl OnOffenceHandler, Weight> for Module where - T: pallet_session::Trait::AccountId>, + T: pallet_session::Trait::AccountId>, T: pallet_session::historical::Trait< - FullIdentification = Exposure<::AccountId, BalanceOf>, + FullIdentification = Exposure<::AccountId, BalanceOf>, FullIdentificationOf = ExposureOf, >, - T::SessionHandler: pallet_session::SessionHandler<::AccountId>, - T::SessionManager: pallet_session::SessionManager<::AccountId>, + T::SessionHandler: pallet_session::SessionHandler<::AccountId>, + T::SessionManager: pallet_session::SessionManager<::AccountId>, T::ValidatorIdOf: Convert< - ::AccountId, - Option<::AccountId>, + ::AccountId, + Option<::AccountId>, >, { fn on_offence( diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 055ebb9730805..7e3c1ba4bb1ca 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -187,7 +187,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MaxLocks: u32 = 1024; } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 2a02d87aa2c57..47307d1a91633 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -3267,7 +3267,7 @@ mod offchain_election { ElectionSize::default(), ), Error::::OffchainElectionEarlySubmission, - Some(::DbWeight::get().reads(1)), + Some(::DbWeight::get().reads(1)), ); }) } @@ -3303,7 +3303,7 @@ mod offchain_election { score, ), Error::::OffchainElectionWeakSubmission, - Some(::DbWeight::get().reads(3)) + Some(::DbWeight::get().reads(3)) ); }) } @@ -4569,14 +4569,14 @@ fn bond_during_era_correctly_populates_claimed_rewards() { fn offences_weight_calculated_correctly() { ExtBuilder::default().nominate(true).build_and_execute(|| { // On offence with zero offenders: 4 Reads, 1 Write - let zero_offence_weight = ::DbWeight::get().reads_writes(4, 1); + let zero_offence_weight = ::DbWeight::get().reads_writes(4, 1); assert_eq!(Staking::on_offence(&[], &[Perbill::from_percent(50)], 0), Ok(zero_offence_weight)); // On Offence with N offenders, Unapplied: 4 Reads, 1 Write + 4 Reads, 5 Writes - let n_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) - + ::DbWeight::get().reads_writes(4, 5); + let n_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) + + ::DbWeight::get().reads_writes(4, 5); - let offenders: Vec::AccountId, pallet_session::historical::IdentificationTuple>> + let offenders: Vec::AccountId, pallet_session::historical::IdentificationTuple>> = (1..10).map(|i| OffenceDetails { offender: (i, Staking::eras_stakers(Staking::active_era().unwrap().index, i)), @@ -4595,14 +4595,14 @@ fn offences_weight_calculated_correctly() { let n = 1; // Number of offenders let rw = 3 + 3 * n; // rw reads and writes - let one_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) - + ::DbWeight::get().reads_writes(rw, rw) + let one_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) + + ::DbWeight::get().reads_writes(rw, rw) // One `slash_cost` - + ::DbWeight::get().reads_writes(6, 5) + + ::DbWeight::get().reads_writes(6, 5) // `slash_cost` * nominators (1) - + ::DbWeight::get().reads_writes(6, 5) + + ::DbWeight::get().reads_writes(6, 5) // `reward_cost` * reporters (1) - + ::DbWeight::get().reads_writes(2, 2); + + ::DbWeight::get().reads_writes(2, 2); assert_eq!(Staking::on_offence(&one_offender, &[Perbill::from_percent(50)], 0), Ok(one_offence_unapplied_weight)); }); @@ -4614,7 +4614,7 @@ fn on_initialize_weight_is_correct() { assert_eq!(Validators::::iter().count(), 0); assert_eq!(Nominators::::iter().count(), 0); // When this pallet has nothing, we do 4 reads each block - let base_weight = ::DbWeight::get().reads(4); + let base_weight = ::DbWeight::get().reads(4); assert_eq!(base_weight, Staking::on_initialize(0)); }); @@ -4636,7 +4636,7 @@ fn on_initialize_weight_is_correct() { // With 4 validators and 5 nominator, we should increase weight by: // - (4 + 5) reads // - 3 Writes - let final_weight = ::DbWeight::get().reads_writes(4 + 9, 3); + let final_weight = ::DbWeight::get().reads_writes(4 + 9, 3); assert_eq!(final_weight, Staking::on_initialize(System::block_number())); }); } diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 0d21e44326668..6573d8f44b92f 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -107,7 +107,7 @@ mod tests; pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// A sudo-able call. type Call: Parameter + UnfilteredDispatchable + GetDispatchInfo; @@ -230,7 +230,7 @@ decl_module! { } decl_event!( - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// A sudo just took place. \[result\] Sudid(DispatchResult), /// The \[sudoer\] just switched identity; the old key is supplied. diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index 7996cd05d071f..403f5aba27b82 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -34,7 +34,7 @@ pub mod logger { use frame_system::ensure_root; pub trait Trait: frame_system::Trait { - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; } decl_storage! { @@ -45,14 +45,14 @@ pub mod logger { } decl_event! { - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { AppendI32(i32, Weight), AppendI32AndAccount(AccountId, i32, Weight), } } decl_module! { - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { fn deposit_event() = default; #[weight = *weight] @@ -118,7 +118,7 @@ impl Filter for BlockEverything { } } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = BlockEverything; type Origin = Origin; type Call = Call; diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index d55faa28d115b..7e7175858b7a3 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -1273,10 +1273,10 @@ macro_rules! decl_module { fn on_initialize() -> $return:ty { $( $impl:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnInitialize<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OnInitialize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn on_initialize(_block_number_not_used: <$trait_instance as $system::Trait>::BlockNumber) -> $return { + fn on_initialize(_block_number_not_used: <$trait_instance as $system::Config>::BlockNumber) -> $return { $crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_initialize")); { $( $impl )* } } @@ -1290,7 +1290,7 @@ macro_rules! decl_module { fn on_initialize($param:ident : $param_ty:ty) -> $return:ty { $( $impl:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnInitialize<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OnInitialize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_initialize($param: $param_ty) -> $return { @@ -1306,7 +1306,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnInitialize<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OnInitialize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1326,10 +1326,10 @@ macro_rules! decl_module { let result: $return = (|| { $( $impl )* })(); $crate::crate_to_pallet_version!() - .put_into_storage::<<$trait_instance as $system::Trait>::PalletInfo, Self>(); + .put_into_storage::<<$trait_instance as $system::Config>::PalletInfo, Self>(); let additional_write = < - <$trait_instance as $system::Trait>::DbWeight as $crate::traits::Get<_> + <$trait_instance as $system::Config>::DbWeight as $crate::traits::Get<_> >::get().writes(1); result.saturating_add(additional_write) @@ -1350,10 +1350,10 @@ macro_rules! decl_module { $crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_runtime_upgrade")); $crate::crate_to_pallet_version!() - .put_into_storage::<<$trait_instance as $system::Trait>::PalletInfo, Self>(); + .put_into_storage::<<$trait_instance as $system::Config>::PalletInfo, Self>(); < - <$trait_instance as $system::Trait>::DbWeight as $crate::traits::Get<_> + <$trait_instance as $system::Config>::DbWeight as $crate::traits::Get<_> >::get().writes(1) } } @@ -1395,10 +1395,10 @@ macro_rules! decl_module { fn on_finalize() { $( $impl:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnFinalize<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn on_finalize(_block_number_not_used: <$trait_instance as $system::Trait>::BlockNumber) { + fn on_finalize(_block_number_not_used: <$trait_instance as $system::Config>::BlockNumber) { $crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_finalize")); { $( $impl )* } } @@ -1412,7 +1412,7 @@ macro_rules! decl_module { fn on_finalize($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnFinalize<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn on_finalize($param: $param_ty) { @@ -1428,7 +1428,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OnFinalize<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { } @@ -1441,10 +1441,10 @@ macro_rules! decl_module { fn offchain_worker() { $( $impl:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OffchainWorker<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OffchainWorker<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { - fn offchain_worker(_block_number_not_used: <$trait_instance as $system::Trait>::BlockNumber) { $( $impl )* } + fn offchain_worker(_block_number_not_used: <$trait_instance as $system::Config>::BlockNumber) { $( $impl )* } } }; @@ -1455,7 +1455,7 @@ macro_rules! decl_module { fn offchain_worker($param:ident : $param_ty:ty) { $( $impl:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OffchainWorker<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OffchainWorker<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* { fn offchain_worker($param: $param_ty) { $( $impl )* } @@ -1468,7 +1468,7 @@ macro_rules! decl_module { { $( $other_where_bounds:tt )* } ) => { impl<$trait_instance: $system::Trait + $trait_name$(, $instance: $instantiable)?> - $crate::traits::OffchainWorker<<$trait_instance as $system::Trait>::BlockNumber> + $crate::traits::OffchainWorker<<$trait_instance as $system::Config>::BlockNumber> for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* {} }; @@ -1824,7 +1824,7 @@ macro_rules! decl_module { fn storage_version() -> Option<$crate::traits::PalletVersion> { let key = $crate::traits::PalletVersion::storage_key::< - <$trait_instance as $system::Trait>::PalletInfo, Self + <$trait_instance as $system::Config>::PalletInfo, Self >().expect("Every active pallet has a name in the runtime; qed"); $crate::storage::unhashed::get(&key) @@ -1837,7 +1837,7 @@ macro_rules! decl_module { { fn on_genesis() { $crate::crate_to_pallet_version!() - .put_into_storage::<<$trait_instance as $system::Trait>::PalletInfo, Self>(); + .put_into_storage::<<$trait_instance as $system::Config>::PalletInfo, Self>(); } } @@ -2417,7 +2417,11 @@ mod tests { pub mod system { use super::*; - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + + pub trait Config: 'static { type AccountId; type Call; type BaseCallFilter; @@ -2443,7 +2447,7 @@ mod tests { } } - pub type Origin = RawOrigin<::AccountId>; + pub type Origin = RawOrigin<::AccountId>; } decl_module! { @@ -2562,7 +2566,7 @@ mod tests { } } - impl system::Trait for TraitImpl { + impl system::Config for TraitImpl { type Origin = OuterOrigin; type AccountId = u32; type Call = OuterCall; diff --git a/frame/support/src/event.rs b/frame/support/src/event.rs index 3538748c30faf..51ea42a9ed8bf 100644 --- a/frame/support/src/event.rs +++ b/frame/support/src/event.rs @@ -551,7 +551,10 @@ mod tests { use codec::{Encode, Decode}; mod system { - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; @@ -570,7 +573,10 @@ mod tests { } mod system_renamed { - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; @@ -601,7 +607,7 @@ mod tests { decl_event!( /// Event without renaming the generic parameter `Balance` and `Origin`. - pub enum Event where ::Balance, ::Origin + pub enum Event where ::Balance, ::Origin { /// Hi, I am a comment. TestEvent(Balance, Origin), @@ -626,7 +632,7 @@ mod tests { /// Event with renamed generic parameter pub enum Event where BalanceRenamed = ::Balance, - OriginRenamed = ::Origin + OriginRenamed = ::Origin { TestEvent(BalanceRenamed), TestOrigin(OriginRenamed), @@ -657,7 +663,7 @@ mod tests { /// Event finish formatting on an unnamed one with trailing comma pub enum Event where ::Balance, - ::Origin, + ::Origin, { TestEvent(Balance, Origin), } @@ -679,7 +685,7 @@ mod tests { /// Event finish formatting on an named one with trailing comma pub enum Event where BalanceRenamed = ::Balance, - OriginRenamed = ::Origin, + OriginRenamed = ::Origin, { TestEvent(BalanceRenamed, OriginRenamed), TrailingCommaInArgs( @@ -722,7 +728,7 @@ mod tests { type Balance = u32; } - impl system::Trait for TestRuntime { + impl system::Config for TestRuntime { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); @@ -737,14 +743,14 @@ mod tests { type Balance = u32; } - impl system_renamed::Trait for TestRuntime2 { + impl system_renamed::Config for TestRuntime2 { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); type DbWeight = (); } - impl system::Trait for TestRuntime2 { + impl system::Config for TestRuntime2 { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index a132b787fd9bf..36d316a9b9a1b 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -499,7 +499,10 @@ mod tests { use sp_std::{marker::PhantomData, result}; use sp_io::TestExternalities; - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type BlockNumber: Codec + EncodeLike + Default; type Origin; type PalletInfo: crate::traits::PalletInfo; @@ -509,7 +512,7 @@ mod tests { mod module { #![allow(dead_code)] - use super::Trait; + use super::{Trait, Config}; decl_module! { pub struct Module for enum Call where origin: T::Origin, system=self {} @@ -540,7 +543,7 @@ mod tests { } struct Test; - impl Trait for Test { + impl Config for Test { type BlockNumber = u32; type Origin = u32; type PalletInfo = (); diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index 80737e4b13d6f..762ae891a066e 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -27,7 +27,10 @@ pub use frame_metadata::{ /// Example: /// ``` ///# mod module0 { -///# pub trait Trait: 'static { +///# // Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. +///# pub trait Trait: Config {} +///# impl Trait for T {} +///# pub trait Config: 'static { ///# type Origin; ///# type BlockNumber; ///# type PalletInfo: frame_support::traits::PalletInfo; @@ -43,7 +46,7 @@ pub use frame_metadata::{ ///# } ///# use module0 as module1; ///# use module0 as module2; -///# impl module0::Trait for Runtime { +///# impl module0::Config for Runtime { ///# type Origin = u32; ///# type BlockNumber = u32; ///# type PalletInfo = (); @@ -297,7 +300,10 @@ mod tests { mod system { use super::*; - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type BaseCallFilter; const ASSOCIATED_CONST: u64 = 500; type Origin: Into, Self::Origin>> @@ -341,7 +347,7 @@ mod tests { } } - pub type Origin = RawOrigin<::AccountId>; + pub type Origin = RawOrigin<::AccountId>; } mod event_module { @@ -445,7 +451,7 @@ mod tests { pub const SystemValue: u32 = 600; } - impl system::Trait for TestRuntime { + impl system::Config for TestRuntime { type BaseCallFilter = (); type Origin = Origin; type AccountId = u32; @@ -480,7 +486,7 @@ mod tests { struct ConstantAssociatedConstByteGetter; impl DefaultByte for ConstantAssociatedConstByteGetter { fn default_byte(&self) -> Vec { - ::ASSOCIATED_CONST.encode() + ::ASSOCIATED_CONST.encode() } } diff --git a/frame/support/src/origin.rs b/frame/support/src/origin.rs index b96a56c8e1d8f..d6d7efbbe30e5 100644 --- a/frame/support/src/origin.rs +++ b/frame/support/src/origin.rs @@ -186,7 +186,7 @@ macro_rules! impl_outer_origin { #[derive(Clone)] pub struct $name { caller: $caller_name, - filter: $crate::sp_std::rc::Rc::Call) -> bool>>, + filter: $crate::sp_std::rc::Rc::Call) -> bool>>, } #[cfg(not(feature = "std"))] @@ -213,9 +213,9 @@ macro_rules! impl_outer_origin { } impl $crate::traits::OriginTrait for $name { - type Call = <$runtime as $system::Trait>::Call; + type Call = <$runtime as $system::Config>::Call; type PalletsOrigin = $caller_name; - type AccountId = <$runtime as $system::Trait>::AccountId; + type AccountId = <$runtime as $system::Config>::AccountId; fn add_filter(&mut self, filter: impl Fn(&Self::Call) -> bool + 'static) { let f = self.filter.clone(); @@ -227,8 +227,8 @@ macro_rules! impl_outer_origin { fn reset_filter(&mut self) { let filter = < - <$runtime as $system::Trait>::BaseCallFilter - as $crate::traits::Filter<<$runtime as $system::Trait>::Call> + <$runtime as $system::Config>::BaseCallFilter + as $crate::traits::Filter<<$runtime as $system::Config>::Call> >::filter; self.filter = $crate::sp_std::rc::Rc::new(Box::new(filter)); @@ -255,7 +255,7 @@ macro_rules! impl_outer_origin { $system::RawOrigin::Root.into() } /// Create with system signed origin and `frame-system::Trait::BaseCallFilter`. - fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self { + fn signed(by: <$runtime as $system::Config>::AccountId) -> Self { $system::RawOrigin::Signed(by).into() } } @@ -289,7 +289,7 @@ macro_rules! impl_outer_origin { <$name as $crate::traits::OriginTrait>::root() } /// Create with system signed origin and `frame-system::Trait::BaseCallFilter`. - pub fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self { + pub fn signed(by: <$runtime as $system::Config>::AccountId) -> Self { <$name as $crate::traits::OriginTrait>::signed(by) } } @@ -335,10 +335,10 @@ macro_rules! impl_outer_origin { } } } - impl From::AccountId>> for $name { + impl From::AccountId>> for $name { /// Convert to runtime origin with caller being system signed or none and use filter /// `frame-system::Trait::BaseCallFilter`. - fn from(x: Option<<$runtime as $system::Trait>::AccountId>) -> Self { + fn from(x: Option<<$runtime as $system::Config>::AccountId>) -> Self { <$system::Origin<$runtime>>::from(x).into() } } @@ -388,7 +388,7 @@ mod tests { mod frame_system { use super::*; - pub trait Trait { + pub trait Config { type AccountId; type Call; type BaseCallFilter; @@ -410,7 +410,7 @@ mod tests { } } - pub type Origin = RawOrigin<::AccountId>; + pub type Origin = RawOrigin<::AccountId>; } mod origin_without_generic { @@ -439,7 +439,7 @@ mod tests { } } - impl frame_system::Trait for TestRuntime { + impl frame_system::Config for TestRuntime { type AccountId = u32; type Call = u32; type BaseCallFilter = BaseCallFilter; diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index cbc62c83de886..8a13abac77aff 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -425,7 +425,10 @@ mod test_iterators { storage::{generator::StorageDoubleMap, IterableStorageDoubleMap, unhashed}, }; - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 601fd4c4a8dd2..af0f3d2e3d554 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -325,7 +325,10 @@ mod test_iterators { storage::{generator::StorageMap, IterableStorageMap, unhashed}, }; - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 9346718f63481..6098e45959252 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -42,14 +42,17 @@ mod tests { struct Runtime; - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type Origin; type BlockNumber; type PalletInfo: crate::traits::PalletInfo; type DbWeight: crate::traits::Get; } - impl Trait for Runtime { + impl Config for Runtime { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 74f0773aa541f..dcb6197fe6c9f 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -701,7 +701,10 @@ mod tests { use crate::{decl_module, parameter_types, traits::Get}; use super::*; - pub trait Trait: 'static { + /// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. + pub trait Trait: Config {} + impl Trait for T {} + pub trait Config: 'static { type Origin; type Balance; type BlockNumber; @@ -718,7 +721,7 @@ mod tests { }; } - impl Trait for TraitImpl { + impl Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type Balance = u32; diff --git a/frame/support/test/src/lib.rs b/frame/support/test/src/lib.rs index a917c781c065c..119d8a0115d0c 100644 --- a/frame/support/test/src/lib.rs +++ b/frame/support/test/src/lib.rs @@ -25,8 +25,12 @@ #[cfg(test)] mod pallet_version; +/// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. +pub trait Trait: Config {} +impl Trait for T {} + /// The configuration trait -pub trait Trait: 'static { +pub trait Config: 'static { /// The runtime origin type. type Origin: codec::Codec + codec::EncodeLike + Default; /// The block number type. diff --git a/frame/support/test/tests/construct_runtime.rs b/frame/support/test/tests/construct_runtime.rs index 4ff4fc6828604..0dba5933eb65b 100644 --- a/frame/support/test/tests/construct_runtime.rs +++ b/frame/support/test/tests/construct_runtime.rs @@ -41,7 +41,7 @@ mod module1 { frame_support::decl_module! { pub struct Module, I: Instance = DefaultInstance> for enum Call - where origin: ::Origin, system=system + where origin: ::Origin, system=system { #[weight = 0] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { @@ -55,7 +55,7 @@ mod module1 { frame_support::decl_event! { pub enum Event where - ::AccountId + ::AccountId { A(AccountId), } @@ -79,7 +79,7 @@ mod module2 { frame_support::decl_module! { pub struct Module for enum Call - where origin: ::Origin, system=system + where origin: ::Origin, system=system { #[weight = 0] pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { @@ -120,7 +120,7 @@ pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter = (); type Hash = H256; type Origin = Origin; diff --git a/frame/support/test/tests/decl_storage.rs b/frame/support/test/tests/decl_storage.rs index 8d5727ce9104b..ad946586e7840 100644 --- a/frame/support/test/tests/decl_storage.rs +++ b/frame/support/test/tests/decl_storage.rs @@ -81,7 +81,7 @@ mod tests { struct TraitImpl {} - impl frame_support_test::Trait for TraitImpl { + impl frame_support_test::Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); @@ -438,7 +438,7 @@ mod test2 { struct TraitImpl {} - impl frame_support_test::Trait for TraitImpl { + impl frame_support_test::Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); @@ -466,7 +466,7 @@ mod test3 { struct TraitImpl {} - impl frame_support_test::Trait for TraitImpl { + impl frame_support_test::Config for TraitImpl { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); @@ -511,7 +511,7 @@ mod test_append_and_len { struct Test {} - impl frame_support_test::Trait for Test { + impl frame_support_test::Config for Test { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); diff --git a/frame/support/test/tests/genesisconfig.rs b/frame/support/test/tests/genesisconfig.rs index f268f11a4dc15..d7ef15ed78d72 100644 --- a/frame/support/test/tests/genesisconfig.rs +++ b/frame/support/test/tests/genesisconfig.rs @@ -29,7 +29,7 @@ frame_support::decl_storage! { struct Test; -impl frame_support_test::Trait for Test { +impl frame_support_test::Config for Test { type BlockNumber = u32; type Origin = (); type PalletInfo = (); diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 6c90767f92e57..5e9f885ff796f 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -41,8 +41,8 @@ mod module1 { use super::*; use sp_std::ops::Add; - pub trait Trait: system::Trait where ::BlockNumber: From { - type Event: From> + Into<::Event>; + pub trait Trait: system::Trait where ::BlockNumber: From { + type Event: From> + Into<::Event>; type Origin: From>; type SomeParameter: Get; type GenericType: Default + Clone + Codec + EncodeLike; @@ -50,7 +50,7 @@ mod module1 { frame_support::decl_module! { pub struct Module, I: Instance> for enum Call where - origin: ::Origin, + origin: ::Origin, system = system, T::BlockNumber: From { @@ -133,7 +133,7 @@ mod module2 { pub trait Trait: system::Trait { type Amount: Parameter + Default; - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; type Origin: From>; } @@ -141,7 +141,7 @@ mod module2 { frame_support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where - origin: ::Origin, + origin: ::Origin, system = system { fn deposit_event() = default; @@ -196,7 +196,7 @@ mod module3 { } frame_support::decl_module! { - pub struct Module for enum Call where origin: ::Origin, system=system {} + pub struct Module for enum Call where origin: ::Origin, system=system {} } } @@ -246,7 +246,7 @@ pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter= (); type Hash = H256; type Origin = Origin; diff --git a/frame/support/test/tests/issue2219.rs b/frame/support/test/tests/issue2219.rs index 596a3b6ffb25d..e341dcd5d6b20 100644 --- a/frame/support/test/tests/issue2219.rs +++ b/frame/support/test/tests/issue2219.rs @@ -27,9 +27,9 @@ mod module { use super::*; pub type Request = ( - ::AccountId, + ::AccountId, Role, - ::BlockNumber, + ::BlockNumber, ); pub type Requests = Vec>; @@ -157,7 +157,7 @@ pub type Header = generic::Header; pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter = (); type Hash = H256; type Origin = Origin; diff --git a/frame/support/test/tests/pallet_version.rs b/frame/support/test/tests/pallet_version.rs index d6293ac6a308a..7adeec30cd695 100644 --- a/frame/support/test/tests/pallet_version.rs +++ b/frame/support/test/tests/pallet_version.rs @@ -41,7 +41,7 @@ mod module1 { frame_support::decl_module! { pub struct Module for enum Call where - origin: ::Origin, + origin: ::Origin, system = system, {} } @@ -56,7 +56,7 @@ mod module2 { frame_support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where - origin: ::Origin, + origin: ::Origin, system = system { fn on_runtime_upgrade() -> Weight { @@ -92,7 +92,7 @@ pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter= (); type Hash = H256; type Origin = Origin; diff --git a/frame/support/test/tests/storage_transaction.rs b/frame/support/test/tests/storage_transaction.rs index 5c687ef05005d..adcdd4fea1835 100644 --- a/frame/support/test/tests/storage_transaction.rs +++ b/frame/support/test/tests/storage_transaction.rs @@ -50,7 +50,7 @@ frame_support::decl_storage!{ struct Runtime; -impl frame_support_test::Trait for Runtime { +impl frame_support_test::Config for Runtime { type Origin = u32; type BlockNumber = u32; type PalletInfo = (); diff --git a/frame/support/test/tests/system.rs b/frame/support/test/tests/system.rs index f30b6e4c2af9d..d1e414f6529ae 100644 --- a/frame/support/test/tests/system.rs +++ b/frame/support/test/tests/system.rs @@ -19,7 +19,11 @@ use frame_support::{ codec::{Encode, Decode, EncodeLike}, traits::Get, weights::RuntimeDbWeight, }; -pub trait Trait: 'static + Eq + Clone { +/// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. +pub trait Trait: Config {} +impl Trait for T {} + +pub trait Config: 'static + Eq + Clone { type Origin: Into, Self::Origin>> + From>; @@ -45,7 +49,7 @@ impl Module { } frame_support::decl_event!( - pub enum Event where BlockNumber = ::BlockNumber { + pub enum Event where BlockNumber = ::BlockNumber { ExtrinsicSuccess, ExtrinsicFailed, Ignore(BlockNumber), @@ -79,7 +83,7 @@ impl From> for RawOrigin { } } -pub type Origin = RawOrigin<::AccountId>; +pub type Origin = RawOrigin<::AccountId>; #[allow(dead_code)] pub fn ensure_root(o: OuterOrigin) -> Result<(), &'static str> diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 00c965136c0d0..6097bb45d417b 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -25,7 +25,7 @@ mod module { use super::*; pub trait Trait: system::Trait { - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; } decl_module! { @@ -60,7 +60,7 @@ frame_support::parameter_types! { } #[derive(Clone, Eq, PartialEq)] pub struct Runtime; -impl system::Trait for Runtime { +impl system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index 33255d7b50e19..2deddf6bbc563 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -50,7 +50,7 @@ impl Dispatchable for Call { #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; diff --git a/frame/system/src/extensions/check_genesis.rs b/frame/system/src/extensions/check_genesis.rs index d0a346519ca23..ed8df30405f05 100644 --- a/frame/system/src/extensions/check_genesis.rs +++ b/frame/system/src/extensions/check_genesis.rs @@ -16,7 +16,7 @@ // limitations under the License. use codec::{Encode, Decode}; -use crate::{Trait, Module}; +use crate::{Trait, Config, Module}; use sp_runtime::{ traits::{SignedExtension, Zero}, transaction_validity::TransactionValidityError, @@ -47,7 +47,7 @@ impl CheckGenesis { impl SignedExtension for CheckGenesis { type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = T::Hash; type Pre = (); const IDENTIFIER: &'static str = "CheckGenesis"; diff --git a/frame/system/src/extensions/check_spec_version.rs b/frame/system/src/extensions/check_spec_version.rs index 8dc4d8d9ceddc..25cb538d7c75c 100644 --- a/frame/system/src/extensions/check_spec_version.rs +++ b/frame/system/src/extensions/check_spec_version.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Trait, Module}; +use crate::{Trait, Config, Module}; use codec::{Encode, Decode}; use sp_runtime::{ traits::SignedExtension, @@ -47,7 +47,7 @@ impl CheckSpecVersion { impl SignedExtension for CheckSpecVersion { type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = u32; type Pre = (); const IDENTIFIER: &'static str = "CheckSpecVersion"; diff --git a/frame/system/src/extensions/check_tx_version.rs b/frame/system/src/extensions/check_tx_version.rs index ee6f3349365b9..d1e2b0a7f6486 100644 --- a/frame/system/src/extensions/check_tx_version.rs +++ b/frame/system/src/extensions/check_tx_version.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{Trait, Module}; +use crate::{Trait, Config, Module}; use codec::{Encode, Decode}; use sp_runtime::{ traits::SignedExtension, @@ -47,7 +47,7 @@ impl CheckTxVersion { impl SignedExtension for CheckTxVersion { type AccountId = T::AccountId; - type Call = ::Call; + type Call = ::Call; type AdditionalSigned = u32; type Pre = (); const IDENTIFIER: &'static str = "CheckTxVersion"; diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index 39439a3e2d8ce..4466c983b7ff1 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -309,18 +309,18 @@ impl sp_std::fmt::Debug for CheckWeight { #[cfg(test)] mod tests { use super::*; - use crate::{BlockWeight, AllExtrinsicsLen}; + use crate::{BlockWeight, AllExtrinsicsLen, Config}; use crate::mock::{Test, CALL, new_test_ext, System}; use sp_std::marker::PhantomData; use frame_support::{assert_ok, assert_noop}; use frame_support::weights::{Weight, Pays}; fn normal_weight_limit() -> Weight { - ::AvailableBlockRatio::get() * ::MaximumBlockWeight::get() + ::AvailableBlockRatio::get() * ::MaximumBlockWeight::get() } fn normal_length_limit() -> u32 { - ::AvailableBlockRatio::get() * ::MaximumBlockLength::get() + ::AvailableBlockRatio::get() * ::MaximumBlockLength::get() } #[test] @@ -341,7 +341,7 @@ mod tests { check(|max, len| { assert_ok!(CheckWeight::::do_pre_dispatch(max, len)); assert_eq!(System::block_weight().total(), Weight::max_value()); - assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); }); check(|max, len| { assert_ok!(CheckWeight::::do_validate(max, len)); @@ -352,7 +352,7 @@ mod tests { fn normal_extrinsic_limited_by_maximum_extrinsic_weight() { new_test_ext().execute_with(|| { let max = DispatchInfo { - weight: ::MaximumExtrinsicWeight::get() + 1, + weight: ::MaximumExtrinsicWeight::get() + 1, class: DispatchClass::Normal, ..Default::default() }; @@ -370,9 +370,9 @@ mod tests { new_test_ext().execute_with(|| { let operational_limit = CheckWeight::::get_dispatch_limit_ratio( DispatchClass::Operational - ) * ::MaximumBlockWeight::get(); - let base_weight = ::ExtrinsicBaseWeight::get(); - let block_base = ::BlockExecutionWeight::get(); + ) * ::MaximumBlockWeight::get(); + let base_weight = ::ExtrinsicBaseWeight::get(); + let block_base = ::BlockExecutionWeight::get(); let weight = operational_limit - base_weight - block_base; let okay = DispatchInfo { @@ -406,7 +406,7 @@ mod tests { new_test_ext().execute_with(|| { System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Normal); assert_eq!(System::block_weight().total(), Weight::max_value()); - assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); }); } @@ -426,8 +426,8 @@ mod tests { assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); assert_eq!(System::block_weight().total(), 768); assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + assert_eq!(::MaximumBlockWeight::get(), 1024); + assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); // Checking single extrinsic should not take current block weight into account. assert_eq!(CheckWeight::::check_extrinsic_weight(&rest_operational), Ok(())); }); @@ -446,8 +446,8 @@ mod tests { // Extra 15 here from block execution + base extrinsic weight assert_eq!(System::block_weight().total(), 266); assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + assert_eq!(::MaximumBlockWeight::get(), 1024); + assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); }); } @@ -553,11 +553,11 @@ mod tests { let normal_limit = normal_weight_limit(); let small = DispatchInfo { weight: 100, ..Default::default() }; let medium = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get(), + weight: normal_limit - ::ExtrinsicBaseWeight::get(), ..Default::default() }; let big = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get() + 1, + weight: normal_limit - ::ExtrinsicBaseWeight::get() + 1, ..Default::default() }; let len = 0_usize; @@ -589,7 +589,7 @@ mod tests { // We allow 75% for normal transaction, so we put 25% - extrinsic base weight BlockWeight::mutate(|current_weight| { - current_weight.put(256 - ::ExtrinsicBaseWeight::get(), DispatchClass::Normal) + current_weight.put(256 - ::ExtrinsicBaseWeight::get(), DispatchClass::Normal) }); let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); @@ -623,7 +623,7 @@ mod tests { let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); assert_eq!( BlockWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), + info.weight + 128 + ::ExtrinsicBaseWeight::get(), ); assert!( @@ -632,7 +632,7 @@ mod tests { ); assert_eq!( BlockWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), + info.weight + 128 + ::ExtrinsicBaseWeight::get(), ); }) } @@ -644,12 +644,12 @@ mod tests { let len = 0_usize; // Initial weight from `BlockExecutionWeight` - assert_eq!(System::block_weight().total(), ::BlockExecutionWeight::get()); + assert_eq!(System::block_weight().total(), ::BlockExecutionWeight::get()); let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len); assert!(r.is_ok()); assert_eq!( System::block_weight().total(), - ::ExtrinsicBaseWeight::get() + ::BlockExecutionWeight::get() + ::ExtrinsicBaseWeight::get() + ::BlockExecutionWeight::get() ); }) } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 595b001ea6b01..da374b9cd473e 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -160,7 +160,12 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { H::ordered_trie_root(xts) } -pub trait Trait: 'static + Eq + Clone { +/// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. +pub trait Trait: Config {} +impl Trait for T {} + +/// 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; @@ -270,8 +275,8 @@ pub trait Trait: 'static + Eq + Clone { type SystemWeightInfo: WeightInfo; } -pub type DigestOf = generic::Digest<::Hash>; -pub type DigestItemOf = generic::DigestItem<::Hash>; +pub type DigestOf = generic::Digest<::Hash>; +pub type DigestItemOf = generic::DigestItem<::Hash>; pub type Key = Vec; pub type KeyValue = (Vec, Vec); @@ -329,7 +334,7 @@ impl From> for RawOrigin { } /// Exposed trait-generic origin type. -pub type Origin = RawOrigin<::AccountId>; +pub type Origin = RawOrigin<::AccountId>; // Create a Hash with 69 for each byte, // only used to build genesis config. @@ -478,7 +483,7 @@ decl_storage! { decl_event!( /// Event for the System module. - pub enum Event where AccountId = ::AccountId { + pub enum Event where AccountId = ::AccountId { /// An extrinsic completed successfully. \[info\] ExtrinsicSuccess(DispatchInfo), /// An extrinsic failed. \[error, info\] @@ -1268,7 +1273,7 @@ impl Happened for CallKillAccount { impl BlockNumberProvider for Module { - type BlockNumber = ::BlockNumber; + type BlockNumber = ::BlockNumber; fn current_block_number() -> Self::BlockNumber { Module::::block_number() diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs index cd67a74114073..2a3e34f3ead64 100644 --- a/frame/system/src/mock.rs +++ b/frame/system/src/mock.rs @@ -80,7 +80,7 @@ impl Dispatchable for Call { } } -impl Trait for Test { +impl Config for Test { type BaseCallFilter = (); type Origin = Origin; type Call = Call; @@ -109,16 +109,16 @@ impl Trait for Test { } pub type System = Module; -pub type SysEvent = ::Event; +pub type SysEvent = ::Event; -pub const CALL: &::Call = &Call; +pub const CALL: &::Call = &Call; /// Create new externalities for `System` module tests. pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext: sp_io::TestExternalities = GenesisConfig::default().build_storage::().unwrap().into(); // Add to each test the initial weight of a block ext.execute_with(|| System::register_extra_weight_unchecked( - ::BlockExecutionWeight::get(), + ::BlockExecutionWeight::get(), DispatchClass::Mandatory )); ext diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index d546a34017d0a..a2cf2ef43cef0 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -314,7 +314,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index dd310c2639842..f0a6dff88578e 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -160,8 +160,8 @@ impl Convert for TargetedFeeAdjustment::AvailableBlockRatio::get() * - ::MaximumBlockWeight::get(); + ::AvailableBlockRatio::get() * + ::MaximumBlockWeight::get(); let normal_block_weight = >::block_weight() .get(frame_support::weights::DispatchClass::Normal) @@ -263,7 +263,7 @@ decl_module! { assert!( ::max_value() >= Multiplier::checked_from_integer( - ::MaximumBlockWeight::get().try_into().unwrap() + ::MaximumBlockWeight::get().try_into().unwrap() ).unwrap(), ); @@ -407,7 +407,7 @@ impl Module where fn weight_to_fee(weight: Weight) -> BalanceOf { // cap the weight to the maximum defined in runtime, otherwise it will be the // `Bounded` maximum of its data type, which is not desired. - let capped_weight = weight.min(::MaximumBlockWeight::get()); + let capped_weight = weight.min(::MaximumBlockWeight::get()); T::WeightToFee::calc(&capped_weight) } } @@ -574,7 +574,7 @@ mod tests { use std::cell::RefCell; use smallvec::smallvec; - const CALL: &::Call = + const CALL: &::Call = &Call::Balances(BalancesCall::transfer(2, 69)); impl_outer_dispatch! { @@ -615,7 +615,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Runtime { + impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Index = u64; @@ -858,7 +858,7 @@ mod tests { // fee will be proportional to what is the actual maximum weight in the runtime. assert_eq!( Balances::free_balance(&1), - (10000 - ::MaximumBlockWeight::get()) as u64 + (10000 - ::MaximumBlockWeight::get()) as u64 ); }); } diff --git a/frame/transaction-payment/src/payment.rs b/frame/transaction-payment/src/payment.rs index de39215b575be..0960e0938e22c 100644 --- a/frame/transaction-payment/src/payment.rs +++ b/frame/transaction-payment/src/payment.rs @@ -12,7 +12,7 @@ use sp_runtime::{ use sp_std::{fmt::Debug, marker::PhantomData}; type NegativeImbalanceOf = - ::AccountId>>::NegativeImbalance; + ::AccountId>>::NegativeImbalance; /// Handle withdrawing, refunding and depositing of transaction fees. pub trait OnChargeTransaction { @@ -56,16 +56,16 @@ pub struct CurrencyAdapter(PhantomData<(C, OU)>); impl OnChargeTransaction for CurrencyAdapter where T: Trait, - T::TransactionByteFee: Get<::AccountId>>::Balance>, - C: Currency<::AccountId>, + T::TransactionByteFee: Get<::AccountId>>::Balance>, + C: Currency<::AccountId>, C::PositiveImbalance: - Imbalance<::AccountId>>::Balance, Opposite = C::NegativeImbalance>, + Imbalance<::AccountId>>::Balance, Opposite = C::NegativeImbalance>, C::NegativeImbalance: - Imbalance<::AccountId>>::Balance, Opposite = C::PositiveImbalance>, + Imbalance<::AccountId>>::Balance, Opposite = C::PositiveImbalance>, OU: OnUnbalanced>, { type LiquidityInfo = Option>; - type Balance = ::AccountId>>::Balance; + type Balance = ::AccountId>>::Balance; /// Withdraw the predicted fee from the transaction origin. /// diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 2ada0660f9ec2..d6088f573baa9 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -155,11 +155,11 @@ use frame_system::{self as system, ensure_signed}; pub use weights::WeightInfo; type BalanceOf = - <>::Currency as Currency<::AccountId>>::Balance; + <>::Currency as Currency<::AccountId>>::Balance; type PositiveImbalanceOf = - <>::Currency as Currency<::AccountId>>::PositiveImbalance; + <>::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = - <>::Currency as Currency<::AccountId>>::NegativeImbalance; + <>::Currency as Currency<::AccountId>>::NegativeImbalance; pub trait Trait: frame_system::Trait { /// The treasury's module id, used for deriving its sovereign account ID. @@ -192,7 +192,7 @@ pub trait Trait: frame_system::Trait { type DataDepositPerByte: Get>; /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// Handler for the unbalanced decrease when slashing for a rejected proposal or bounty. type OnSlash: OnUnbalanced>; @@ -388,8 +388,8 @@ decl_event!( pub enum Event where Balance = BalanceOf, - ::AccountId, - ::Hash, + ::AccountId, + ::Hash, { /// New proposal. \[proposal_index\] Proposed(ProposalIndex), diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 88c4f23b91ae2..3435d044f6811 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -59,7 +59,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/frame/utility/src/benchmarking.rs b/frame/utility/src/benchmarking.rs index 413ed66ac8498..f6a743ab82e2d 100644 --- a/frame/utility/src/benchmarking.rs +++ b/frame/utility/src/benchmarking.rs @@ -27,7 +27,7 @@ const SEED: u32 = 0; fn assert_last_event(generic_event: ::Event) { let events = frame_system::Module::::events(); - let system_event: ::Event = generic_event.into(); + let system_event: ::Event = generic_event.into(); // compare to the last event record let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index e7ff09c8f0db1..390cd5166dadf 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -76,7 +76,7 @@ pub use weights::WeightInfo; /// Configuration trait. pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From + Into<::Event>; + type Event: From + Into<::Event>; /// The overarching call type. type Call: Parameter + Dispatchable diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index a3c33bdf2081f..c019e87d6910e 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -40,7 +40,7 @@ pub mod example { pub trait Trait: frame_system::Trait { } decl_module! { - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call where origin: ::Origin { #[weight = *weight] fn noop(_origin, weight: Weight) { } @@ -97,7 +97,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Test { +impl frame_system::Config for Test { type BaseCallFilter = TestBaseCallFilter; type Origin = Origin; type Index = u64; diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 652d10aab3ae4..65663cc3e34d8 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -29,7 +29,7 @@ use crate::Module as Vesting; const SEED: u32 = 0; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; fn add_locks(who: &T::AccountId, n: u8) { for id in 0..n { diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 8b78eac4fedf8..4350ddc6b4de7 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -64,12 +64,12 @@ use frame_support::traits::{ use frame_system::{ensure_signed, ensure_root}; pub use weights::WeightInfo; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -type MaxLocksOf = <::Currency as LockableCurrency<::AccountId>>::MaxLocks; +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type MaxLocksOf = <::Currency as LockableCurrency<::AccountId>>::MaxLocks; pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From> + Into<::Event>; /// The currency trait. type Currency: LockableCurrency; @@ -156,7 +156,7 @@ decl_storage! { } decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// The amount vested has been updated. This could indicate more funds are available. The /// balance given is the amount which is left unvested (and thus locked). /// \[account, unvested\] @@ -415,7 +415,7 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } - impl frame_system::Trait for Test { + impl frame_system::Config for Test { type BaseCallFilter = (); type Origin = Origin; type Index = u64; diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index e772a28ee33a2..59be0e65b0326 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -436,7 +436,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } -impl frame_system::Trait for Runtime { +impl frame_system::Config for Runtime { type BaseCallFilter = (); type Origin = Origin; type Call = Extrinsic; diff --git a/utils/frame/rpc/support/src/lib.rs b/utils/frame/rpc/support/src/lib.rs index dc87d6185209d..874f01baac7ae 100644 --- a/utils/frame/rpc/support/src/lib.rs +++ b/utils/frame/rpc/support/src/lib.rs @@ -43,7 +43,7 @@ use sc_rpc_api::state::StateClient; /// # use frame_system::Trait; /// # use sc_rpc_api::state::StateClient; /// # -/// # // Hash would normally be ::Hash, but we don't have +/// # // Hash would normally be ::Hash, but we don't have /// # // frame_system::Trait implemented for TestRuntime. Here we just pretend. /// # type Hash = (); /// # From 336d3c956a080d59d346875e756a68eb88d5fd44 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 27 Oct 2020 16:51:05 +0100 Subject: [PATCH 02/36] make construct_runtime handle Pallet and Module pallets can now be implemented on struct named Pallet or Module, both definition are valid. This is because next macro will generate only Pallet placeholder. --- .../procedural/src/construct_runtime/mod.rs | 60 +++++++++++++------ .../procedural/src/construct_runtime/parse.rs | 6 ++ frame/support/test/tests/construct_runtime.rs | 22 ++++--- .../construct_runtime_ui/conflicting_index.rs | 4 +- .../conflicting_index.stderr | 4 +- .../conflicting_index_2.rs | 8 +-- .../conflicting_index_2.stderr | 4 +- .../conflicting_module_pallet_parts.rs | 13 ++++ .../conflicting_module_pallet_parts.stderr | 11 ++++ .../invalid_module_details_keyword.stderr | 2 +- .../invalid_module_entry.stderr | 2 +- ...g_event_generic_on_module_with_instance.rs | 2 +- ...ent_generic_on_module_with_instance.stderr | 2 +- ..._origin_generic_on_module_with_instance.rs | 2 +- ...gin_generic_on_module_with_instance.stderr | 2 +- .../more_than_256_modules.rs | 4 +- .../more_than_256_modules.stderr | 2 +- .../tests/construct_runtime_ui/no_part.rs | 13 ++++ .../tests/construct_runtime_ui/no_part.stderr | 5 ++ 19 files changed, 122 insertions(+), 46 deletions(-) create mode 100644 frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs create mode 100644 frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr create mode 100644 frame/support/test/tests/construct_runtime_ui/no_part.rs create mode 100644 frame/support/test/tests/construct_runtime_ui/no_part.stderr diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 15f0935f38233..614c69acabcbb 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -25,6 +25,7 @@ use proc_macro2::{TokenStream as TokenStream2}; use quote::quote; use syn::{Ident, Result, TypePath}; use std::collections::HashMap; +use syn::spanned::Spanned; /// The fixed name of the system module. const SYSTEM_MODULE_NAME: &str = "System"; @@ -32,6 +33,9 @@ const SYSTEM_MODULE_NAME: &str = "System"; /// The complete definition of a module with the resulting fixed index. #[derive(Debug, Clone)] pub struct Module { + /// A Pallet use either Module (if defined with old macros) or Pallet. + /// This contains the struct to access Pallet information. + pub pallet_or_module: syn::Ident, pub name: Ident, pub index: u8, pub module: Ident, @@ -88,7 +92,29 @@ fn complete_modules(decl: impl Iterator) -> syn::Resul return Err(err); } + // Get if pallet use struct Module or Pallet. + let module_part = module.module_parts.iter().find(|part| part.name() == "Module"); + let pallet_part = module.module_parts.iter().find(|part| part.name() == "Pallet"); + let pallet_or_module = match (module_part, pallet_part) { + (Some(module_part), None) => syn::Ident::new("Module", module_part.keyword.span()), + (None, Some(pallet_part)) => syn::Ident::new("Pallet", pallet_part.keyword.span()), + (None, None) => { + let msg = "Cannot find part `Module` nor `Pallet`, one must be defined"; + return Err(syn::Error::new(module.name.span(), msg)); + }, + (Some(module_part), Some(pallet_part)) => { + let msg = "`Module` cannot be defined when `Pallet` is defined"; + let mut err = syn::Error::new(module_part.keyword.span(), msg); + let msg1 = "`Module` cannot be defined when `Pallet` is defined"; + let err1 = syn::Error::new(pallet_part.keyword.span(), msg1); + err.combine(err1); + return Err(err); + }, + }; + + Ok(Module { + pallet_or_module, name: module.name, index: final_index, module: module.module, @@ -295,30 +321,23 @@ fn decl_runtime_metadata<'a>( extrinsic: &TypePath, ) -> TokenStream2 { let modules_tokens = module_declarations - .filter_map(|module_declaration| { - module_declaration.find_part("Module").map(|_| { - let filtered_names: Vec<_> = module_declaration - .module_parts() - .into_iter() - .filter(|part| part.name() != "Module") - .map(|part| part.ident()) - .collect(); - (module_declaration, filtered_names) - }) - }) - .map(|(module_declaration, filtered_names)| { + .map(|module_declaration| { + let parts = module_declaration.module_parts().into_iter() + .map(|part| part.ident()); + let module = &module_declaration.module; let name = &module_declaration.name; - let instance = module_declaration - .instance - .as_ref() - .map(|name| quote!(<#name>)) - .into_iter(); + let instance = module_declaration.instance.as_ref() + .map(|name| quote!(<#name>)); + + let pallet_or_module = &module_declaration.pallet_or_module; let index = module_declaration.index; quote!( - #module::Module #(#instance)* as #name { index #index } with #(#filtered_names)*, + // Note: we can keep the parts Pallet or Module or ValidateUnsigned because they + // are not used by impl_runtime_metadata anyway. + #module::#pallet_or_module #instance as #name { index #index } with #(#parts)*, ) }); quote!( @@ -450,8 +469,11 @@ fn decl_all_modules<'a>( .iter() .map(|name| quote!(#module::#name)), ); + + let pallet_or_module = &module_declaration.pallet_or_module; + let type_decl = quote!( - pub type #type_name = #module::Module <#(#generics),*>; + pub type #type_name = #module::#pallet_or_module <#(#generics),*>; ); types.extend(type_decl); names.push(&module_declaration.name); diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index 4a45044d67f25..0f39db5081436 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -29,6 +29,7 @@ mod keyword { syn::custom_keyword!(NodeBlock); syn::custom_keyword!(UncheckedExtrinsic); syn::custom_keyword!(Module); + syn::custom_keyword!(Pallet); syn::custom_keyword!(Call); syn::custom_keyword!(Storage); syn::custom_keyword!(Event); @@ -221,6 +222,7 @@ fn parse_module_parts(input: ParseStream) -> Result> { #[derive(Debug, Clone)] pub enum ModulePartKeyword { Module(keyword::Module), + Pallet(keyword::Pallet), Call(keyword::Call), Storage(keyword::Storage), Event(keyword::Event), @@ -236,6 +238,8 @@ impl Parse for ModulePartKeyword { if lookahead.peek(keyword::Module) { Ok(Self::Module(input.parse()?)) + } else if lookahead.peek(keyword::Pallet) { + Ok(Self::Pallet(input.parse()?)) } else if lookahead.peek(keyword::Call) { Ok(Self::Call(input.parse()?)) } else if lookahead.peek(keyword::Storage) { @@ -261,6 +265,7 @@ impl ModulePartKeyword { fn name(&self) -> &'static str { match self { Self::Module(_) => "Module", + Self::Pallet(_) => "Pallet", Self::Call(_) => "Call", Self::Storage(_) => "Storage", Self::Event(_) => "Event", @@ -291,6 +296,7 @@ impl Spanned for ModulePartKeyword { fn span(&self) -> Span { match self { Self::Module(inner) => inner.span(), + Self::Pallet(inner) => inner.span(), Self::Call(inner) => inner.span(), Self::Storage(inner) => inner.span(), Self::Event(inner) => inner.span(), diff --git a/frame/support/test/tests/construct_runtime.rs b/frame/support/test/tests/construct_runtime.rs index 0dba5933eb65b..4c1aa548d9a1e 100644 --- a/frame/support/test/tests/construct_runtime.rs +++ b/frame/support/test/tests/construct_runtime.rs @@ -39,6 +39,9 @@ mod module1 { pub trait Trait: system::Trait {} + // Test that pallet can be used instead of module. + pub type Pallet = Module; + frame_support::decl_module! { pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: ::Origin, system=system @@ -77,6 +80,9 @@ mod module2 { pub trait Trait: system::Trait {} + // Test that pallet can be used instead of module. + pub type Pallet = Module; + frame_support::decl_module! { pub struct Module for enum Call where origin: ::Origin, system=system @@ -140,15 +146,15 @@ frame_support::construct_runtime!( { System: system::{Module, Call, Event, Origin} = 30, Module1_1: module1::::{Module, Call, Storage, Event, Origin}, - Module2: module2::{Module, Call, Storage, Event, Origin}, + Module2: module2::{Pallet, Call, Storage, Event, Origin}, Module1_2: module1::::{Module, Call, Storage, Event, Origin}, - Module1_3: module1::::{Module, Storage} = 6, - Module1_4: module1::::{Module, Call} = 3, - Module1_5: module1::::{Module, Event}, - Module1_6: module1::::{Module, Call, Storage, Event, Origin} = 1, - Module1_7: module1::::{Module, Call, Storage, Event, Origin}, - Module1_8: module1::::{Module, Call, Storage, Event, Origin} = 12, - Module1_9: module1::::{Module, Call, Storage, Event, Origin}, + Module1_3: module1::::{Pallet, Storage} = 6, + Module1_4: module1::::{Pallet, Call} = 3, + Module1_5: module1::::{Pallet, Event}, + Module1_6: module1::::{Pallet, Call, Storage, Event, Origin} = 1, + Module1_7: module1::::{Pallet, Call, Storage, Event, Origin}, + Module1_8: module1::::{Pallet, Call, Storage, Event, Origin} = 12, + Module1_9: module1::::{Pallet, Call, Storage, Event, Origin}, } ); diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs b/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs index a48b4bd097039..a361c5fc15afe 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs @@ -6,8 +6,8 @@ construct_runtime! { Block = Block, NodeBlock = Block, { - System: system::{}, - Pallet1: pallet1::{} = 0, + System: system::{Pallet}, + Pallet1: pallet1::{Pallet} = 0, } } diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr b/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr index 65368666c88fe..f8fef492b16de 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr @@ -1,11 +1,11 @@ error: Module indices are conflicting: Both modules System and Pallet1 are at index 0 --> $DIR/conflicting_index.rs:9:3 | -9 | System: system::{}, +9 | System: system::{Pallet}, | ^^^^^^ error: Module indices are conflicting: Both modules System and Pallet1 are at index 0 --> $DIR/conflicting_index.rs:10:3 | -10 | Pallet1: pallet1::{} = 0, +10 | Pallet1: pallet1::{Pallet} = 0, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs index c949cb41a23fa..a93876d6e98df 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs @@ -6,10 +6,10 @@ construct_runtime! { Block = Block, NodeBlock = Block, { - System: system::{} = 5, - Pallet1: pallet1::{} = 3, - Pallet2: pallet2::{}, - Pallet3: pallet3::{}, + System: system::{Pallet} = 5, + Pallet1: pallet1::{Pallet} = 3, + Pallet2: pallet2::{Pallet}, + Pallet3: pallet3::{Pallet}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr index b792ff5d2a541..2594fdcf52512 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr @@ -1,11 +1,11 @@ error: Module indices are conflicting: Both modules System and Pallet3 are at index 5 --> $DIR/conflicting_index_2.rs:9:3 | -9 | System: system::{} = 5, +9 | System: system::{Pallet} = 5, | ^^^^^^ error: Module indices are conflicting: Both modules System and Pallet3 are at index 5 --> $DIR/conflicting_index_2.rs:12:3 | -12 | Pallet3: pallet3::{}, +12 | Pallet3: pallet3::{Pallet}, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs b/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs new file mode 100644 index 0000000000000..ed1efc5e1afa7 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + UncheckedExtrinsic = UncheckedExtrinsic, + Block = Block, + NodeBlock = Block, + { + System: system::{Pallet, Module}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr b/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr new file mode 100644 index 0000000000000..4e99c0f751390 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr @@ -0,0 +1,11 @@ +error: `Module` cannot be defined when `Pallet` is defined + --> $DIR/conflicting_module_pallet_parts.rs:9:28 + | +9 | System: system::{Pallet, Module}, + | ^^^^^^ + +error: `Module` cannot be defined when `Pallet` is defined + --> $DIR/conflicting_module_pallet_parts.rs:9:20 + | +9 | System: system::{Pallet, Module}, + | ^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr index 66c9fc95cb546..0e4f0e0bfeaa7 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr @@ -1,4 +1,4 @@ -error: expected one of: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` +error: expected one of: `Module`, `Pallet`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` --> $DIR/invalid_module_details_keyword.rs:9:20 | 9 | system: System::{enum}, diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr index 7442c6be3a9a3..53ecdc2bafbb6 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr @@ -1,4 +1,4 @@ -error: expected one of: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` +error: expected one of: `Module`, `Pallet`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` --> $DIR/invalid_module_entry.rs:10:23 | 10 | Balance: balances::{Error}, diff --git a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs index 5eb7df5d18c20..b4c5742c03345 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs +++ b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs @@ -7,7 +7,7 @@ construct_runtime! { UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module}, - Balance: balances::::{Event}, + Balance: balances::::{Pallet, Event}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr index f80b4bd66abdd..f4f0dd9a362e3 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr +++ b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr @@ -1,5 +1,5 @@ error: Instantiable module with no generic `Event` cannot be constructed: module `Balance` must have generic `Event` --> $DIR/missing_event_generic_on_module_with_instance.rs:10:3 | -10 | Balance: balances::::{Event}, +10 | Balance: balances::::{Pallet, Event}, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs index 5e44ae84d87c6..0dcac4a2ded11 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs +++ b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs @@ -7,7 +7,7 @@ construct_runtime! { UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module}, - Balance: balances::::{Origin}, + Balance: balances::::{Pallet, Origin}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr index 0f7d36aafb863..da24e6c34a58b 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr +++ b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr @@ -1,5 +1,5 @@ error: Instantiable module with no generic `Origin` cannot be constructed: module `Balance` must have generic `Origin` --> $DIR/missing_origin_generic_on_module_with_instance.rs:10:3 | -10 | Balance: balances::::{Origin}, +10 | Balance: balances::::{Pallet, Origin}, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs index 4c8331ae442c8..547b35b186da4 100644 --- a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs +++ b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs @@ -6,8 +6,8 @@ construct_runtime! { Block = Block, NodeBlock = Block, { - System: system::{} = 255, - Pallet256: pallet256::{}, + System: system::{Pallet} = 255, + Pallet256: pallet256::{Pallet}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr index c0ef5c8e60b9e..453396c3ef747 100644 --- a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr +++ b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr @@ -1,5 +1,5 @@ error: Module index doesn't fit into u8, index is 256 --> $DIR/more_than_256_modules.rs:10:3 | -10 | Pallet256: pallet256::{}, +10 | Pallet256: pallet256::{Pallet}, | ^^^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/no_part.rs b/frame/support/test/tests/construct_runtime_ui/no_part.rs new file mode 100644 index 0000000000000..6d74014e04f09 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/no_part.rs @@ -0,0 +1,13 @@ +use frame_support::construct_runtime; + +construct_runtime! { + pub enum Runtime where + UncheckedExtrinsic = UncheckedExtrinsic, + Block = Block, + NodeBlock = Block, + { + System: system::{}, + } +} + +fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/no_part.stderr b/frame/support/test/tests/construct_runtime_ui/no_part.stderr new file mode 100644 index 0000000000000..647eeca4f81b9 --- /dev/null +++ b/frame/support/test/tests/construct_runtime_ui/no_part.stderr @@ -0,0 +1,5 @@ +error: Cannot find part `Module` nor `Pallet`, one must be defined + --> $DIR/no_part.rs:9:3 + | +9 | System: system::{}, + | ^^^^^^ From 942c16108de4ac6c39c9f62386a01760c6c3b351 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Tue, 27 Oct 2020 17:34:21 +0100 Subject: [PATCH 03/36] introduce pallet attribute macro currently just with tests, frame_system and other example hasn't been upgraded --- Cargo.lock | 1 + frame/support/procedural/src/lib.rs | 11 +- .../procedural/src/pallet/expand/call.rs | 199 ++++ .../procedural/src/pallet/expand/constants.rs | 138 +++ .../procedural/src/pallet/expand/error.rs | 141 +++ .../procedural/src/pallet/expand/event.rs | 143 +++ .../src/pallet/expand/genesis_build.rs | 77 ++ .../src/pallet/expand/genesis_config.rs | 49 + .../procedural/src/pallet/expand/hooks.rs | 110 ++ .../procedural/src/pallet/expand/instances.rs | 44 + .../procedural/src/pallet/expand/mod.rs | 81 ++ .../src/pallet/expand/pallet_struct.rs | 110 ++ .../procedural/src/pallet/expand/storage.rs | 262 +++++ .../src/pallet/expand/store_trait.rs | 55 + .../src/pallet/expand/type_value.rs | 55 + frame/support/procedural/src/pallet/mod.rs | 49 + .../procedural/src/pallet/parse/call.rs | 237 +++++ .../procedural/src/pallet/parse/config.rs | 385 +++++++ .../procedural/src/pallet/parse/error.rs | 86 ++ .../procedural/src/pallet/parse/event.rs | 256 +++++ .../src/pallet/parse/extra_constants.rs | 121 +++ .../src/pallet/parse/genesis_build.rs | 56 + .../src/pallet/parse/genesis_config.rs | 81 ++ .../procedural/src/pallet/parse/helper.rs | 600 +++++++++++ .../procedural/src/pallet/parse/hooks.rs | 69 ++ .../procedural/src/pallet/parse/inherent.rs | 58 ++ .../procedural/src/pallet/parse/mod.rs | 412 ++++++++ .../procedural/src/pallet/parse/origin.rs | 80 ++ .../src/pallet/parse/pallet_struct.rs | 99 ++ .../procedural/src/pallet/parse/storage.rs | 221 ++++ .../procedural/src/pallet/parse/type_value.rs | 100 ++ .../src/pallet/parse/validate_unsigned.rs | 61 ++ .../support/procedural/src/pallet_version.rs | 2 +- frame/support/procedural/src/storage/mod.rs | 2 + frame/support/procedural/src/transactional.rs | 4 +- frame/support/procedural/tools/src/lib.rs | 16 +- frame/support/src/lib.rs | 977 +++++++++++++++++- frame/support/src/traits.rs | 73 ++ frame/support/test/Cargo.toml | 2 + frame/support/test/tests/pallet.rs | 675 ++++++++++++ .../test/tests/pallet_compatibility.rs | 300 ++++++ .../tests/pallet_compatibility_instance.rs | 311 ++++++ frame/support/test/tests/pallet_instance.rs | 657 ++++++++++++ frame/support/test/tests/pallet_ui.rs | 26 + .../pallet_ui/call_argument_invalid_bound.rs | 27 + .../call_argument_invalid_bound.stderr | 28 + .../call_argument_invalid_bound_2.rs | 27 + .../call_argument_invalid_bound_2.stderr | 11 + .../call_argument_invalid_bound_3.rs | 29 + .../call_argument_invalid_bound_3.stderr | 26 + .../tests/pallet_ui/call_invalid_const.rs | 22 + .../tests/pallet_ui/call_invalid_const.stderr | 5 + .../pallet_ui/call_invalid_origin_type.rs | 22 + .../pallet_ui/call_invalid_origin_type.stderr | 11 + .../tests/pallet_ui/call_missing_weight.rs | 22 + .../pallet_ui/call_missing_weight.stderr | 5 + .../test/tests/pallet_ui/call_no_origin.rs | 22 + .../tests/pallet_ui/call_no_origin.stderr | 5 + .../test/tests/pallet_ui/call_no_return.rs | 22 + .../tests/pallet_ui/call_no_return.stderr | 5 + .../tests/pallet_ui/duplicate_call_attr.rs | 28 + .../pallet_ui/duplicate_call_attr.stderr | 5 + .../tests/pallet_ui/duplicate_store_attr.rs | 26 + .../pallet_ui/duplicate_store_attr.stderr | 5 + .../tests/pallet_ui/error_no_fieldless.rs | 25 + .../tests/pallet_ui/error_no_fieldless.stderr | 5 + .../test/tests/pallet_ui/error_wrong_item.rs | 23 + .../tests/pallet_ui/error_wrong_item.stderr | 5 + .../tests/pallet_ui/error_wrong_item_name.rs | 23 + .../pallet_ui/error_wrong_item_name.stderr | 5 + .../tests/pallet_ui/event_field_not_member.rs | 28 + .../pallet_ui/event_field_not_member.stderr | 28 + .../tests/pallet_ui/event_not_in_trait.rs | 27 + .../tests/pallet_ui/event_not_in_trait.stderr | 7 + .../pallet_ui/event_type_invalid_bound.rs | 28 + .../pallet_ui/event_type_invalid_bound.stderr | 5 + .../pallet_ui/event_type_invalid_bound_2.rs | 28 + .../event_type_invalid_bound_2.stderr | 5 + .../test/tests/pallet_ui/event_wrong_item.rs | 23 + .../tests/pallet_ui/event_wrong_item.stderr | 5 + .../tests/pallet_ui/event_wrong_item_name.rs | 23 + .../pallet_ui/event_wrong_item_name.stderr | 5 + .../genesis_default_not_satisfied.rs | 26 + .../genesis_default_not_satisfied.stderr | 10 + .../genesis_inconsistent_build_config.rs | 23 + .../genesis_inconsistent_build_config.stderr | 5 + .../pallet_ui/genesis_invalid_generic.rs | 23 + .../pallet_ui/genesis_invalid_generic.stderr | 13 + .../tests/pallet_ui/genesis_wrong_name.rs | 23 + .../tests/pallet_ui/genesis_wrong_name.stderr | 5 + .../tests/pallet_ui/hooks_invalid_item.rs | 19 + .../tests/pallet_ui/hooks_invalid_item.stderr | 5 + .../pallet_ui/inconsistent_instance_1.rs | 20 + .../pallet_ui/inconsistent_instance_1.stderr | 29 + .../pallet_ui/inconsistent_instance_2.rs | 20 + .../pallet_ui/inconsistent_instance_2.stderr | 29 + .../pallet_ui/inherent_check_inner_span.rs | 23 + .../inherent_check_inner_span.stderr | 10 + .../tests/pallet_ui/inherent_invalid_item.rs | 23 + .../pallet_ui/inherent_invalid_item.stderr | 5 + .../test/tests/pallet_ui/mod_not_inlined.rs | 5 + .../tests/pallet_ui/mod_not_inlined.stderr | 13 + .../pallet_ui/storage_incomplete_item.rs | 23 + .../pallet_ui/storage_incomplete_item.stderr | 13 + .../storage_invalid_first_generic.rs | 23 + .../storage_invalid_first_generic.stderr | 11 + .../pallet_ui/storage_not_storage_type.rs | 23 + .../pallet_ui/storage_not_storage_type.stderr | 5 + .../pallet_ui/storage_value_no_generic.rs | 23 + .../pallet_ui/storage_value_no_generic.stderr | 5 + .../tests/pallet_ui/storage_wrong_item.rs | 23 + .../tests/pallet_ui/storage_wrong_item.stderr | 5 + .../pallet_ui/store_trait_leak_private.rs | 25 + .../pallet_ui/store_trait_leak_private.stderr | 8 + .../pallet_ui/trait_constant_invalid_bound.rs | 23 + .../trait_constant_invalid_bound.stderr | 11 + .../tests/pallet_ui/trait_invalid_item.rs | 23 + .../tests/pallet_ui/trait_invalid_item.stderr | 5 + .../tests/pallet_ui/trait_no_supertrait.rs | 21 + .../pallet_ui/trait_no_supertrait.stderr | 5 + .../pallet_ui/type_value_error_in_block.rs | 25 + .../type_value_error_in_block.stderr | 5 + .../pallet_ui/type_value_invalid_item.rs | 22 + .../pallet_ui/type_value_invalid_item.stderr | 5 + .../tests/pallet_ui/type_value_no_return.rs | 22 + .../pallet_ui/type_value_no_return.stderr | 5 + frame/support/test/tests/pallet_version.rs | 118 ++- frame/system/src/lib.rs | 13 + 128 files changed, 8933 insertions(+), 29 deletions(-) create mode 100644 frame/support/procedural/src/pallet/expand/call.rs create mode 100644 frame/support/procedural/src/pallet/expand/constants.rs create mode 100644 frame/support/procedural/src/pallet/expand/error.rs create mode 100644 frame/support/procedural/src/pallet/expand/event.rs create mode 100644 frame/support/procedural/src/pallet/expand/genesis_build.rs create mode 100644 frame/support/procedural/src/pallet/expand/genesis_config.rs create mode 100644 frame/support/procedural/src/pallet/expand/hooks.rs create mode 100644 frame/support/procedural/src/pallet/expand/instances.rs create mode 100644 frame/support/procedural/src/pallet/expand/mod.rs create mode 100644 frame/support/procedural/src/pallet/expand/pallet_struct.rs create mode 100644 frame/support/procedural/src/pallet/expand/storage.rs create mode 100644 frame/support/procedural/src/pallet/expand/store_trait.rs create mode 100644 frame/support/procedural/src/pallet/expand/type_value.rs create mode 100644 frame/support/procedural/src/pallet/mod.rs create mode 100644 frame/support/procedural/src/pallet/parse/call.rs create mode 100644 frame/support/procedural/src/pallet/parse/config.rs create mode 100644 frame/support/procedural/src/pallet/parse/error.rs create mode 100644 frame/support/procedural/src/pallet/parse/event.rs create mode 100644 frame/support/procedural/src/pallet/parse/extra_constants.rs create mode 100644 frame/support/procedural/src/pallet/parse/genesis_build.rs create mode 100644 frame/support/procedural/src/pallet/parse/genesis_config.rs create mode 100644 frame/support/procedural/src/pallet/parse/helper.rs create mode 100644 frame/support/procedural/src/pallet/parse/hooks.rs create mode 100644 frame/support/procedural/src/pallet/parse/inherent.rs create mode 100644 frame/support/procedural/src/pallet/parse/mod.rs create mode 100644 frame/support/procedural/src/pallet/parse/origin.rs create mode 100644 frame/support/procedural/src/pallet/parse/pallet_struct.rs create mode 100644 frame/support/procedural/src/pallet/parse/storage.rs create mode 100644 frame/support/procedural/src/pallet/parse/type_value.rs create mode 100644 frame/support/procedural/src/pallet/parse/validate_unsigned.rs create mode 100644 frame/support/test/tests/pallet.rs create mode 100644 frame/support/test/tests/pallet_compatibility.rs create mode 100644 frame/support/test/tests/pallet_compatibility_instance.rs create mode 100644 frame/support/test/tests/pallet_instance.rs create mode 100644 frame/support/test/tests/pallet_ui.rs create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.rs create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs create mode 100644 frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_const.rs create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_const.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs create mode 100644 frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_missing_weight.rs create mode 100644 frame/support/test/tests/pallet_ui/call_missing_weight.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_no_origin.rs create mode 100644 frame/support/test/tests/pallet_ui/call_no_origin.stderr create mode 100644 frame/support/test/tests/pallet_ui/call_no_return.rs create mode 100644 frame/support/test/tests/pallet_ui/call_no_return.stderr create mode 100644 frame/support/test/tests/pallet_ui/duplicate_call_attr.rs create mode 100644 frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr create mode 100644 frame/support/test/tests/pallet_ui/duplicate_store_attr.rs create mode 100644 frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr create mode 100644 frame/support/test/tests/pallet_ui/error_no_fieldless.rs create mode 100644 frame/support/test/tests/pallet_ui/error_no_fieldless.stderr create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item.rs create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item_name.rs create mode 100644 frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_field_not_member.rs create mode 100644 frame/support/test/tests/pallet_ui/event_field_not_member.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_not_in_trait.rs create mode 100644 frame/support/test/tests/pallet_ui/event_not_in_trait.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs create mode 100644 frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item.rs create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item_name.rs create mode 100644 frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr create mode 100644 frame/support/test/tests/pallet_ui/genesis_wrong_name.rs create mode 100644 frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr create mode 100644 frame/support/test/tests/pallet_ui/hooks_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs create mode 100644 frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr create mode 100644 frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs create mode 100644 frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr create mode 100644 frame/support/test/tests/pallet_ui/inherent_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/mod_not_inlined.rs create mode 100644 frame/support/test/tests/pallet_ui/mod_not_inlined.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_incomplete_item.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_not_storage_type.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_value_no_generic.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr create mode 100644 frame/support/test/tests/pallet_ui/storage_wrong_item.rs create mode 100644 frame/support/test/tests/pallet_ui/storage_wrong_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/store_trait_leak_private.rs create mode 100644 frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr create mode 100644 frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs create mode 100644 frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr create mode 100644 frame/support/test/tests/pallet_ui/trait_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/trait_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/trait_no_supertrait.rs create mode 100644 frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr create mode 100644 frame/support/test/tests/pallet_ui/type_value_error_in_block.rs create mode 100644 frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr create mode 100644 frame/support/test/tests/pallet_ui/type_value_invalid_item.rs create mode 100644 frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr create mode 100644 frame/support/test/tests/pallet_ui/type_value_no_return.rs create mode 100644 frame/support/test/tests/pallet_ui/type_value_no_return.stderr diff --git a/Cargo.lock b/Cargo.lock index 3a87dfec66403..cfe9884d08351 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1743,6 +1743,7 @@ version = "2.0.0" dependencies = [ "frame-metadata", "frame-support", + "frame-system", "parity-scale-codec", "pretty_assertions", "rustversion", diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index a6fb58846cbad..26bb99c892853 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -21,12 +21,14 @@ mod storage; mod construct_runtime; +mod pallet; mod pallet_version; mod transactional; mod debug_no_bound; mod clone_no_bound; mod partial_eq_no_bound; +pub(crate) use storage::INHERENT_INSTANCE_NAME; use proc_macro::TokenStream; /// Declares strongly-typed wrappers around codec-compatible types in storage. @@ -274,7 +276,8 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// /// We provide support for the following module parts in a pallet: /// -/// - `Module` +/// - `Pallet` or `Module`, mandatory. (one or the other must be provided depending if pallet use +/// pallet attribute macro or old decl_module macro /// - `Call` /// - `Storage` /// - `Event` or `Event` (if the event is generic) @@ -305,6 +308,12 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream { construct_runtime::construct_runtime(input) } +/// Macro to define a pallet. Docs are at `frame_support::pallet`. +#[proc_macro_attribute] +pub fn pallet(attr: TokenStream, item: TokenStream) -> TokenStream { + pallet::pallet(attr, item) +} + /// Execute the annotated function in a new storage transaction. /// /// The return type of the annotated function must be `Result`. All changes to storage performed diff --git a/frame/support/procedural/src/pallet/expand/call.rs b/frame/support/procedural/src/pallet/expand/call.rs new file mode 100644 index 0000000000000..a5ad68cd90640 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/call.rs @@ -0,0 +1,199 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use frame_support_procedural_tools::clean_type_string; +use syn::spanned::Spanned; + +/// * Generate enum call and implement various trait on it. +/// * Implement Callable and call_function on `Pallet` +pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_decl_bounded_gen = &def.type_decl_bounded_generics(); + let type_use_gen = &def.type_use_generics(); + let call_ident = syn::Ident::new("Call", def.call.attr_span.clone()); + let pallet_ident = &def.pallet_struct.pallet; + let where_clause = &def.call.where_clause; + + let fn_ = def.call.methods.iter().map(|method| &method.fn_).collect::>(); + + let fn_weight = def.call.methods.iter().map(|method| &method.weight); + + let fn_doc = def.call.methods.iter().map(|method| &method.docs).collect::>(); + + let args_name = def.call.methods.iter() + .map(|method| method.args.iter().map(|(_, name, _)| name.clone()).collect::>()) + .collect::>(); + + let args_type = def.call.methods.iter() + .map(|method| method.args.iter().map(|(_, _, type_)| type_.clone()).collect::>()) + .collect::>(); + + let args_compact_attr = def.call.methods.iter().map(|method| { + method.args.iter() + .map(|(is_compact, _, type_)| { + if *is_compact { + quote::quote_spanned!(type_.span() => #[codec(compact)] ) + } else { + quote::quote!() + } + }) + .collect::>() + }); + + let args_metadata_type = def.call.methods.iter().map(|method| { + method.args.iter() + .map(|(is_compact, _, type_)| { + let final_type = if *is_compact { + quote::quote!(Compact<#type_>) + } else { + quote::quote!(#type_) + }; + clean_type_string(&final_type.to_string()) + }) + .collect::>() + }); + + quote::quote_spanned!(def.call.attr_span => + #[derive( + #frame_support::RuntimeDebugNoBound, + #frame_support::CloneNoBound, + #frame_support::EqNoBound, + #frame_support::PartialEqNoBound, + #frame_support::codec::Encode, + #frame_support::codec::Decode, + )] + #[allow(non_camel_case_types)] + pub enum #call_ident<#type_decl_bounded_gen> #where_clause { + #[doc(hidden)] + #[codec(skip)] + __Ignore( + #frame_support::sp_std::marker::PhantomData<(#type_use_gen,)>, + #frame_support::Never, + ), + #( #fn_( #( #args_compact_attr #args_type ),* ), )* + } + + impl<#type_impl_gen> #frame_support::dispatch::GetDispatchInfo + for #call_ident<#type_use_gen> + #where_clause + { + fn get_dispatch_info(&self) -> #frame_support::dispatch::DispatchInfo { + match *self { + #( + Self::#fn_ ( #( ref #args_name, )* ) => { + let base_weight = #fn_weight; + + let weight = < + dyn #frame_support::dispatch::WeighData<( #( & #args_type, )* )> + >::weigh_data(&base_weight, ( #( #args_name, )* )); + + let class = < + dyn #frame_support::dispatch::ClassifyDispatch< + ( #( & #args_type, )* ) + > + >::classify_dispatch(&base_weight, ( #( #args_name, )* )); + + let pays_fee = < + dyn #frame_support::dispatch::PaysFee<( #( & #args_type, )* )> + >::pays_fee(&base_weight, ( #( #args_name, )* )); + + #frame_support::dispatch::DispatchInfo { + weight, + class, + pays_fee, + } + }, + )* + Self::__Ignore(_, _) => unreachable!("__Ignore cannot be used"), + } + } + } + + impl<#type_impl_gen> #frame_support::dispatch::GetCallName for #call_ident<#type_use_gen> + #where_clause + { + fn get_call_name(&self) -> &'static str { + match *self { + #( Self::#fn_(..) => stringify!(#fn_), )* + Self::__Ignore(_, _) => unreachable!("__PhantomItem cannot be used."), + } + } + + fn get_call_names() -> &'static [&'static str] { + &[ #( stringify!(#fn_), )* ] + } + } + + impl<#type_impl_gen> #frame_support::traits::UnfilteredDispatchable + for #call_ident<#type_use_gen> + #where_clause + { + type Origin = #frame_system::pallet_prelude::OriginFor; + fn dispatch_bypass_filter( + self, + origin: Self::Origin + ) -> #frame_support::dispatch::DispatchResultWithPostInfo { + match self { + #( + Self::#fn_( #( #args_name, )* ) => + <#pallet_ident<#type_use_gen>>::#fn_(origin, #( #args_name, )* ) + .map(Into::into).map_err(Into::into), + )* + Self::__Ignore(_, _) => { + let _ = origin; // Use origin for empty Call enum + unreachable!("__PhantomItem cannot be used."); + }, + } + } + } + + impl<#type_impl_gen> #frame_support::dispatch::Callable for #pallet_ident<#type_use_gen> + #where_clause + { + type Call = #call_ident<#type_use_gen>; + } + + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #where_clause { + #[doc(hidden)] + pub fn call_functions() -> &'static [#frame_support::dispatch::FunctionMetadata] { + &[ #( + #frame_support::dispatch::FunctionMetadata { + name: #frame_support::dispatch::DecodeDifferent::Encode(stringify!(#fn_)), + arguments: #frame_support::dispatch::DecodeDifferent::Encode( + &[ #( + #frame_support::dispatch::FunctionArgumentMetadata { + name: #frame_support::dispatch::DecodeDifferent::Encode( + stringify!(#args_name) + ), + ty: #frame_support::dispatch::DecodeDifferent::Encode( + #args_metadata_type + ), + }, + )* ] + ), + documentation: #frame_support::dispatch::DecodeDifferent::Encode( + &[ #( #fn_doc ),* ] + ), + }, + )* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/constants.rs b/frame/support/procedural/src/pallet/expand/constants.rs new file mode 100644 index 0000000000000..25cceb7449e16 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/constants.rs @@ -0,0 +1,138 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use frame_support_procedural_tools::clean_type_string; +use quote::ToTokens; + +struct ConstDef { + /// Name of the associated type. + pub ident: syn::Ident, + /// The type in Get, e.g. `u32` in `type Foo: Get;`, but `Self` is replaced by `T` + pub type_: syn::Type, + /// The doc associated + pub doc: Vec, + /// default_byte implementation + pub default_byte_impl: proc_macro2::TokenStream, +} + +/// * Impl fn module_constant_metadata for pallet. +pub fn expand_constants(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let type_impl_gen = &def.type_impl_generics(); + let type_decl_gen = &def.type_decl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + + let mut where_clauses = vec![&def.config.where_clause]; + where_clauses.extend(def.extra_constants.iter().map(|d| &d.where_clause)); + let completed_where_clause = super::merge_where_clauses(&where_clauses); + + let config_consts = def.config.consts_metadata.iter().map(|const_| { + let ident = &const_.ident; + let const_type = &const_.type_; + + ConstDef { + ident: const_.ident.clone(), + type_: const_.type_.clone(), + doc: const_.doc.clone(), + default_byte_impl: quote::quote!( + let value = >::get(); + #frame_support::codec::Encode::encode(&value) + ), + } + }); + + let extra_consts = def.extra_constants.iter().flat_map(|d| &d.extra_constants).map(|const_| { + let ident = &const_.ident; + + ConstDef { + ident: const_.ident.clone(), + type_: const_.type_.clone(), + doc: const_.doc.clone(), + default_byte_impl: quote::quote!( + let value = >::#ident(); + #frame_support::codec::Encode::encode(&value) + ), + } + }); + + let consts = config_consts.chain(extra_consts) + .map(|const_| { + let const_type = &const_.type_; + let const_type_str = clean_type_string(&const_type.to_token_stream().to_string()); + let ident = &const_.ident; + let ident_str = format!("{}", ident); + let doc = const_.doc.clone().into_iter(); + let default_byte_impl = &const_.default_byte_impl; + let default_byte_getter = syn::Ident::new( + &format!("{}DefaultByteGetter", ident), + ident.span() + ); + + quote::quote!({ + #[allow(non_upper_case_types)] + #[allow(non_camel_case_types)] + struct #default_byte_getter<#type_decl_gen>( + #frame_support::sp_std::marker::PhantomData<(#type_use_gen)> + ); + + impl<#type_impl_gen> #frame_support::dispatch::DefaultByte for + #default_byte_getter<#type_use_gen> + #completed_where_clause + { + fn default_byte(&self) -> #frame_support::sp_std::vec::Vec { + #default_byte_impl + } + } + + unsafe impl<#type_impl_gen> Send for #default_byte_getter<#type_use_gen> + #completed_where_clause + {} + unsafe impl<#type_impl_gen> Sync for #default_byte_getter<#type_use_gen> + #completed_where_clause + {} + + #frame_support::dispatch::ModuleConstantMetadata { + name: #frame_support::dispatch::DecodeDifferent::Encode(#ident_str), + ty: #frame_support::dispatch::DecodeDifferent::Encode(#const_type_str), + value: #frame_support::dispatch::DecodeDifferent::Encode( + #frame_support::dispatch::DefaultByteGetter( + &#default_byte_getter::<#type_use_gen>( + #frame_support::sp_std::marker::PhantomData + ) + ) + ), + documentation: #frame_support::dispatch::DecodeDifferent::Encode( + &[ #( #doc ),* ] + ), + } + }) + }); + + quote::quote!( + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause{ + + #[doc(hidden)] + pub fn module_constants_metadata() + -> &'static [#frame_support::dispatch::ModuleConstantMetadata] + { + &[ #( #consts ),* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/error.rs b/frame/support/procedural/src/pallet/expand/error.rs new file mode 100644 index 0000000000000..e60d717ff7dd2 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/error.rs @@ -0,0 +1,141 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use syn::spanned::Spanned; + +/// * impl various trait on Error +/// * impl ModuleErrorMetadata for Error +pub fn expand_error(def: &mut Def) -> proc_macro2::TokenStream { + let error = if let Some(error) = &def.error { + error + } else { + return Default::default() + }; + + let error_item_span = + def.item.content.as_mut().expect("Checked by def parser").1[error.index].span(); + let error_ident = &error.error; + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let config_where_clause = &def.config.where_clause; + + let phantom_variant: syn::Variant = syn::parse_quote!( + #[doc(hidden)] + __Ignore( + #frame_support::sp_std::marker::PhantomData<(#type_use_gen)>, + #frame_support::Never, + ) + ); + + let as_u8_matches = error.variants.iter().enumerate() + .map(|(i, (variant, _))| quote::quote!(Self::#variant => #i as u8,)); + + let as_str_matches = error.variants.iter() + .map(|(variant, _)| { + let variant_str = format!("{}", variant); + quote::quote!(Self::#variant => #variant_str,) + }); + + let metadata = error.variants.iter() + .map(|(variant, doc)| { + let variant_str = format!("{}", variant); + quote::quote!( + #frame_support::error::ErrorMetadata { + name: #frame_support::error::DecodeDifferent::Encode(#variant_str), + documentation: #frame_support::error::DecodeDifferent::Encode(&[ #( #doc, )* ]), + }, + ) + }); + + let error_item = { + let item = &mut def.item.content.as_mut().expect("Checked by def parser").1[error.index]; + if let syn::Item::Enum(item) = item { + item + } else { + unreachable!("Checked by event parser") + } + }; + + error_item.variants.insert(0, phantom_variant); + + quote::quote_spanned!(error_item_span => + impl<#type_impl_gen> #frame_support::sp_std::fmt::Debug for #error_ident<#type_use_gen> + #config_where_clause + { + fn fmt(&self, f: &mut #frame_support::sp_std::fmt::Formatter<'_>) + -> #frame_support::sp_std::fmt::Result + { + f.write_str(self.as_str()) + } + } + + impl<#type_impl_gen> #error_ident<#type_use_gen> #config_where_clause { + pub fn as_u8(&self) -> u8 { + match &self { + Self::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"), + #( #as_u8_matches )* + } + } + + pub fn as_str(&self) -> &'static str { + match &self { + Self::__Ignore(_, _) => unreachable!("`__Ignore` can never be constructed"), + #( #as_str_matches )* + } + } + } + + impl<#type_impl_gen> From<#error_ident<#type_use_gen>> for &'static str + #config_where_clause + { + fn from(err: #error_ident<#type_use_gen>) -> &'static str { + err.as_str() + } + } + + impl<#type_impl_gen> From<#error_ident<#type_use_gen>> + for #frame_support::sp_runtime::DispatchError + #config_where_clause + { + fn from(err: #error_ident<#type_use_gen>) -> Self { + let index = < + ::PalletInfo + as #frame_support::traits::PalletInfo + >::index::>() + .expect("Every active module has an index in the runtime; qed") as u8; + + #frame_support::sp_runtime::DispatchError::Module { + index, + error: err.as_u8(), + message: Some(err.as_str()), + } + } + } + + impl<#type_impl_gen> #frame_support::error::ModuleErrorMetadata + for #error_ident<#type_use_gen> + #config_where_clause + { + fn metadata() -> &'static [#frame_support::error::ErrorMetadata] { + &[ #( #metadata )* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/event.rs b/frame/support/procedural/src/pallet/expand/event.rs new file mode 100644 index 0000000000000..33e4224cd36a1 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/event.rs @@ -0,0 +1,143 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use syn::spanned::Spanned; + +/// * Add __Ignore variant on Event +/// * Impl various trait on Event including metadata +/// * if deposit_event is defined, implement deposit_event on module. +pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream { + let event = if let Some(event) = &def.event { + event + } else { + return Default::default() + }; + + let event_where_clause = &event.where_clause; + + // NOTE: actually event where clause must be a subset of config where clause because of + // `type Event: From>`. But we merge either way for potential better error message + let completed_where_clause = super::merge_where_clauses(&[ + &event.where_clause, + &def.config.where_clause, + ]); + + let event_ident = &event.event; + let frame_system = &def.frame_system; + let frame_support = &def.frame_support; + let event_use_gen = &event.event_use_gen(); + let event_impl_gen= &event.event_impl_gen(); + let metadata = event.metadata.iter() + .map(|(ident, args, docs)| { + let name = format!("{}", ident); + quote::quote!( + #frame_support::event::EventMetadata { + name: #frame_support::event::DecodeDifferent::Encode(#name), + arguments: #frame_support::event::DecodeDifferent::Encode(&[ + #( #args, )* + ]), + documentation: #frame_support::event::DecodeDifferent::Encode(&[ + #( #docs, )* + ]), + }, + ) + }); + + let event_item_span = + def.item.content.as_mut().expect("Checked by def parser").1[event.index].span(); + + let event_item = { + let item = &mut def.item.content.as_mut().expect("Checked by def parser").1[event.index]; + if let syn::Item::Enum(item) = item { + item + } else { + unreachable!("Checked by event parser") + } + }; + + // Phantom data is added for generic event. + if event.is_generic { + let variant = syn::parse_quote!( + #[doc(hidden)] + #[codec(skip)] + __Ignore( + #frame_support::sp_std::marker::PhantomData<(#event_use_gen)>, + #frame_support::Never, + ) + ); + + // Push ignore variant at the end. + event_item.variants.push(variant); + } + + // derive some traits because system event require Clone, FullCodec, Eq, PartialEq and Debug + event_item.attrs.push(syn::parse_quote!( + #[derive( + #frame_support::CloneNoBound, + #frame_support::EqNoBound, + #frame_support::PartialEqNoBound, + #frame_support::RuntimeDebugNoBound, + #frame_support::codec::Encode, + #frame_support::codec::Decode, + )] + )); + + + let deposit_event = if let Some((fn_vis, fn_span)) = &event.deposit_event { + let event_use_gen = &event.event_use_gen(); + let trait_use_gen = &def.trait_use_generics(); + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + + quote::quote_spanned!(*fn_span => + impl<#type_impl_gen> Pallet<#type_use_gen> #completed_where_clause { + #fn_vis fn deposit_event(event: Event<#event_use_gen>) { + let event = < + ::Event as + From> + >::from(event); + + let event = < + ::Event as + Into<::Event> + >::into(event); + + <#frame_system::Pallet>::deposit_event(event) + } + } + ) + } else { + Default::default() + }; + + quote::quote_spanned!(event_item_span => + #deposit_event + + impl<#event_impl_gen> From<#event_ident<#event_use_gen>> for () #event_where_clause { + fn from(_: #event_ident<#event_use_gen>) -> () { () } + } + + impl<#event_impl_gen> #event_ident<#event_use_gen> #event_where_clause { + #[allow(dead_code)] + #[doc(hidden)] + pub fn metadata() -> &'static [#frame_support::event::EventMetadata] { + &[ #( #metadata )* ] + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/genesis_build.rs b/frame/support/procedural/src/pallet/expand/genesis_build.rs new file mode 100644 index 0000000000000..71eebd25e349d --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/genesis_build.rs @@ -0,0 +1,77 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use syn::spanned::Spanned; + +/// * implement the trait `sp_runtime::BuildModuleGenesisStorage` +/// * add #[cfg(features = "std")] to GenesisBuild implementation. +pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream { + let genesis_config = if let Some(genesis_config) = &def.genesis_config { + genesis_config + } else { + return Default::default() + }; + + let frame_support = &def.frame_support; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let trait_use_gen = if def.config.has_instance { + quote::quote!(T, I) + } else { + // `__InherentHiddenInstance` used by construct_runtime here is alias for `()` + quote::quote!(T, ()) + }; + let gen_cfg_ident = &genesis_config.genesis_config; + + let gen_cfg_use_gen = match (genesis_config.has_trait, genesis_config.has_instance) { + (false, false) => (quote::quote!()), + (true, false) => (quote::quote!(T)), + (true, true) => (quote::quote!(T, I)), + (false, true) => unreachable!("Checked by def parser"), + }; + + let genesis_build = def.genesis_build.as_ref().expect("Checked by def parser"); + let genesis_build_item = &mut def.item.content.as_mut() + .expect("Checked by def parser").1[genesis_build.index]; + + let genesis_build_item_impl = if let syn::Item::Impl(impl_) = genesis_build_item { + impl_ + } else { + unreachable!("Checked by genesis_build parser") + }; + + genesis_build_item_impl.attrs.push(syn::parse_quote!( #[cfg(feature = "std")] )); + let where_clause = &genesis_build.where_clause; + + quote::quote_spanned!(genesis_build_item.span() => + #[cfg(feature = "std")] + impl<#type_impl_gen> #frame_support::sp_runtime::BuildModuleGenesisStorage<#trait_use_gen> + for #gen_cfg_ident<#gen_cfg_use_gen> #where_clause + { + fn build_module_genesis_storage( + &self, + storage: &mut #frame_support::sp_runtime::Storage, + ) -> std::result::Result<(), std::string::String> { + #frame_support::BasicExternalities::execute_with_storage(storage, || { + >::build(self); + Ok(()) + }) + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/genesis_config.rs b/frame/support/procedural/src/pallet/expand/genesis_config.rs new file mode 100644 index 0000000000000..db67eaeaee74f --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/genesis_config.rs @@ -0,0 +1,49 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; + +/// * add various derive trait on GenesisConfig struct. +pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream { + let genesis_config = if let Some(genesis_config) = &def.genesis_config { + genesis_config + } else { + return Default::default() + }; + let frame_support = &def.frame_support; + + let genesis_config_item = &mut def.item.content.as_mut() + .expect("Checked by def parser").1[genesis_config.index]; + + match genesis_config_item { + syn::Item::Enum(syn::ItemEnum { attrs, ..}) | + syn::Item::Struct(syn::ItemStruct { attrs, .. }) | + syn::Item::Type(syn::ItemType { attrs, .. }) => { + attrs.push(syn::parse_quote!( #[cfg(feature = "std")] )); + attrs.push(syn::parse_quote!( + #[derive(#frame_support::Serialize, #frame_support::Deserialize)] + )); + attrs.push(syn::parse_quote!( #[serde(rename_all = "camelCase")] )); + attrs.push(syn::parse_quote!( #[serde(deny_unknown_fields)] )); + attrs.push(syn::parse_quote!( #[serde(bound(serialize = ""))] )); + attrs.push(syn::parse_quote!( #[serde(bound(deserialize = ""))] )); + }, + _ => unreachable!("Checked by genesis_config parser"), + } + + Default::default() +} diff --git a/frame/support/procedural/src/pallet/expand/hooks.rs b/frame/support/procedural/src/pallet/expand/hooks.rs new file mode 100644 index 0000000000000..8ae7738bcc176 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/hooks.rs @@ -0,0 +1,110 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use syn::spanned::Spanned; + +/// * implement the individual traits using the Hooks trait +pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + let where_clause = &def.hooks.where_clause; + let frame_system = &def.frame_system; + + let hooks_item_span = def.item.content.as_mut() + .expect("Checked by def parser").1[def.hooks.index].span(); + + quote::quote_spanned!(hooks_item_span => + impl<#type_impl_gen> + #frame_support::traits::OnFinalize<::BlockNumber> + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_finalize(n: ::BlockNumber) { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::on_finalize(n) + } + } + + impl<#type_impl_gen> + #frame_support::traits::OnInitialize<::BlockNumber> + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_initialize( + n: ::BlockNumber + ) -> #frame_support::weights::Weight { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::on_initialize(n) + } + } + + impl<#type_impl_gen> + #frame_support::traits::OnRuntimeUpgrade + for #pallet_ident<#type_use_gen> #where_clause + { + fn on_runtime_upgrade() -> #frame_support::weights::Weight { + let result = < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::on_runtime_upgrade(); + + #frame_support::crate_to_pallet_version!() + .put_into_storage::<::PalletInfo, Self>(); + + let additional_write = < + ::DbWeight as #frame_support::traits::Get<_> + >::get().writes(1); + + result.saturating_add(additional_write) + } + } + + impl<#type_impl_gen> + #frame_support::traits::OffchainWorker<::BlockNumber> + for #pallet_ident<#type_use_gen> #where_clause + { + fn offchain_worker(n: ::BlockNumber) { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::offchain_worker(n) + } + } + + impl<#type_impl_gen> + #frame_support::traits::IntegrityTest + for #pallet_ident<#type_use_gen> #where_clause + { + fn integrity_test() { + < + Self as #frame_support::traits::Hooks< + ::BlockNumber + > + >::integrity_test() + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/instances.rs b/frame/support/procedural/src/pallet/expand/instances.rs new file mode 100644 index 0000000000000..46783d71079c5 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/instances.rs @@ -0,0 +1,44 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use proc_macro2::Span; +use crate::pallet::Def; + +/// * Provide inherent instance to be used by construct_runtime +/// * Provide Instance0 .. Instance16 for instantiable pallet +pub fn expand_instances(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let inherent_ident = syn::Ident::new(crate::INHERENT_INSTANCE_NAME, Span::call_site()); + let instances = if def.config.has_instance { + (0..16).map(|i| syn::Ident::new(&format!("Instance{}", i), Span::call_site())).collect() + } else { + vec![] + }; + + quote::quote!( + /// Hidden instance generated to be internally used when module is used without + /// instance. + #[doc(hidden)] + pub type #inherent_ident = (); + + #( + /// Generated module instance + #[derive(Clone, Copy, PartialEq, Eq, #frame_support::RuntimeDebugNoBound)] + pub struct #instances; + )* + ) +} diff --git a/frame/support/procedural/src/pallet/expand/mod.rs b/frame/support/procedural/src/pallet/expand/mod.rs new file mode 100644 index 0000000000000..6bfc1f9a9ee48 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/mod.rs @@ -0,0 +1,81 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +mod constants; +mod pallet_struct; +mod call; +mod error; +mod event; +mod storage; +mod hooks; +mod store_trait; +mod instances; +mod genesis_build; +mod genesis_config; +mod type_value; + +use crate::pallet::Def; +use quote::ToTokens; + +/// Merge where clause together, `where` token span is taken from the first not none one. +pub fn merge_where_clauses(clauses: &[&Option]) -> Option { + let mut clauses = clauses.iter().filter_map(|f| f.as_ref()); + let mut res = clauses.next()?.clone(); + for other in clauses { + res.predicates.extend(other.predicates.iter().cloned()) + } + Some(res) +} + +/// Expand definition, in particular: +/// * add some bounds and variants to type defined, +/// * create some new types, +/// * impl stuff on them. +pub fn expand(mut def: Def) -> proc_macro2::TokenStream { + let constants = constants::expand_constants(&mut def); + let pallet_struct = pallet_struct::expand_pallet_struct(&mut def); + let call = call::expand_call(&mut def); + let error = error::expand_error(&mut def); + let event = event::expand_event(&mut def); + let storages = storage::expand_storages(&mut def); + let instances = instances::expand_instances(&mut def); + let store_trait = store_trait::expand_store_trait(&mut def); + let hooks = hooks::expand_hooks(&mut def); + let genesis_build = genesis_build::expand_genesis_build(&mut def); + let genesis_config = genesis_config::expand_genesis_config(&mut def); + let type_values = type_value::expand_type_values(&mut def); + + let new_items = quote::quote!( + #constants + #pallet_struct + #call + #error + #event + #storages + #instances + #store_trait + #hooks + #genesis_build + #genesis_config + #type_values + ); + + def.item.content.as_mut().expect("This is checked by parsing").1 + .push(syn::Item::Verbatim(new_items)); + + def.item.into_token_stream() +} diff --git a/frame/support/procedural/src/pallet/expand/pallet_struct.rs b/frame/support/procedural/src/pallet/expand/pallet_struct.rs new file mode 100644 index 0000000000000..53e102013a335 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/pallet_struct.rs @@ -0,0 +1,110 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; + +/// * Add derive trait on Pallet +/// * Implement GetPalletVersion on Pallet +/// * Implement OnGenesis on Pallet +/// * Implement ModuleErrorMetadata on Pallet +pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + let config_where_clause = &def.config.where_clause; + + let pallet_item = { + let pallet_module_items = &mut def.item.content.as_mut().expect("Checked by def").1; + let item = &mut pallet_module_items[def.pallet_struct.index]; + if let syn::Item::Struct(item) = item { + item + } else { + unreachable!("Checked by pallet struct parser") + } + }; + + pallet_item.attrs.push(syn::parse_quote!( + #[derive( + #frame_support::CloneNoBound, + #frame_support::EqNoBound, + #frame_support::PartialEqNoBound, + #frame_support::RuntimeDebugNoBound, + )] + )); + + let module_error_metadata = if let Some(error_def) = &def.error { + let error_ident = &error_def.error; + quote::quote!( + impl<#type_impl_gen> #frame_support::error::ModuleErrorMetadata + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn metadata() -> &'static [#frame_support::error::ErrorMetadata] { + < + #error_ident<#type_use_gen> as #frame_support::error::ModuleErrorMetadata + >::metadata() + } + } + ) + } else { + quote::quote!( + impl<#type_impl_gen> #frame_support::error::ModuleErrorMetadata + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn metadata() -> &'static [#frame_support::error::ErrorMetadata] { + &[] + } + } + ) + }; + + quote::quote!( + #module_error_metadata + + // Implement `GetPalletVersion` for `Pallet` + impl<#type_impl_gen> #frame_support::traits::GetPalletVersion + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn current_version() -> #frame_support::traits::PalletVersion { + #frame_support::crate_to_pallet_version!() + } + + fn storage_version() -> Option<#frame_support::traits::PalletVersion> { + let key = #frame_support::traits::PalletVersion::storage_key::< + ::PalletInfo, Self + >().expect("Every active pallet has a name in the runtime; qed"); + + #frame_support::storage::unhashed::get(&key) + } + } + + // Implement `OnGenesis` for `Pallet` + impl<#type_impl_gen> #frame_support::traits::OnGenesis + for #pallet_ident<#type_use_gen> + #config_where_clause + { + fn on_genesis() { + #frame_support::crate_to_pallet_version!() + .put_into_storage::<::PalletInfo, Self>(); + } + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/storage.rs b/frame/support/procedural/src/pallet/expand/storage.rs new file mode 100644 index 0000000000000..7f6e6cac5f16b --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/storage.rs @@ -0,0 +1,262 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use crate::pallet::parse::storage::{Metadata, QueryKind}; +use frame_support_procedural_tools::clean_type_string; + +/// Generate the prefix_ident related the the storage. +/// prefix_ident is used for the prefix struct to be given to storage as first generic param. +fn prefix_ident(storage_ident: &syn::Ident) -> syn::Ident { + syn::Ident::new(&format!("_GeneratedPrefixForStorage{}", storage_ident), storage_ident.span()) +} + +/// * generate StoragePrefix structs (e.g. for a storage `MyStorage` a struct with the name +/// `_GeneratedPrefixForStorage$NameOfStorage` is generated) and implements StorageInstance trait. +/// * replace the first generic `_` by the genereted prefix structure +/// * generate metadatas +pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream { + let frame_support = &def.frame_support; + let frame_system = &def.frame_system; + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + + // Replace first arg `_` by the generated prefix structure. + // Add `#[allow(type_alias_bounds)]` + for storage_def in def.storages.iter_mut() { + let item = &mut def.item.content.as_mut().expect("Checked by def").1[storage_def.index]; + + let typ_item = if let syn::Item::Type(t) = item { + t + } else { + unreachable!("Checked by def"); + }; + + typ_item.attrs.push(syn::parse_quote!(#[allow(type_alias_bounds)])); + + let typ_path = if let syn::Type::Path(p) = &mut *typ_item.ty { + p + } else { + unreachable!("Checked by def"); + }; + + let args = if let syn::PathArguments::AngleBracketed(args) = + &mut typ_path.path.segments[0].arguments + { + args + } else { + unreachable!("Checked by def"); + }; + + let prefix_ident = prefix_ident(&storage_def.ident); + args.args[0] = syn::parse_quote!( #prefix_ident<#type_use_gen> ); + } + + let entries = def.storages.iter() + .map(|storage| { + let docs = &storage.docs; + + let ident = &storage.ident; + let gen = &def.type_use_generics(); + let full_ident = quote::quote!( #ident<#gen> ); + + let metadata_trait = match &storage.metadata { + Metadata::Value { .. } => + quote::quote!(#frame_support::storage::types::StorageValueMetadata), + Metadata::Map { .. } => + quote::quote!(#frame_support::storage::types::StorageMapMetadata), + Metadata::DoubleMap { .. } => + quote::quote!(#frame_support::storage::types::StorageDoubleMapMetadata), + }; + + let ty = match &storage.metadata { + Metadata::Value { value } => { + let value = clean_type_string("e::quote!(#value).to_string()); + quote::quote!( + #frame_support::metadata::StorageEntryType::Plain( + #frame_support::metadata::DecodeDifferent::Encode(#value) + ) + ) + }, + Metadata::Map { key, value } => { + let value = clean_type_string("e::quote!(#value).to_string()); + let key = clean_type_string("e::quote!(#key).to_string()); + quote::quote!( + #frame_support::metadata::StorageEntryType::Map { + hasher: <#full_ident as #metadata_trait>::HASHER, + key: #frame_support::metadata::DecodeDifferent::Encode(#key), + value: #frame_support::metadata::DecodeDifferent::Encode(#value), + unused: false, + } + ) + }, + Metadata::DoubleMap { key1, key2, value } => { + let value = clean_type_string("e::quote!(#value).to_string()); + let key1 = clean_type_string("e::quote!(#key1).to_string()); + let key2 = clean_type_string("e::quote!(#key2).to_string()); + quote::quote!( + #frame_support::metadata::StorageEntryType::DoubleMap { + hasher: <#full_ident as #metadata_trait>::HASHER1, + key2_hasher: <#full_ident as #metadata_trait>::HASHER2, + key1: #frame_support::metadata::DecodeDifferent::Encode(#key1), + key2: #frame_support::metadata::DecodeDifferent::Encode(#key2), + value: #frame_support::metadata::DecodeDifferent::Encode(#value), + } + ) + } + }; + + quote::quote_spanned!(storage.ident.span() => + #frame_support::metadata::StorageEntryMetadata { + name: #frame_support::metadata::DecodeDifferent::Encode( + <#full_ident as #metadata_trait>::NAME + ), + modifier: <#full_ident as #metadata_trait>::MODIFIER, + ty: #ty, + default: #frame_support::metadata::DecodeDifferent::Encode( + <#full_ident as #metadata_trait>::DEFAULT + ), + documentation: #frame_support::metadata::DecodeDifferent::Encode(&[ + #( #docs, )* + ]), + } + ) + }); + + let getters = def.storages.iter() + .map(|storage| if let Some(getter) = &storage.getter { + let completed_where_clause = super::merge_where_clauses(&[ + &storage.where_clause, + &def.config.where_clause, + ]); + let docs = storage.docs.iter().map(|d| quote::quote!(#[doc = #d])); + + let ident = &storage.ident; + let gen = &def.type_use_generics(); + let full_ident = quote::quote!( #ident<#gen> ); + + match &storage.metadata { + Metadata::Value { value } => { + let query = match storage.query_kind.as_ref().expect("Checked by def") { + QueryKind::OptionQuery => quote::quote!(Option<#value>), + QueryKind::ValueQuery => quote::quote!(#value), + }; + quote::quote_spanned!(getter.span() => + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause { + #( #docs )* + pub fn #getter() -> #query { + < + #full_ident as #frame_support::storage::StorageValue<#value> + >::get() + } + } + ) + }, + Metadata::Map { key, value } => { + let query = match storage.query_kind.as_ref().expect("Checked by def") { + QueryKind::OptionQuery => quote::quote!(Option<#value>), + QueryKind::ValueQuery => quote::quote!(#value), + }; + quote::quote_spanned!(getter.span() => + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause { + #( #docs )* + pub fn #getter(k: KArg) -> #query where + KArg: #frame_support::codec::EncodeLike<#key>, + { + < + #full_ident as #frame_support::storage::StorageMap<#key, #value> + >::get(k) + } + } + ) + }, + Metadata::DoubleMap { key1, key2, value } => { + let query = match storage.query_kind.as_ref().expect("Checked by def") { + QueryKind::OptionQuery => quote::quote!(Option<#value>), + QueryKind::ValueQuery => quote::quote!(#value), + }; + quote::quote_spanned!(getter.span() => + impl<#type_impl_gen> #pallet_ident<#type_use_gen> #completed_where_clause { + #( #docs )* + pub fn #getter(k1: KArg1, k2: KArg2) -> #query where + KArg1: #frame_support::codec::EncodeLike<#key1>, + KArg2: #frame_support::codec::EncodeLike<#key2>, + { + < + #full_ident as + #frame_support::storage::StorageDoubleMap<#key1, #key2, #value> + >::get(k1, k2) + } + } + ) + }, + } + } else { + Default::default() + }); + + let prefix_structs = def.storages.iter().map(|storage_def| { + let prefix_struct_ident = prefix_ident(&storage_def.ident); + let prefix_struct_vis = &storage_def.vis; + let prefix_struct_const = storage_def.ident.to_string(); + let config_where_clause = &def.config.where_clause; + + quote::quote_spanned!(storage_def.ident.span() => + #prefix_struct_vis struct #prefix_struct_ident<#type_use_gen>( + core::marker::PhantomData<(#type_use_gen,)> + ); + impl<#type_impl_gen> #frame_support::traits::StorageInstance + for #prefix_struct_ident<#type_use_gen> + #config_where_clause + { + type PalletInfo = ::PalletInfo; + type Pallet = Pallet<#type_use_gen>; + const STORAGE_PREFIX: &'static str = #prefix_struct_const; + } + ) + }); + + let mut where_clauses = vec![&def.config.where_clause]; + where_clauses.extend(def.storages.iter().map(|storage| &storage.where_clause)); + let completed_where_clause = super::merge_where_clauses(&where_clauses); + + quote::quote!( + impl<#type_impl_gen> #pallet_ident<#type_use_gen> + #completed_where_clause + { + #[doc(hidden)] + pub fn storage_metadata() -> #frame_support::metadata::StorageMetadata { + #frame_support::metadata::StorageMetadata { + prefix: #frame_support::metadata::DecodeDifferent::Encode( + < + ::PalletInfo as + #frame_support::traits::PalletInfo + >::name::<#pallet_ident<#type_use_gen>>() + .expect("Every active pallet has a name in the runtime; qed") + ), + entries: #frame_support::metadata::DecodeDifferent::Encode( + &[ #( #entries, )* ] + ), + } + } + } + + #( #getters )* + #( #prefix_structs )* + ) +} diff --git a/frame/support/procedural/src/pallet/expand/store_trait.rs b/frame/support/procedural/src/pallet/expand/store_trait.rs new file mode 100644 index 0000000000000..ceea270bb9f39 --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/store_trait.rs @@ -0,0 +1,55 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use syn::spanned::Spanned; + +/// If attribute `#[pallet::generate_store(..)]` is defined then: +/// * generate Store trait with all storages, +/// * implement Store trait for Pallet. +pub fn expand_store_trait(def: &mut Def) -> proc_macro2::TokenStream { + let (trait_vis, trait_store) = if let Some(store) = &def.pallet_struct.store { + store + } else { + return Default::default() + }; + + let type_impl_gen = &def.type_impl_generics(); + let type_use_gen = &def.type_use_generics(); + let pallet_ident = &def.pallet_struct.pallet; + + let mut where_clauses = vec![&def.config.where_clause]; + where_clauses.extend(def.storages.iter().map(|storage| &storage.where_clause)); + let completed_where_clause = super::merge_where_clauses(&where_clauses); + + let storage_names = &def.storages.iter().map(|storage| &storage.ident).collect::>(); + + quote::quote_spanned!(trait_store.span() => + #trait_vis trait #trait_store { + #( + type #storage_names; + )* + } + impl<#type_impl_gen> #trait_store for #pallet_ident<#type_use_gen> + #completed_where_clause + { + #( + type #storage_names = #storage_names<#type_use_gen>; + )* + } + ) +} diff --git a/frame/support/procedural/src/pallet/expand/type_value.rs b/frame/support/procedural/src/pallet/expand/type_value.rs new file mode 100644 index 0000000000000..9b3e9e351c4bf --- /dev/null +++ b/frame/support/procedural/src/pallet/expand/type_value.rs @@ -0,0 +1,55 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use crate::pallet::Def; +use syn::spanned::Spanned; + +/// * Generate the struct +/// * implement the `Get<..>` on it +pub fn expand_type_values(def: &mut Def) -> proc_macro2::TokenStream { + let mut expand = quote::quote!(); + let frame_support = &def.frame_support; + + for type_value in &def.type_values { + // Remove item from module content + let item = &mut def.item.content.as_mut().expect("Checked by def").1[type_value.index]; + let span = item.span(); + *item = syn::Item::Verbatim(Default::default()); + + let vis = &type_value.vis; + let ident = &type_value.ident; + let block = &type_value.block; + let type_ = &type_value.type_; + let where_clause = &type_value.where_clause; + + let (struct_impl_gen, struct_use_gen) = if type_value.is_generic { + (def.type_impl_generics(), def.type_use_generics()) + } else { + (Default::default(), Default::default()) + }; + + expand.extend(quote::quote_spanned!(span => + #vis struct #ident<#struct_use_gen>(core::marker::PhantomData<((), #struct_use_gen)>); + impl<#struct_impl_gen> #frame_support::traits::Get<#type_> for #ident<#struct_use_gen> + #where_clause + { + fn get() -> #type_ #block + } + )); + } + expand +} diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs new file mode 100644 index 0000000000000..8b9a814b33909 --- /dev/null +++ b/frame/support/procedural/src/pallet/mod.rs @@ -0,0 +1,49 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Implementation for pallet attribute macro. +//! +//! General workflow: +//! 1 - parse all pallet attributes: +//! This step remove all attributes `#[pallet::*]` from the ItemMod and build the `Def` struct +//! which holds the ItemMod without `#[pallet::*]` and information given by those attributes +//! 2 - expand from the parsed information +//! This step will modify the ItemMod by adding some derive attributes or phantom data variants +//! to user defined types. And also crate new types and implement block. + +mod parse; +mod expand; + +pub use parse::Def; +use syn::spanned::Spanned; + +pub fn pallet( + attr: proc_macro::TokenStream, + item: proc_macro::TokenStream +) -> proc_macro::TokenStream { + if !attr.is_empty() { + let msg = "Invalid pallet macro call: expect `#[frame_support::pallet]`"; + let span = proc_macro2::TokenStream::from(attr).span(); + return syn::Error::new(span, msg).to_compile_error().into(); + } + + let item = syn::parse_macro_input!(item as syn::ItemMod); + match parse::Def::try_from(item) { + Ok(def) => expand::expand(def).into(), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs new file mode 100644 index 0000000000000..c77667913e3db --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -0,0 +1,237 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use quote::ToTokens; +use syn::spanned::Spanned; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(DispatchResultWithPostInfo); + syn::custom_keyword!(Call); + syn::custom_keyword!(OriginFor); + syn::custom_keyword!(weight); + syn::custom_keyword!(compact); + syn::custom_keyword!(T); + syn::custom_keyword!(pallet); +} + +/// Definition of dispatchables typically `impl Pallet { ... }` +pub struct CallDef { + /// The where_clause used. + pub where_clause: Option, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The index of call item in pallet module. + pub index: usize, + /// Information on methods (used for expansion). + pub methods: Vec, + /// The span of the attribute. + pub attr_span: proc_macro2::Span, +} + +/// Definition of dispatchable typically: `#[weight...] fn foo(origin .., param1: ...) -> ..` +pub struct CallVariantDef { + /// Function name. + pub fn_: syn::Ident, + /// Information on args: `(is_compact, name, type)` + pub args: Vec<(bool, syn::Ident, Box)>, + /// Weight formula. + pub weight: syn::Expr, + /// Docs, used for metadata. + pub docs: Vec, +} + +/// Attributes for functions in call impl block. +/// Parse for `#[pallet::weight = expr]` +pub struct FunctionAttr { + weight: syn::Expr, +} + +impl syn::parse::Parse for FunctionAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + content.parse::()?; + + let weight_content; + syn::parenthesized!(weight_content in content); + Ok(FunctionAttr { + weight: weight_content.parse::()?, + }) + } +} + +/// Attribute for arguments in function in call impl block. +/// Parse for `#[pallet::compact]| +pub struct ArgAttrIsCompact; + +impl syn::parse::Parse for ArgAttrIsCompact { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + content.parse::()?; + Ok(ArgAttrIsCompact) + } +} + +/// Check the syntax is `OriginFor` +pub fn check_dispatchable_first_arg_type(ty: &syn::Type) -> syn::Result<()> { + let expected = "expect `OriginFor`"; + + pub struct CheckDispatchableFirstArg; + impl syn::parse::Parse for CheckDispatchableFirstArg { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + + Ok(Self) + } + } + + syn::parse2::(ty.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid ty: {}", expected); + let mut err = syn::Error::new(ty.span(), msg); + err.combine(e); + err + })?; + + Ok(()) +} + +impl CallDef { + pub fn try_from( + // Span needed for expansion + attr_span: proc_macro2::Span, + index: usize, + item: &mut syn::Item + ) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::call, expect item impl")); + }; + + let mut instances = vec![]; + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + + if let Some((_, _, for_)) = item.trait_ { + let msg = "Invalid pallet::call, expect no trait ident as in \ + `impl<..> Pallet<..> { .. }`"; + return Err(syn::Error::new(for_.span(), msg)) + } + + let mut methods = vec![]; + for impl_item in &mut item.items { + if let syn::ImplItem::Method(method) = impl_item { + match method.sig.inputs.first() { + None => { + let msg = "Invalid pallet::call, must have at least origin arg"; + return Err(syn::Error::new(method.sig.span(), msg)); + }, + Some(syn::FnArg::Receiver(_)) => { + let msg = "Invalid pallet::call, first argument must be a typed argument, \ + e.g. `origin: OriginFor`"; + return Err(syn::Error::new(method.sig.span(), msg)); + }, + Some(syn::FnArg::Typed(arg)) => { + check_dispatchable_first_arg_type(&*arg.ty)?; + }, + } + + if let syn::ReturnType::Type(_, type_) = &method.sig.output { + syn::parse2::(type_.to_token_stream())?; + } else { + let msg = "Invalid pallet::call, require return type \ + DispatchResultWithPostInfo"; + return Err(syn::Error::new(method.sig.span(), msg)); + } + + let mut call_var_attrs: Vec = + helper::take_item_attrs(&mut method.attrs)?; + + if call_var_attrs.len() != 1 { + let msg = if call_var_attrs.len() == 0 { + "Invalid pallet::call, require weight attribute i.e. `#[pallet::weight = $expr]`" + } else { + "Invalid pallet::call, to many weight attribute given" + }; + return Err(syn::Error::new(method.sig.span(), msg)); + } + let weight = call_var_attrs.pop().unwrap().weight; + + let mut args = vec![]; + for arg in method.sig.inputs.iter_mut().skip(1) { + let arg = if let syn::FnArg::Typed(arg) = arg { + arg + } else { + unreachable!("Only first argument can be receiver"); + }; + + let arg_attrs: Vec = + helper::take_item_attrs(&mut arg.attrs)?; + + if arg_attrs.len() > 1 { + let msg = "Invalid pallet::call, argument has too many attributes"; + return Err(syn::Error::new(arg.span(), msg)); + } + + let arg_ident = if let syn::Pat::Ident(pat) = &*arg.pat { + pat.ident.clone() + } else { + let msg = "Invalid pallet::call, argument must be ident"; + return Err(syn::Error::new(arg.pat.span(), msg)); + }; + + args.push((!arg_attrs.is_empty(), arg_ident, arg.ty.clone())); + } + + let docs = helper::get_doc_literals(&method.attrs); + + methods.push(CallVariantDef { + fn_: method.sig.ident.clone(), + weight, + args, + docs, + }); + } else { + let msg = "Invalid pallet::call, only method accepted"; + return Err(syn::Error::new(impl_item.span(), msg)); + } + } + + Ok(Self { + index, + attr_span, + instances, + methods, + where_clause: item.generics.where_clause.clone(), + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs new file mode 100644 index 0000000000000..a243920ee0b24 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -0,0 +1,385 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(Config); + syn::custom_keyword!(From); + syn::custom_keyword!(T); + syn::custom_keyword!(I); + syn::custom_keyword!(Get); + syn::custom_keyword!(config); + syn::custom_keyword!(IsType); + syn::custom_keyword!(Event); + syn::custom_keyword!(constant); + syn::custom_keyword!(frame_system); + syn::custom_keyword!(disable_frame_system_supertrait_check); +} + +/// Input definition for the pallet config. +pub struct ConfigDef { + /// The index of item in pallet module. + pub index: usize, + /// Wheither the trait has instance (i.e. define with `Config`) + pub has_instance: bool, + /// Const associated type. + pub consts_metadata: Vec, + /// Wether the trait has the associated type `Event`, note that those bounds are checked: + /// * `IsType::Event` + /// * `From` or `From>` or `From>` + pub has_event_type: bool, + /// The where clause on trait definition but modified so `Self` is `T`. + pub where_clause: Option, + +} + +/// Input definition for a constant in pallet config. +pub struct ConstMetadataDef { + /// Name of the associated type. + pub ident: syn::Ident, + /// The type in Get, e.g. `u32` in `type Foo: Get;`, but `Self` is replaced by `T` + pub type_: syn::Type, + /// The doc associated + pub doc: Vec, +} + +impl syn::parse::Parse for ConstMetadataDef { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let doc = helper::get_doc_literals(&syn::Attribute::parse_outer(input)?); + input.parse::()?; + let ident = input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + let mut type_ = input.parse::()?; + type_ = syn::parse2::(replace_self_by_t(type_.to_token_stream())) + .expect("Internal error: replacing `Self` by `T` should result in valid type"); + input.parse::]>()?; + input.parse::()?; + + Ok(Self { ident, type_, doc }) + } +} + +/// Parse for `#[pallet::disable_frame_system_supertrait_check]` +pub struct DisableFrameSystemSupertraitCheck; + +impl syn::parse::Parse for DisableFrameSystemSupertraitCheck { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + content.parse::()?; + Ok(Self) + } +} + +/// Parse for `#[pallet::constant]` +pub struct TypeAttrConst(proc_macro2::Span); + +impl Spanned for TypeAttrConst { + fn span(&self) -> proc_macro2::Span { + self.0 + } +} + +impl syn::parse::Parse for TypeAttrConst { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + Ok(TypeAttrConst(content.parse::()?.span())) + } +} + +/// Parse for `$ident::Config` +pub struct ConfigBoundParse(syn::Ident); + +impl syn::parse::Parse for ConfigBoundParse { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let ident = input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(ident)) + } +} + +/// Parse for `IsType<::Event>` and retrieve `$ident` +pub struct IsTypeBoundEventParse(syn::Ident); + +impl syn::parse::Parse for IsTypeBoundEventParse { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + let ident = input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + + Ok(Self(ident)) + } +} + +/// Parse for `From` or `From>` or `From>` +pub struct FromEventParse { + is_generic: bool, + has_instance: bool, +} + +impl syn::parse::Parse for FromEventParse { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut is_generic = false; + let mut has_instance = false; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![<]) { + is_generic = true; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![,]) { + input.parse::()?; + input.parse::()?; + has_instance = true; + } + input.parse::]>()?; + } + input.parse::]>()?; + + Ok(Self { is_generic, has_instance }) + } +} + +/// Check if trait_item is `type Event`, if so checks its bounds are those expected. +/// (Event type is reserved type) +fn check_event_type( + frame_system: &syn::Ident, + trait_item: &syn::TraitItem, + trait_has_instance: bool +) -> syn::Result { + if let syn::TraitItem::Type(type_) = trait_item { + if type_.ident == "Event" { + // Check event has no generics + if !type_.generics.params.is_empty() || type_.generics.where_clause.is_some() { + let msg = "Invalid `type Event`, associated type `Event` is reserved and must have\ + no generics nor where_clause"; + return Err(syn::Error::new(trait_item.span(), msg)); + } + // Check bound contains IsType and From + + let has_is_type_bound = type_.bounds.iter().any(|s| { + syn::parse2::(s.to_token_stream()) + .map_or(false, |b| b.0 == *frame_system) + }); + + if !has_is_type_bound { + let msg = format!( + "Invalid `type Event`, associated type `Event` is reserved and must \ + bound: `IsType<::Event>`", + frame_system, + ); + return Err(syn::Error::new(type_.span(), msg)); + } + + let from_event_bound = type_.bounds.iter().find_map(|s| { + syn::parse2::(s.to_token_stream()).ok() + }); + + let from_event_bound = if let Some(b) = from_event_bound { + b + } else { + let msg = "Invalid `type Event`, associated type `Event` is reserved and must \ + bound: `From` or `From>` or `From>`"; + return Err(syn::Error::new(type_.span(), msg)); + }; + + if from_event_bound.is_generic + && (from_event_bound.has_instance != trait_has_instance) + { + let msg = "Invalid `type Event`, associated type `Event` bounds inconsistent \ + `From`. Config and generic Event must be both with instance or \ + without instance"; + return Err(syn::Error::new(type_.span(), msg)); + } + + Ok(true) + } else { + Ok(false) + } + } else { + Ok(false) + } +} + +/// Replace ident `Self` by `T` +pub fn replace_self_by_t(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream { + input.into_iter() + .map(|token_tree| match token_tree { + proc_macro2::TokenTree::Group(group) => + proc_macro2::Group::new( + group.delimiter(), + replace_self_by_t(group.stream()) + ).into(), + proc_macro2::TokenTree::Ident(ident) if ident == "Self" => + proc_macro2::Ident::new("T", ident.span()).into(), + other @ _ => other + }) + .collect() +} + +impl ConfigDef { + pub fn try_from( + frame_system: &syn::Ident, + index: usize, + item: &mut syn::Item + ) -> syn::Result { + let item = if let syn::Item::Trait(item) = item { + item + } else { + let msg = "Invalid pallet::config, expect trait definition"; + return Err(syn::Error::new(item.span(), msg)); + }; + + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::config, trait must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + syn::parse2::(item.ident.to_token_stream())?; + + + let where_clause = { + let stream = replace_self_by_t(item.generics.where_clause.to_token_stream()); + syn::parse2::>(stream) + .expect("Internal error: replacing `Self` by `T` should result in valid where + clause") + }; + + if item.generics.params.len() > 1 { + let msg = "Invalid pallet::config, expect no more than one generics"; + return Err(syn::Error::new(item.generics.params[2].span(), msg)); + } + + let has_instance; + if let Some(_) = item.generics.params.first() { + helper::check_config_def_gen(&item.generics, item.ident.span())?; + has_instance = true; + } else { + has_instance = false; + } + + let mut has_event_type = false; + let mut consts_metadata = vec![]; + for trait_item in &mut item.items { + // Parse for event + has_event_type = has_event_type + || check_event_type(frame_system, trait_item, has_instance)?; + + // Parse for constant + let type_attrs_const: Vec = helper::take_item_attrs(trait_item)?; + + if type_attrs_const.len() > 1 { + let msg = "Invalid attribute in pallet::config, only one attribute is expected"; + return Err(syn::Error::new(type_attrs_const[1].span(), msg)); + } + + if type_attrs_const.len() == 1 { + match trait_item { + syn::TraitItem::Type(type_) => { + let constant = syn::parse2::(type_.to_token_stream()) + .map_err(|e| { + let error_msg = "Invalid usage of `#[pallet::constant]`, syntax \ + must be `type $SomeIdent: Get<$SomeType>;`"; + let mut err = syn::Error::new(type_.span(), error_msg); + err.combine(e); + err + })?; + + consts_metadata.push(constant); + }, + _ => { + let msg = "Invalid pallet::constant in pallet::config, expect type trait \ + item"; + return Err(syn::Error::new(trait_item.span(), msg)); + }, + } + } + } + + let attr: Option = helper::take_first_item_attr( + &mut item.attrs + )?; + + let disable_system_supertrait_check = attr.is_some(); + + let has_frame_system_supertrait = item.supertraits.iter().any(|s| { + syn::parse2::(s.to_token_stream()) + .map_or(false, |b| b.0 == *frame_system) + }); + + if !has_frame_system_supertrait && !disable_system_supertrait_check { + let found = if item.supertraits.is_empty() { + "none".to_string() + } else { + let mut found = item.supertraits.iter() + .fold(String::new(), |acc, s| { + format!("{}`{}`, ", acc, quote::quote!(#s).to_string()) + }); + found.pop(); + found.pop(); + found + }; + + let msg = format!( + "Invalid pallet::trait, expect explicit `{}::Config` as supertrait, \ + found {}. \ + (try `pub trait Config: frame_system::Config {{ ...` or \ + `pub trait Config: frame_system::Config {{ ...`). \ + To disable this check, use `#[pallet::disable_frame_system_supertrait_check]`", + frame_system, + found, + ); + return Err(syn::Error::new(item.span(), msg)); + } + + Ok(Self { + index, + has_instance, + consts_metadata, + has_event_type, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/error.rs b/frame/support/procedural/src/pallet/parse/error.rs new file mode 100644 index 0000000000000..4fcde327cc0d1 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/error.rs @@ -0,0 +1,86 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(Error); +} + +/// This checks error declaration as a enum declaration with only variants without fields nor +/// discriminant. +pub struct ErrorDef { + /// The index of error item in pallet module. + pub index: usize, + /// Variants ident and doc literals (ordered as declaration order) + pub variants: Vec<(syn::Ident, Vec)>, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The keyword error used (contains span). + pub error: keyword::Error +} + +impl ErrorDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Enum(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::error, expect item enum")); + }; + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::error, `Error` must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_type_def_gen_no_bounds(&item.generics, item.ident.span())?); + + if item.generics.where_clause.is_some() { + let msg = "Invalid pallet::error, unexpected where clause"; + return Err(syn::Error::new(item.generics.where_clause.as_ref().unwrap().span(), msg)); + } + + let error = syn::parse2::(item.ident.to_token_stream())?; + + let variants = item.variants.iter() + .map(|variant| { + if !matches!(variant.fields, syn::Fields::Unit) { + let msg = "Invalid pallet::error, unexpected fields, must be `Unit`"; + return Err(syn::Error::new(variant.fields.span(), msg)); + } + if variant.discriminant.is_some() { + let msg = "Invalid pallet::error, unexpected discriminant, discriminant \ + are not supported"; + let span = variant.discriminant.as_ref().unwrap().0.span(); + return Err(syn::Error::new(span, msg)); + } + + Ok((variant.ident.clone(), helper::get_doc_literals(&variant.attrs))) + }) + .collect::>()?; + + Ok(ErrorDef { + index, + variants, + instances, + error, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs new file mode 100644 index 0000000000000..49911832e20d2 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -0,0 +1,256 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(metadata); + syn::custom_keyword!(Event); + syn::custom_keyword!(pallet); + syn::custom_keyword!(generate_deposit); + syn::custom_keyword!(deposit_event); +} + +/// Definition for pallet event enum. +pub struct EventDef { + /// The index of event item in pallet module. + pub index: usize, + /// The keyword Event used (contains span). + pub event: keyword::Event, + /// Event metadatas: `(name, args, docs)`. + pub metadata: Vec<(syn::Ident, Vec, Vec)>, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// If event is declared with instance. + pub has_instance: bool, + /// If event is declared with genericity. + pub is_generic: bool, + /// Weither the function `deposit_event` must be generated. + pub deposit_event: Option<(syn::Visibility, proc_macro2::Span)>, + /// Where clause used in event definition. + pub where_clause: Option, +} + +impl EventDef { + /// Return the generic to be used when using Event type + /// + /// Depending on its definition it can be: ``, `T` or `T, I` + pub fn event_use_gen(&self) -> proc_macro2::TokenStream { + if self.is_generic { + if self.has_instance { + quote::quote!(T, I) + } else { + quote::quote!(T) + } + } else { + quote::quote!() + } + } + + /// Return the generic to be used in `impl<..>` when implementing on Event type. + pub fn event_impl_gen(&self) -> proc_macro2::TokenStream { + if self.is_generic { + if self.has_instance { + quote::quote!(T: Config, I) + } else { + quote::quote!(T: Config) + } + } else { + quote::quote!() + } + } +} + +/// Attribute for Event: defines metadata name to use. +/// +/// Syntax is: +/// * `#[pallet::metadata(SomeType = MetadataName, ...)]` +/// * `#[pallet::generate_deposit($vis fn deposit_event)]` +enum PalletEventAttr { + Metadata { + metadata: Vec<(syn::Type, String)>, + // Span of the attribute + span: proc_macro2::Span, + }, + DepositEvent { + fn_vis: syn::Visibility, + // Span for the keyword deposit_event + fn_span: proc_macro2::Span, + // Span of the attribute + span: proc_macro2::Span, + }, +} + +impl PalletEventAttr { + fn span(&self) -> proc_macro2::Span { + match self { + Self::Metadata { span, .. } => span.clone(), + Self::DepositEvent { span, .. } => span.clone(), + } + } +} + +/// Parse for syntax `$Type = "$SomeString"`. +fn parse_event_metadata_element(input: syn::parse::ParseStream) -> syn::Result<(syn::Type, String)> { + let typ = input.parse::()?; + input.parse::()?; + let ident = input.parse::()?; + Ok((typ, ident.value())) +} + +impl syn::parse::Parse for PalletEventAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + let lookahead = content.lookahead1(); + if lookahead.peek(keyword::metadata) { + let span = content.parse::()?.span(); + let metadata_content; + syn::parenthesized!(metadata_content in content); + + let metadata = metadata_content + .parse_terminated::<_, syn::Token![,]>(parse_event_metadata_element)? + .into_pairs() + .map(syn::punctuated::Pair::into_value) + .collect(); + + Ok(PalletEventAttr::Metadata { metadata, span }) + } else if lookahead.peek(keyword::generate_deposit) { + let span = content.parse::()?.span(); + + let generate_content; + syn::parenthesized!(generate_content in content); + let fn_vis = generate_content.parse::()?; + generate_content.parse::()?; + let fn_span = generate_content.parse::()?.span(); + + + Ok(PalletEventAttr::DepositEvent { fn_vis, span, fn_span }) + } else { + Err(lookahead.error()) + } + } +} + +struct PalletEventAttrInfo { + metadata: Option>, + deposit_event: Option<(syn::Visibility, proc_macro2::Span)>, +} + +impl PalletEventAttrInfo { + fn from_attrs(attrs: Vec) -> syn::Result { + let mut metadata = None; + let mut deposit_event = None; + for attr in attrs { + match attr { + PalletEventAttr::Metadata { metadata: m, .. } if metadata.is_none() => + metadata = Some(m), + PalletEventAttr::DepositEvent { fn_vis, fn_span, .. } if deposit_event.is_none() => + deposit_event = Some((fn_vis, fn_span)), + attr => { + return Err(syn::Error::new(attr.span(), "Duplicate attribute")); + } + } + } + + Ok(PalletEventAttrInfo { metadata, deposit_event }) + } +} + +impl EventDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Enum(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::event, expect item enum")) + }; + + let event_attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; + let attr_info = PalletEventAttrInfo::from_attrs(event_attrs)?; + let metadata = attr_info.metadata.unwrap_or_else(|| vec![]); + let deposit_event = attr_info.deposit_event; + + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::event, `Error` must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + let where_clause = item.generics.where_clause.clone(); + let has_instance = item.generics.params.len() == 2; + let is_generic = item.generics.params.len() > 0; + + let mut instances = vec![]; + if let Some(u) = helper::check_type_def_optional_gen(&item.generics, item.ident.span())? { + instances.push(u); + } else { + // construct_runtime only allow generic event for instantiable pallet. + instances.push(helper::InstanceUsage { + has_instance: false, + span: item.ident.span(), + }) + } + + let event = syn::parse2::(item.ident.to_token_stream())?; + + let metadata = item.variants.iter() + .map(|variant| { + let name = variant.ident.clone(); + let docs = helper::get_doc_literals(&variant.attrs); + let args = variant.fields.iter() + .map(|field| { + metadata.iter().find(|m| m.0 == field.ty) + .map(|m| m.1.clone()) + .or_else(|| { + if let syn::Type::Path(p) = &field.ty { + p.path.segments.last().map(|s| format!("{}", s.ident)) + } else { + None + } + }) + .ok_or_else(|| { + let msg = "Invalid pallet::event, type can't be parsed for \ + metadata, must be either a path type (and thus last \ + segments ident is metadata) or match a type in the \ + metadata attributes"; + syn::Error::new(field.span(), msg) + }) + }) + .collect::>()?; + + Ok((name, args, docs)) + }) + .collect::>()?; + + Ok(EventDef { + index, + metadata, + instances, + has_instance, + deposit_event, + event, + is_generic, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/extra_constants.rs b/frame/support/procedural/src/pallet/parse/extra_constants.rs new file mode 100644 index 0000000000000..fd44dacbcc1d0 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/extra_constants.rs @@ -0,0 +1,121 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use syn::spanned::Spanned; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(DispatchResultWithPostInfo); + syn::custom_keyword!(Call); + syn::custom_keyword!(OriginFor); + syn::custom_keyword!(weight); + syn::custom_keyword!(compact); + syn::custom_keyword!(T); + syn::custom_keyword!(pallet); +} + +/// Definition of extra constants typically `impl Pallet { ... }` +pub struct ExtraConstantsDef { + /// The where_clause used. + pub where_clause: Option, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The index of call item in pallet module. + pub index: usize, + /// The extra constant defined. + pub extra_constants: Vec, +} + +/// Input definition for an constant in pallet. +pub struct ExtraConstantDef { + /// Name of the function + pub ident: syn::Ident, + /// The type returned by the function + pub type_: syn::Type, + /// The doc associated + pub doc: Vec, +} + +impl ExtraConstantsDef { + pub fn try_from( + index: usize, + item: &mut syn::Item + ) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::call, expect item impl")); + }; + + let mut instances = vec![]; + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + + if let Some((_, _, for_)) = item.trait_ { + let msg = "Invalid pallet::call, expect no trait ident as in \ + `impl<..> Pallet<..> { .. }`"; + return Err(syn::Error::new(for_.span(), msg)) + } + + let mut extra_constants = vec![]; + for impl_item in &mut item.items { + let method = if let syn::ImplItem::Method(method) = impl_item { + method + } else { + let msg = "Invalid pallet::call, only method accepted"; + return Err(syn::Error::new(impl_item.span(), msg)); + }; + + if method.sig.inputs.len() != 0 { + let msg = "Invalid pallet::extra_constants, method must have 0 args"; + return Err(syn::Error::new(method.sig.span(), msg)); + } + + if method.sig.generics.params.len() != 0 { + let msg = "Invalid pallet::extra_constants, method must have 0 generics"; + return Err(syn::Error::new(method.sig.generics.params[0].span(), msg)); + } + + if method.sig.generics.where_clause.is_some() { + let msg = "Invalid pallet::extra_constants, method must have no where clause"; + return Err(syn::Error::new(method.sig.generics.where_clause.span(), msg)); + } + + let type_ = match &method.sig.output { + syn::ReturnType::Default => { + let msg = "Invalid pallet::extra_constants, method must have a return type"; + return Err(syn::Error::new(method.span(), msg)); + }, + syn::ReturnType::Type(_, type_) => *type_.clone(), + }; + + extra_constants.push(ExtraConstantDef { + ident: method.sig.ident.clone(), + type_, + doc: helper::get_doc_literals(&method.attrs), + }); + } + + Ok(Self { + index, + instances, + where_clause: item.generics.where_clause.clone(), + extra_constants, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/genesis_build.rs b/frame/support/procedural/src/pallet/parse/genesis_build.rs new file mode 100644 index 0000000000000..c3f3c59bcabea --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/genesis_build.rs @@ -0,0 +1,56 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use syn::spanned::Spanned; +use super::helper; + +/// Definition for pallet genesis build implementation. +pub struct GenesisBuildDef { + /// The index of item in pallet module. + pub index: usize, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The where_clause used. + pub where_clause: Option, +} + +impl GenesisBuildDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + let msg = "Invalid pallet::genesis_build, expect item impl"; + return Err(syn::Error::new(item.span(), msg)); + }; + + let item_trait = &item.trait_.as_ref() + .ok_or_else(|| { + let msg = "Invalid pallet::genesis_build, expect impl<..> GenesisBuild<..> \ + for GenesisConfig<..>"; + syn::Error::new(item.span(), msg) + })?.1; + + let mut instances = vec![]; + instances.push(helper::check_genesis_builder_usage(&item_trait)?); + + Ok(Self { + index, + instances, + where_clause: item.generics.where_clause.clone(), + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/genesis_config.rs b/frame/support/procedural/src/pallet/parse/genesis_config.rs new file mode 100644 index 0000000000000..beecd3ef39243 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/genesis_config.rs @@ -0,0 +1,81 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use syn::spanned::Spanned; +use super::helper; + +/// Definition for pallet genesis config type. +/// +/// Either: +/// * `type GenesisConfig` +/// * `struct GenesisConfig` +/// * `enum GenesisConfig` +pub struct GenesisConfigDef { + /// The index of item in pallet module. + pub index: usize, + /// Weither type has instance generic. + pub has_instance: bool, + /// Weither type has trait generic. + pub has_trait: bool, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The ident of genesis_config, can be used for span. + pub genesis_config: syn::Ident, +} + +impl GenesisConfigDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item_span = item.span(); + let (vis, ident, generics) = match &item { + syn::Item::Enum(item) => (&item.vis, &item.ident, &item.generics), + syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics), + syn::Item::Type(item) => (&item.vis, &item.ident, &item.generics), + _ => { + let msg = "Invalid pallet::genesis_config, expect enum or struct or type"; + return Err(syn::Error::new(item.span(), msg)); + }, + }; + + let has_instance = generics.type_params().any(|t| t.ident == "I"); + let has_trait = generics.type_params().any(|t| t.ident == "T"); + + let mut instances = vec![]; + // NOTE: GenesisConfig is not allowed to be only generic on I because it is not supported + // by construct_runtime. + if let Some(u) = helper::check_type_def_optional_gen(&generics, ident.span())? { + instances.push(u); + } + + if !matches!(vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::genesis_config, GenesisConfig must be public"; + return Err(syn::Error::new(item_span, msg)); + } + + if ident != "GenesisConfig" { + let msg = "Invalid pallet::genesis_config, ident must `GenesisConfig`"; + return Err(syn::Error::new(ident.span(), msg)); + } + + Ok(GenesisConfigDef { + index, + genesis_config: ident.clone(), + has_instance, + has_trait, + instances, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/helper.rs b/frame/support/procedural/src/pallet/parse/helper.rs new file mode 100644 index 0000000000000..1d797a0cc72ca --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/helper.rs @@ -0,0 +1,600 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(I); + syn::custom_keyword!(compact); + syn::custom_keyword!(GenesisBuild); + syn::custom_keyword!(Config); + syn::custom_keyword!(T); + syn::custom_keyword!(Pallet); + syn::custom_keyword!(origin); +} + +/// A usage of instance, either the trait `Config` has been used with instance or without instance. +/// Used to check for consistency. +#[derive(Clone)] +pub struct InstanceUsage { + pub has_instance: bool, + pub span: proc_macro2::Span, +} + +/// Trait implemented for syn items to get mutable references on their attributes. +/// +/// NOTE: verbatim variants are not supported. +pub trait MutItemAttrs { + fn mut_item_attrs(&mut self) -> Option<&mut Vec>; +} + +/// Take the first pallet attribute (e.g. attribute like `#[pallet..]`) and decode it to `Attr` +pub fn take_first_item_attr(item: &mut impl MutItemAttrs) -> syn::Result> where + Attr: syn::parse::Parse, +{ + let attrs = if let Some(attrs) = item.mut_item_attrs() { + attrs + } else { + return Ok(None) + }; + + if let Some(index) = attrs.iter() + .position(|attr| + attr.path.segments.first().map_or(false, |segment| segment.ident == "pallet") + ) + { + let pallet_attr = attrs.remove(index); + Ok(Some(syn::parse2(pallet_attr.into_token_stream())?)) + } else { + Ok(None) + } +} + +/// Take all the pallet attributes (e.g. attribute like `#[pallet..]`) and decode them to `Attr` +pub fn take_item_attrs(item: &mut impl MutItemAttrs) -> syn::Result> where + Attr: syn::parse::Parse, +{ + let mut pallet_attrs = Vec::new(); + + while let Some(attr) = take_first_item_attr(item)? { + pallet_attrs.push(attr) + } + + Ok(pallet_attrs) +} + +impl MutItemAttrs for syn::Item { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + match self { + Self::Const(item) => Some(item.attrs.as_mut()), + Self::Enum(item) => Some(item.attrs.as_mut()), + Self::ExternCrate(item) => Some(item.attrs.as_mut()), + Self::Fn(item) => Some(item.attrs.as_mut()), + Self::ForeignMod(item) => Some(item.attrs.as_mut()), + Self::Impl(item) => Some(item.attrs.as_mut()), + Self::Macro(item) => Some(item.attrs.as_mut()), + Self::Macro2(item) => Some(item.attrs.as_mut()), + Self::Mod(item) => Some(item.attrs.as_mut()), + Self::Static(item) => Some(item.attrs.as_mut()), + Self::Struct(item) => Some(item.attrs.as_mut()), + Self::Trait(item) => Some(item.attrs.as_mut()), + Self::TraitAlias(item) => Some(item.attrs.as_mut()), + Self::Type(item) => Some(item.attrs.as_mut()), + Self::Union(item) => Some(item.attrs.as_mut()), + Self::Use(item) => Some(item.attrs.as_mut()), + Self::Verbatim(_) => None, + Self::__Nonexhaustive => None, + } + } +} + + +impl MutItemAttrs for syn::TraitItem { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + match self { + Self::Const(item) => Some(item.attrs.as_mut()), + Self::Method(item) => Some(item.attrs.as_mut()), + Self::Type(item) => Some(item.attrs.as_mut()), + Self::Macro(item) => Some(item.attrs.as_mut()), + Self::Verbatim(_) => None, + Self::__Nonexhaustive => None, + } + } +} + +impl MutItemAttrs for Vec { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + Some(self) + } +} + +impl MutItemAttrs for syn::ItemMod { + fn mut_item_attrs(&mut self) -> Option<&mut Vec> { + Some(&mut self.attrs) + } +} + +/// Return all doc attributes literals found. +pub fn get_doc_literals(attrs: &Vec) -> Vec { + attrs.iter() + .filter_map(|attr| { + if let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() { + if meta.path.get_ident().map_or(false, |ident| ident == "doc") { + Some(meta.lit.clone()) + } else { + None + } + } else { + None + } + }) + .collect() +} + +/// Parse for `()` +struct Unit; +impl syn::parse::Parse for Unit { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let content; + syn::parenthesized!(content in input); + if !content.is_empty() { + let msg = "unexpected tokens, expect nothing inside parenthesis as `()`"; + return Err(syn::Error::new(content.span(), msg)); + } + Ok(Self) + } +} + +/// Parse for `'static` +struct StaticLifetime; +impl syn::parse::Parse for StaticLifetime { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let lifetime = input.parse::()?; + if lifetime.ident != "static" { + let msg = "unexpected tokens, expect `static`"; + return Err(syn::Error::new(lifetime.ident.span(), msg)); + } + Ok(Self) + } +} + +/// Check the syntax: `I: 'static = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_config_def_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result<()> { + let expected = "expect `I: 'static = ()`"; + pub struct CheckTraitDefGenerics; + impl syn::parse::Parse for CheckTraitDefGenerics { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self) + } + } + + syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?; + + Ok(()) +} + +/// Check the syntax: +/// * either `T` +/// * or `T, I = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_type_def_gen_no_bounds( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result { + let expected = "expect `T` or `T, I = ()`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + has_instance: false, + span: input.span(), + }; + + input.parse::()?; + if input.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + } + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the syntax: +/// * either `` (no generics +/// * or `T` +/// * or `T: Config` +/// * or `T, I = ()` +/// * or `T: Config, I: 'static = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_type_def_optional_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result> { + let expected = "expect `` or `T` or `T: Config` or `T, I = ()` or \ + `T: Config, I: 'static = ()`"; + pub struct Checker(Option); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + if input.is_empty() { + return Ok(Self(None)) + } + + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + + if input.is_empty() { + return Ok(Self(Some(instance_usage))) + } + + let lookahead = input.lookahead1(); + if lookahead.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(Some(instance_usage))) + } else if lookahead.peek(syn::Token![:]) { + input.parse::()?; + input.parse::()?; + + if input.is_empty() { + return Ok(Self(Some(instance_usage))) + } + + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(Some(instance_usage))) + } else { + Err(lookahead.error()) + } + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0 + // Span can be call_site if generic is empty. Thus we replace it. + .map(|mut i| { i.span = span; i }); + + Ok(i) +} + +/// Check the syntax: +/// * either `Pallet` +/// * or `Pallet` +/// +/// return the instance if found. +pub fn check_pallet_struct_usage(type_: &Box) -> syn::Result { + let expected = "expect `Pallet` or `Pallet`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + } + input.parse::]>()?; + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(type_.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid pallet struct: {}", expected); + let mut err = syn::Error::new(type_.span(), msg); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the generic is: +/// * either `T: Config` +/// * or `T: Config, I: 'static` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return weither it contains instance. +pub fn check_impl_gen( + gen: &syn::Generics, + span: proc_macro2::Span +) -> syn::Result { + let expected = "expect `impl` or `impl, I: 'static>`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![<]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + } + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let mut err = syn::Error::new(span, format!("Invalid generics: {}", expected)); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the syntax: +/// * or `T` +/// * or `T: Config` +/// * or `T, I = ()` +/// * or `T: Config, I: 'static = ()` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_type_def_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result { + let expected = "expect `T` or `T: Config` or `T, I = ()` or \ + `T: Config, I: 'static = ()`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + + if input.is_empty() { + return Ok(Self(instance_usage)) + } + + let lookahead = input.lookahead1(); + if lookahead.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(instance_usage)) + } else if lookahead.peek(syn::Token![:]) { + input.parse::()?; + input.parse::()?; + + if input.is_empty() { + return Ok(Self(instance_usage)) + } + + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(instance_usage)) + } else { + Err(lookahead.error()) + } + } + } + + let mut i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0; + + // Span can be call_site if generic is empty. Thus we replace it. + i.span = span; + + Ok(i) +} + +/// Check the syntax: +/// * either `GenesisBuild` +/// * or `GenesisBuild` +/// +/// return the instance if found. +pub fn check_genesis_builder_usage(type_: &syn::Path) -> syn::Result { + let expected = "expect `GenesisBuild` or `GenesisBuild`"; + pub struct Checker(InstanceUsage); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + input.parse::()?; + input.parse::()?; + input.parse::()?; + if input.peek(syn::Token![,]) { + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + } + input.parse::]>()?; + + Ok(Self(instance_usage)) + } + } + + let i = syn::parse2::(type_.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid genesis builder: {}", expected); + let mut err = syn::Error::new(type_.span(), msg); + err.combine(e); + err + })?.0; + + Ok(i) +} + +/// Check the syntax: +/// * either `` (no generics) +/// * or `T: Config` +/// * or `T: Config, I: 'static` +/// +/// `span` is used in case generics is empty (empty generics has span == call_site). +/// +/// return the instance if found. +pub fn check_type_value_gen( + gen: &syn::Generics, + span: proc_macro2::Span, +) -> syn::Result> { + let expected = "expect `` or `T: Config` or `T: Config, I: 'static`"; + pub struct Checker(Option); + impl syn::parse::Parse for Checker { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + if input.is_empty() { + return Ok(Self(None)) + } + + input.parse::()?; + input.parse::()?; + input.parse::()?; + + let mut instance_usage = InstanceUsage { + span: input.span(), + has_instance: false, + }; + + if input.is_empty() { + return Ok(Self(Some(instance_usage))) + } + + instance_usage.has_instance = true; + input.parse::()?; + input.parse::()?; + input.parse::]>()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + input.parse::()?; + + Ok(Self(Some(instance_usage))) + } + } + + let i = syn::parse2::(gen.params.to_token_stream()) + .map_err(|e| { + let msg = format!("Invalid type def generics: {}", expected); + let mut err = syn::Error::new(span, msg); + err.combine(e); + err + })?.0 + // Span can be call_site if generic is empty. Thus we replace it. + .map(|mut i| { i.span = span; i }); + + Ok(i) +} diff --git a/frame/support/procedural/src/pallet/parse/hooks.rs b/frame/support/procedural/src/pallet/parse/hooks.rs new file mode 100644 index 0000000000000..ab3d31a327a49 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/hooks.rs @@ -0,0 +1,69 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use syn::spanned::Spanned; +use super::helper; + +/// Implementation of the pallet hooks. +pub struct HooksDef { + /// The index of item in pallet. + pub index: usize, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, + /// The where_clause used. + pub where_clause: Option, +} + +impl HooksDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + let msg = "Invalid pallet::hooks, expect item impl"; + return Err(syn::Error::new(item.span(), msg)); + }; + + let mut instances = vec![]; + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + + let item_trait = &item.trait_.as_ref() + .ok_or_else(|| { + let msg = "Invalid pallet::hooks, expect impl<..> Hooks \ + for Pallet<..>"; + syn::Error::new(item.span(), msg) + })?.1; + + if item_trait.segments.len() != 1 + || item_trait.segments[0].ident != "Hooks" + { + let msg = format!( + "Invalid pallet::hooks, expect trait to be `Hooks` found `{}`\ + , you can import from `frame_support::pallet_prelude`", + quote::quote!(#item_trait) + ); + + return Err(syn::Error::new(item_trait.span(), msg)); + } + + Ok(Self { + index, + instances, + where_clause: item.generics.where_clause.clone(), + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/inherent.rs b/frame/support/procedural/src/pallet/parse/inherent.rs new file mode 100644 index 0000000000000..b97d0fd8f2f2b --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/inherent.rs @@ -0,0 +1,58 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use syn::spanned::Spanned; +use super::helper; + +/// The definition of the pallet inherent implementation. +pub struct InherentDef { + /// The index of inherent item in pallet module. + pub index: usize, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, +} + +impl InherentDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::inherent, expect item impl")); + }; + + if item.trait_.is_none() { + let msg = "Invalid pallet::inherent, expect impl<..> ProvideInherent for Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() { + if last.ident != "ProvideInherent" { + let msg = "Invalid pallet::inherent, expect trait ProvideInherent"; + return Err(syn::Error::new(last.span(), msg)); + } + } else { + let msg = "Invalid pallet::inherent, expect impl<..> ProvideInherent for Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + + Ok(InherentDef { index, instances }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs new file mode 100644 index 0000000000000..36ba7e1847401 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -0,0 +1,412 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +//! Parse for pallet macro. +//! +//! Parse the module into `Def` struct through `Def::try_from` function. + +pub mod config; +pub mod pallet_struct; +pub mod hooks; +pub mod call; +pub mod error; +pub mod origin; +pub mod inherent; +pub mod storage; +pub mod event; +pub mod helper; +pub mod genesis_config; +pub mod genesis_build; +pub mod validate_unsigned; +pub mod type_value; +pub mod extra_constants; + +use syn::spanned::Spanned; +use frame_support_procedural_tools::generate_crate_access_2018; + +/// Parsed definition of a pallet. +pub struct Def { + /// The module items. + /// (their order must not be modified because they are registered in individual definitions). + pub item: syn::ItemMod, + pub config: config::ConfigDef, + pub pallet_struct: pallet_struct::PalletStructDef, + pub hooks: hooks::HooksDef, + pub call: call::CallDef, + pub storages: Vec, + pub error: Option, + pub event: Option, + pub origin: Option, + pub inherent: Option, + pub genesis_config: Option, + pub genesis_build: Option, + pub validate_unsigned: Option, + pub extra_constants: Option, + pub type_values: Vec, + pub frame_system: syn::Ident, + pub frame_support: syn::Ident, +} + +impl Def { + pub fn try_from(mut item: syn::ItemMod) -> syn::Result { + let frame_system = generate_crate_access_2018("frame-system")?; + let frame_support = generate_crate_access_2018("frame-support")?; + + let item_span = item.span().clone(); + let items = &mut item.content.as_mut() + .ok_or_else(|| { + let msg = "Invalid pallet definition, expect mod to be inlined."; + syn::Error::new(item_span, msg) + })?.1; + + let mut config = None; + let mut pallet_struct = None; + let mut hooks = None; + let mut call = None; + let mut error = None; + let mut event = None; + let mut origin = None; + let mut inherent = None; + let mut genesis_config = None; + let mut genesis_build = None; + let mut validate_unsigned = None; + let mut extra_constants = None; + let mut storages = vec![]; + let mut type_values = vec![]; + + for (index, item) in items.iter_mut().enumerate() { + let pallet_attr: Option = helper::take_first_item_attr(item)?; + + match pallet_attr { + Some(PalletAttr::Config(_)) if config.is_none() => + config = Some(config::ConfigDef::try_from(&frame_system, index, item)?), + Some(PalletAttr::Pallet(_)) if pallet_struct.is_none() => + pallet_struct = Some(pallet_struct::PalletStructDef::try_from(index, item)?), + Some(PalletAttr::Hooks(_)) if hooks.is_none() => { + let m = hooks::HooksDef::try_from(index, item)?; + hooks = Some(m); + }, + Some(PalletAttr::Call(span)) if call.is_none() => + call = Some(call::CallDef::try_from(span, index, item)?), + Some(PalletAttr::Error(_)) if error.is_none() => + error = Some(error::ErrorDef::try_from(index, item)?), + Some(PalletAttr::Event(_)) if event.is_none() => + event = Some(event::EventDef::try_from(index, item)?), + Some(PalletAttr::GenesisConfig(_)) if genesis_config.is_none() => { + genesis_config = + Some(genesis_config::GenesisConfigDef::try_from(index, item)?); + }, + Some(PalletAttr::GenesisBuild(_)) if genesis_build.is_none() => + genesis_build = Some(genesis_build::GenesisBuildDef::try_from(index, item)?), + Some(PalletAttr::Origin(_)) if origin.is_none() => + origin = Some(origin::OriginDef::try_from(index, item)?), + Some(PalletAttr::Inherent(_)) if inherent.is_none() => + inherent = Some(inherent::InherentDef::try_from(index, item)?), + Some(PalletAttr::Storage(_)) => + storages.push(storage::StorageDef::try_from(index, item)?), + Some(PalletAttr::ValidateUnsigned(_)) if validate_unsigned.is_none() => { + let v = validate_unsigned::ValidateUnsignedDef::try_from(index, item)?; + validate_unsigned = Some(v); + }, + Some(PalletAttr::TypeValue(_)) => + type_values.push(type_value::TypeValueDef::try_from(index, item)?), + Some(PalletAttr::ExtraConstants(_)) => { + extra_constants = + Some(extra_constants::ExtraConstantsDef::try_from(index, item)?) + }, + Some(attr) => { + let msg = "Invalid duplicated attribute"; + return Err(syn::Error::new(attr.span(), msg)); + }, + None => (), + } + } + + if genesis_config.is_some() != genesis_build.is_some() { + let msg = format!( + "`#[pallet::genesis_config]` and `#[pallet::genesis_build]` attributes must be \ + either both used or both not used, instead genesis_config is {} and genesis_build \ + is {}", + genesis_config.as_ref().map_or("unused", |_| "used"), + genesis_build.as_ref().map_or("unused", |_| "used"), + ); + return Err(syn::Error::new(item_span, msg)); + } + + let def = Def { + item: item, + config: config.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::config]`"))?, + pallet_struct: pallet_struct + .ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::pallet]`"))?, + hooks: hooks + .ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::hooks]`"))?, + call: call.ok_or_else(|| syn::Error::new(item_span, "Missing `#[pallet::call]"))?, + extra_constants, + genesis_config, + genesis_build, + validate_unsigned, + error, + event, + origin, + inherent, + storages, + type_values, + frame_system, + frame_support, + }; + + def.check_instance_usage()?; + def.check_event_usage()?; + + Ok(def) + } + + /// Check that usage of trait `Event` is consistent with the definition, i.e. it is declared + /// and trait defines type Event, or not declared and no trait associated type. + fn check_event_usage(&self) -> syn::Result<()> { + match ( + self.config.has_event_type, + self.event.is_some(), + ) { + (true, false) => { + let msg = "Invalid usage of Event, `Config` contains associated type `Event`, \ + but enum `Event` is not declared (i.e. no use of `#[pallet::event]`). \ + Note that type `Event` in trait is reserved to work alongside pallet event."; + Err(syn::Error::new(proc_macro2::Span::call_site(), msg)) + }, + (false, true) => { + let msg = "Invalid usage of Event, `Config` contains no associated type \ + `Event`, but enum `Event` is declared (in use of `#[pallet::event]`). \ + An Event associated type must be declare on trait `Config`."; + Err(syn::Error::new(proc_macro2::Span::call_site(), msg)) + }, + _ => Ok(()) + } + } + /// Check that usage of trait `Config` is consistent with the definition, i.e. it is used with + /// instance iff it is defined with instance. + fn check_instance_usage(&self) -> syn::Result<()> { + let mut instances = vec![]; + instances.extend_from_slice(&self.call.instances[..]); + instances.extend_from_slice(&self.pallet_struct.instances[..]); + instances.extend_from_slice(&self.hooks.instances[..]); + instances.extend(&mut self.storages.iter().flat_map(|s| s.instances.clone())); + if let Some(event) = &self.event { + instances.extend_from_slice(&event.instances[..]); + } + if let Some(error) = &self.error { + instances.extend_from_slice(&error.instances[..]); + } + if let Some(inherent) = &self.inherent { + instances.extend_from_slice(&inherent.instances[..]); + } + if let Some(origin) = &self.origin { + instances.extend_from_slice(&origin.instances[..]); + } + if let Some(genesis_config) = &self.genesis_config { + instances.extend_from_slice(&genesis_config.instances[..]); + } + if let Some(genesis_build) = &self.genesis_build { + instances.extend_from_slice(&genesis_build.instances[..]); + } + if let Some(extra_constants) = &self.extra_constants { + instances.extend_from_slice(&extra_constants.instances[..]); + } + + let mut errors = instances.into_iter() + .filter_map(|instances| { + if instances.has_instance == self.config.has_instance { + return None + } + let msg = if self.config.has_instance { + "Invalid generic declaration, trait is defined with instance but generic use none" + } else { + "Invalid generic declaration, trait is defined without instance but generic use \ + some" + }; + Some(syn::Error::new(instances.span, msg)) + }); + + if let Some(mut first_error) = errors.next() { + for error in errors { + first_error.combine(error) + } + Err(first_error) + } else { + Ok(()) + } + } + + /// Depending on if pallet is instantiable: + /// * either `T: Config` + /// * or `T: Config, I: 'static` + pub fn type_impl_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T: Config, I: 'static) + } else { + quote::quote!(T: Config) + } + } + + /// Depending on if pallet is instantiable: + /// * either `T: Config` + /// * or `T: Config, I: 'static = ()` + pub fn type_decl_bounded_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T: Config, I: 'static = ()) + } else { + quote::quote!(T: Config) + } + } + + /// Depending on if pallet is instantiable: + /// * either `T` + /// * or `T, I` + pub fn type_decl_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T, I) + } else { + quote::quote!(T) + } + } + + /// Depending on if pallet is instantiable: + /// * either `` + /// * or `` + /// to be used when using pallet trait `Config` + pub fn trait_use_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!() + } else { + quote::quote!() + } + } + + /// Depending on if pallet is instantiable: + /// * either `T` + /// * or `T, I` + pub fn type_use_generics(&self) -> proc_macro2::TokenStream { + if self.config.has_instance { + quote::quote!(T, I) + } else { + quote::quote!(T) + } + } +} + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(origin); + syn::custom_keyword!(call); + syn::custom_keyword!(event); + syn::custom_keyword!(config); + syn::custom_keyword!(hooks); + syn::custom_keyword!(inherent); + syn::custom_keyword!(error); + syn::custom_keyword!(storage); + syn::custom_keyword!(genesis_build); + syn::custom_keyword!(genesis_config); + syn::custom_keyword!(validate_unsigned); + syn::custom_keyword!(type_value); + syn::custom_keyword!(pallet); + syn::custom_keyword!(generate_store); + syn::custom_keyword!(Store); + syn::custom_keyword!(extra_constants); +} + +/// Parse attributes for item in pallet module +/// syntax must be `pallet::` (e.g. `#[pallet::config]`) +enum PalletAttr { + Config(proc_macro2::Span), + Pallet(proc_macro2::Span), + Hooks(proc_macro2::Span), + Call(proc_macro2::Span), + Error(proc_macro2::Span), + Event(proc_macro2::Span), + Origin(proc_macro2::Span), + Inherent(proc_macro2::Span), + Storage(proc_macro2::Span), + GenesisConfig(proc_macro2::Span), + GenesisBuild(proc_macro2::Span), + ValidateUnsigned(proc_macro2::Span), + TypeValue(proc_macro2::Span), + ExtraConstants(proc_macro2::Span), +} + +impl PalletAttr { + fn span(&self) -> proc_macro2::Span { + match self { + Self::Config(span) => span.clone(), + Self::Pallet(span) => span.clone(), + Self::Hooks(span) => span.clone(), + Self::Call(span) => span.clone(), + Self::Error(span) => span.clone(), + Self::Event(span) => span.clone(), + Self::Origin(span) => span.clone(), + Self::Inherent(span) => span.clone(), + Self::Storage(span) => span.clone(), + Self::GenesisConfig(span) => span.clone(), + Self::GenesisBuild(span) => span.clone(), + Self::ValidateUnsigned(span) => span.clone(), + Self::TypeValue(span) => span.clone(), + Self::ExtraConstants(span) => span.clone(), + } + } +} + +impl syn::parse::Parse for PalletAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + + let lookahead = content.lookahead1(); + if lookahead.peek(keyword::config) { + Ok(PalletAttr::Config(content.parse::()?.span())) + } else if lookahead.peek(keyword::pallet) { + Ok(PalletAttr::Pallet(content.parse::()?.span())) + } else if lookahead.peek(keyword::hooks) { + Ok(PalletAttr::Hooks(content.parse::()?.span())) + } else if lookahead.peek(keyword::call) { + Ok(PalletAttr::Call(content.parse::()?.span())) + } else if lookahead.peek(keyword::error) { + Ok(PalletAttr::Error(content.parse::()?.span())) + } else if lookahead.peek(keyword::event) { + Ok(PalletAttr::Event(content.parse::()?.span())) + } else if lookahead.peek(keyword::origin) { + Ok(PalletAttr::Origin(content.parse::()?.span())) + } else if lookahead.peek(keyword::inherent) { + Ok(PalletAttr::Inherent(content.parse::()?.span())) + } else if lookahead.peek(keyword::storage) { + Ok(PalletAttr::Storage(content.parse::()?.span())) + } else if lookahead.peek(keyword::genesis_config) { + Ok(PalletAttr::GenesisConfig(content.parse::()?.span())) + } else if lookahead.peek(keyword::genesis_build) { + Ok(PalletAttr::GenesisBuild(content.parse::()?.span())) + } else if lookahead.peek(keyword::validate_unsigned) { + Ok(PalletAttr::ValidateUnsigned(content.parse::()?.span())) + } else if lookahead.peek(keyword::type_value) { + Ok(PalletAttr::TypeValue(content.parse::()?.span())) + } else if lookahead.peek(keyword::extra_constants) { + Ok(PalletAttr::ExtraConstants(content.parse::()?.span())) + } else { + Err(lookahead.error()) + } + } +} diff --git a/frame/support/procedural/src/pallet/parse/origin.rs b/frame/support/procedural/src/pallet/parse/origin.rs new file mode 100644 index 0000000000000..1f5d535060e73 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/origin.rs @@ -0,0 +1,80 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use syn::spanned::Spanned; +use super::helper; + +/// Definition of the pallet origin type. +/// +/// Either: +/// * `type Origin` +/// * `struct Origin` +/// * `enum Origin` +pub struct OriginDef { + /// The index of item in pallet module. + pub index: usize, + pub has_instance: bool, + pub is_generic: bool, + /// A set of usage of instance, must be check for consistency with trait. + pub instances: Vec, +} + +impl OriginDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item_span = item.span(); + let (vis, ident, generics) = match &item { + syn::Item::Enum(item) => (&item.vis, &item.ident, &item.generics), + syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics), + syn::Item::Type(item) => (&item.vis, &item.ident, &item.generics), + _ => { + let msg = "Invalid pallet::origin, expect enum or struct or type"; + return Err(syn::Error::new(item.span(), msg)); + }, + }; + + let has_instance = generics.params.len() == 2; + let is_generic = generics.params.len() > 0; + + let mut instances = vec![]; + if let Some(u) = helper::check_type_def_optional_gen(&generics, item.span())? { + instances.push(u); + } else { + // construct_runtime only allow generic event for instantiable pallet. + instances.push(helper::InstanceUsage { + has_instance: false, + span: ident.span(), + }) + } + + if !matches!(vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::origin, Origin must be public"; + return Err(syn::Error::new(item_span, msg)); + } + + if ident != "Origin" { + let msg = "Invalid pallet::origin, ident must `Origin`"; + return Err(syn::Error::new(ident.span(), msg)); + } + + Ok(OriginDef { + index, + has_instance, + is_generic, + instances, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/pallet_struct.rs b/frame/support/procedural/src/pallet/parse/pallet_struct.rs new file mode 100644 index 0000000000000..6ed7c899a877f --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/pallet_struct.rs @@ -0,0 +1,99 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(pallet); + syn::custom_keyword!(Pallet); + syn::custom_keyword!(generate_store); + syn::custom_keyword!(Store); +} + +/// Definition of the pallet pallet. +pub struct PalletStructDef { + /// The index of item in pallet pallet. + pub index: usize, + /// A set of usage of instance, must be check for consistency with config trait. + pub instances: Vec, + /// The keyword Pallet used (contains span). + pub pallet: keyword::Pallet, + /// Weither the trait `Store` must be generated. + pub store: Option<(syn::Visibility, keyword::Store)> +} + +/// Parse for `#[pallet::generate_store($vis trait Store)]` +pub struct PalletStructAttr { + vis: syn::Visibility, + keyword: keyword::Store, +} + +impl syn::parse::Parse for PalletStructAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + content.parse::()?; + + let generate_content; + syn::parenthesized!(generate_content in content); + let vis = generate_content.parse::()?; + generate_content.parse::()?; + let keyword = generate_content.parse::()?; + Ok(Self { vis, keyword }) + } +} + +impl PalletStructDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Struct(item) = item { + item + } else { + let msg = "Invalid pallet::pallet, expect struct definition"; + return Err(syn::Error::new(item.span(), msg)); + }; + + let mut event_attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; + if event_attrs.len() > 1 { + let msg = "Invalid pallet::pallet, multiple argument pallet::generate_store found"; + return Err(syn::Error::new(event_attrs[1].keyword.span(), msg)); + } + let store = event_attrs.pop().map(|attr| (attr.vis, attr.keyword)); + + let pallet = syn::parse2::(item.ident.to_token_stream())?; + + if !matches!(item.vis, syn::Visibility::Public(_)) { + let msg = "Invalid pallet::pallet, Pallet must be public"; + return Err(syn::Error::new(item.span(), msg)); + } + + if item.generics.where_clause.is_some() { + let msg = "Invalid pallet::pallet, where clause not supported on Pallet declaration"; + return Err(syn::Error::new(item.generics.where_clause.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_type_def_gen_no_bounds(&item.generics, item.ident.span())?); + + Ok(Self { index, instances, pallet, store }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/storage.rs b/frame/support/procedural/src/pallet/parse/storage.rs new file mode 100644 index 0000000000000..ba1b24e76362a --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/storage.rs @@ -0,0 +1,221 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use syn::spanned::Spanned; +use quote::ToTokens; + +/// List of additional token to be used for parsing. +mod keyword { + syn::custom_keyword!(Error); + syn::custom_keyword!(pallet); + syn::custom_keyword!(getter); + syn::custom_keyword!(OptionQuery); + syn::custom_keyword!(ValueQuery); +} + +/// Parse for `#[pallet::getter(fn dummy)]` +pub struct PalletStorageAttr { + getter: syn::Ident, +} + +impl syn::parse::Parse for PalletStorageAttr { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse::()?; + let content; + syn::bracketed!(content in input); + content.parse::()?; + content.parse::()?; + content.parse::()?; + + let generate_content; + syn::parenthesized!(generate_content in content); + generate_content.parse::()?; + Ok(Self { getter: generate_content.parse::()? }) + } +} + +/// The value and key types used by storages. Needed to expand metadata. +pub enum Metadata{ + Value { value: syn::GenericArgument }, + Map { value: syn::GenericArgument, key: syn::GenericArgument }, + DoubleMap { + value: syn::GenericArgument, + key1: syn::GenericArgument, + key2: syn::GenericArgument + }, +} + +pub enum QueryKind { + OptionQuery, + ValueQuery, +} + +/// Definition of a storage, storage is a storage type like +/// `type MyStorage = StorageValue` +/// The keys and values types are parsed in order to get metadata +pub struct StorageDef { + /// The index of error item in pallet module. + pub index: usize, + /// Visibility of the storage type. + pub vis: syn::Visibility, + /// The type ident, to generate the StoragePrefix for. + pub ident: syn::Ident, + /// The keys and value metadata of the storage. + pub metadata: Metadata, + /// The doc associated to the storage. + pub docs: Vec, + /// A set of usage of instance, must be check for consistency with config. + pub instances: Vec, + /// Optional getter to generate. If some then query_kind is ensured to be some as well. + pub getter: Option, + /// Whereas the querytype of the storage is OptionQuery or ValueQuery. + /// Note that this is best effort as it can't be determined when QueryKind is generic, and + /// result can be false if user do some unexpected type alias. + pub query_kind: Option, + /// Where clause of type definition. + pub where_clause: Option, +} + +/// In `Foo` retrieve the argument at given position, i.e. A is argument at position 0. +fn retrieve_arg( + segment: &syn::PathSegment, + arg_pos: usize, +) -> syn::Result { + if let syn::PathArguments::AngleBracketed(args) = &segment.arguments { + if arg_pos < args.args.len() { + Ok(args.args[arg_pos].clone()) + } else { + let msg = format!("pallet::storage unexpected number of generic argument, expect at \ + least {} args, found {}", arg_pos + 1, args.args.len()); + Err(syn::Error::new(args.span(), msg)) + } + } else { + let msg = format!("pallet::storage unexpected number of generic argument, expect at least \ + {} args, found none", arg_pos + 1); + Err(syn::Error::new(segment.span(), msg)) + } +} + +impl StorageDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Type(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::storage, expect item type")); + }; + + let mut attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; + if attrs.len() > 1 { + let msg = "Invalid pallet::storage, multiple argument pallet::getter found"; + return Err(syn::Error::new(attrs[1].getter.span(), msg)); + } + let getter = attrs.pop().map(|attr| attr.getter); + + let mut instances = vec![]; + instances.push(helper::check_type_def_gen(&item.generics, item.ident.span())?); + + let where_clause = item.generics.where_clause.clone(); + let docs = helper::get_doc_literals(&item.attrs); + + let typ = if let syn::Type::Path(typ) = &*item.ty { + typ + } else { + let msg = "Invalid pallet::storage, expect type path"; + return Err(syn::Error::new(item.ty.span(), msg)); + }; + + if typ.path.segments.len() != 1 { + let msg = "Invalid pallet::storage, expect type path with one segment"; + return Err(syn::Error::new(item.ty.span(), msg)); + } + + let query_kind; + let metadata = match &*typ.path.segments[0].ident.to_string() { + "StorageValue" => { + query_kind = retrieve_arg(&typ.path.segments[0], 2); + Metadata::Value { + value: retrieve_arg(&typ.path.segments[0], 1)?, + } + } + "StorageMap" => { + query_kind = retrieve_arg(&typ.path.segments[0], 4); + Metadata::Map { + key: retrieve_arg(&typ.path.segments[0], 2)?, + value: retrieve_arg(&typ.path.segments[0], 3)?, + } + } + "StorageDoubleMap" => { + query_kind = retrieve_arg(&typ.path.segments[0], 6); + Metadata::DoubleMap { + key1: retrieve_arg(&typ.path.segments[0], 2)?, + key2: retrieve_arg(&typ.path.segments[0], 4)?, + value: retrieve_arg(&typ.path.segments[0], 5)?, + } + } + found @ _ => { + let msg = format!( + "Invalid pallet::storage, expect ident: `StorageValue` or \ + `StorageMap` or `StorageDoubleMap` in order to expand metadata, found \ + `{}`", + found, + ); + return Err(syn::Error::new(item.ty.span(), msg)); + } + }; + let query_kind = query_kind + .map(|query_kind| match query_kind { + syn::GenericArgument::Type(syn::Type::Path(path)) + if path.path.segments.last().map_or(false, |s| s.ident == "OptionQuery") + => Some(QueryKind::OptionQuery), + syn::GenericArgument::Type(syn::Type::Path(path)) + if path.path.segments.last().map_or(false, |s| s.ident == "ValueQuery") + => Some(QueryKind::ValueQuery), + _ => None, + }) + .unwrap_or(Some(QueryKind::OptionQuery)); // This value must match the default generic. + + if query_kind.is_none() && getter.is_some() { + let msg = "Invalid pallet::storage, cannot generate getter because QueryKind is not \ + identifiable. QueryKind must be `OptionQuery`, `ValueQuery`, or default one to be \ + identifiable."; + return Err(syn::Error::new(getter.unwrap().span(), msg)); + } + + let prefix_arg = retrieve_arg(&typ.path.segments[0], 0)?; + syn::parse2::(prefix_arg.to_token_stream()) + .map_err(|e| { + let msg = "Invalid use of `#[pallet::storage]`, the type first generic argument \ + must be `_`, the final argument is automatically set by macro."; + let mut err = syn::Error::new(prefix_arg.span(), msg); + err.combine(e); + err + })?; + + Ok(StorageDef { + index, + vis: item.vis.clone(), + ident: item.ident.clone(), + instances, + metadata, + docs, + getter, + query_kind, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/type_value.rs b/frame/support/procedural/src/pallet/parse/type_value.rs new file mode 100644 index 0000000000000..fd9ef197ac5a3 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/type_value.rs @@ -0,0 +1,100 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use super::helper; +use syn::spanned::Spanned; + +/// Definition of type value. Just a function which is expanded to a struct implementing `Get`. +pub struct TypeValueDef { + /// The index of error item in pallet module. + pub index: usize, + /// Visibility of the struct to generate. + pub vis: syn::Visibility, + /// Ident of the struct to generate. + pub ident: syn::Ident, + /// The type return by Get. + pub type_: Box, + /// The block returning the value to get + pub block: Box, + /// If type value is generic over `T` (or `T` and `I` for instantiable pallet) + pub is_generic: bool, + /// A set of usage of instance, must be check for consistency with config. + pub instances: Vec, + /// The where clause of the function. + pub where_clause: Option, +} + +impl TypeValueDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Fn(item) = item { + item + } else { + return Err(syn::Error::new(item.span(), "Invalid pallet::type_value, expect item fn")); + }; + + + if !item.attrs.is_empty() { + let msg = "Invalid pallet::type_value, unexpected attribute"; + return Err(syn::Error::new(item.attrs[0].span(), msg)); + } + + if let Some(span) = item.sig.constness.as_ref().map(|t| t.span()) + .or(item.sig.asyncness.as_ref().map(|t| t.span())) + .or(item.sig.unsafety.as_ref().map(|t| t.span())) + .or(item.sig.abi.as_ref().map(|t| t.span())) + .or(item.sig.variadic.as_ref().map(|t| t.span())) + { + let msg = "Invalid pallet::type_value, unexpected token"; + return Err(syn::Error::new(span, msg)); + } + + if !item.sig.inputs.is_empty() { + let msg = "Invalid pallet::type_value, unexpected argument"; + return Err(syn::Error::new(item.sig.inputs[0].span(), msg)); + } + + let vis = item.vis.clone(); + let ident = item.sig.ident.clone(); + let block = item.block.clone(); + let type_ = match item.sig.output.clone() { + syn::ReturnType::Type(_, type_) => type_, + syn::ReturnType::Default => { + let msg = "Invalid pallet::type_value, expect return type"; + return Err(syn::Error::new(item.sig.span(), msg)); + }, + }; + + let mut instances = vec![]; + if let Some(usage) = helper::check_type_value_gen(&item.sig.generics, item.sig.span())? { + instances.push(usage); + } + + let is_generic = item.sig.generics.type_params().count() > 0; + let where_clause = item.sig.generics.where_clause.clone(); + + Ok(TypeValueDef { + index, + is_generic, + vis, + ident, + block, + type_, + instances, + where_clause, + }) + } +} diff --git a/frame/support/procedural/src/pallet/parse/validate_unsigned.rs b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs new file mode 100644 index 0000000000000..a94c9b5fdd920 --- /dev/null +++ b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs @@ -0,0 +1,61 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use syn::spanned::Spanned; +use super::helper; + +/// The definition of the pallet validate unsigned implementation. +pub struct ValidateUnsignedDef { + /// The index of validate unsigned item in pallet module. + pub index: usize, + /// A set of usage of instance, must be check for consistency with config. + pub instances: Vec, +} + +impl ValidateUnsignedDef { + pub fn try_from(index: usize, item: &mut syn::Item) -> syn::Result { + let item = if let syn::Item::Impl(item) = item { + item + } else { + let msg = "Invalid pallet::validate_unsigned, expect item impl"; + return Err(syn::Error::new(item.span(), msg)); + }; + + if item.trait_.is_none() { + let msg = "Invalid pallet::validate_unsigned, expect impl<..> ValidateUnsigned for \ + Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() { + if last.ident != "ValidateUnsigned" { + let msg = "Invalid pallet::validate_unsigned, expect trait ValidateUnsigned"; + return Err(syn::Error::new(last.span(), msg)); + } + } else { + let msg = "Invalid pallet::validate_unsigned, expect impl<..> ValidateUnsigned for \ + Pallet<..>"; + return Err(syn::Error::new(item.span(), msg)); + } + + let mut instances = vec![]; + instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); + instances.push(helper::check_impl_gen(&item.generics, item.impl_token.span())?); + + Ok(ValidateUnsignedDef { index, instances }) + } +} diff --git a/frame/support/procedural/src/pallet_version.rs b/frame/support/procedural/src/pallet_version.rs index ffd4b41208d56..f0437d4cb6b7d 100644 --- a/frame/support/procedural/src/pallet_version.rs +++ b/frame/support/procedural/src/pallet_version.rs @@ -52,7 +52,7 @@ pub fn crate_to_pallet_version(input: proc_macro::TokenStream) -> Result("CARGO_PKG_VERSION_PATCH") .map_err(|_| create_error("Patch version needs to fit into `u8`"))?; - let crate_ = generate_crate_access_2018()?; + let crate_ = generate_crate_access_2018("frame-support")?; Ok(quote::quote! { #crate_::traits::PalletVersion { diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index 0aa0a3cad7cd1..cfb3369fa9a8a 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -25,6 +25,8 @@ mod metadata; mod instance_trait; mod genesis_config; +pub(crate) use instance_trait::INHERENT_INSTANCE_NAME; + use quote::quote; use frame_support_procedural_tools::{ generate_crate_access, generate_hidden_includes, syn_ext as ext diff --git a/frame/support/procedural/src/transactional.rs b/frame/support/procedural/src/transactional.rs index 3c2617a17e508..8c49a8deec1bb 100644 --- a/frame/support/procedural/src/transactional.rs +++ b/frame/support/procedural/src/transactional.rs @@ -23,7 +23,7 @@ use frame_support_procedural_tools::generate_crate_access_2018; pub fn transactional(_attr: TokenStream, input: TokenStream) -> Result { let ItemFn { attrs, vis, sig, block } = syn::parse(input)?; - let crate_ = generate_crate_access_2018()?; + let crate_ = generate_crate_access_2018("frame-support")?; let output = quote! { #(#attrs)* #vis #sig { @@ -45,7 +45,7 @@ pub fn transactional(_attr: TokenStream, input: TokenStream) -> Result Result { let ItemFn { attrs, vis, sig, block } = syn::parse(input)?; - let crate_ = generate_crate_access_2018()?; + let crate_ = generate_crate_access_2018("frame-support")?; let output = quote! { #(#attrs)* #vis #sig { diff --git a/frame/support/procedural/tools/src/lib.rs b/frame/support/procedural/tools/src/lib.rs index c5a27c809aff8..2cf559eab9b40 100644 --- a/frame/support/procedural/tools/src/lib.rs +++ b/frame/support/procedural/tools/src/lib.rs @@ -46,17 +46,17 @@ pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream { } } -/// Generate the crate access for the `frame-support` crate using 2018 syntax. +/// Generate the crate access for the crate using 2018 syntax. /// -/// Output will for example be `frame_support`. -pub fn generate_crate_access_2018() -> Result { - if std::env::var("CARGO_PKG_NAME").unwrap() == "frame-support" { - Ok(quote::quote!( frame_support )) +/// for `frame-support` output will for example be `frame_support`. +pub fn generate_crate_access_2018(def_crate: &str) -> Result { + if std::env::var("CARGO_PKG_NAME").unwrap() == def_crate { + let name = def_crate.to_string().replace("-", "_"); + Ok(syn::Ident::new(&name, Span::call_site())) } else { - match crate_name("frame-support") { + match crate_name(def_crate) { Ok(name) => { - let name = Ident::new(&name, Span::call_site()); - Ok(quote!( #name )) + Ok(Ident::new(&name, Span::call_site())) }, Err(e) => { Err(Error::new(Span::call_site(), &e)) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 36d316a9b9a1b..7bd2e00698930 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -80,7 +80,7 @@ pub use self::dispatch::{Parameter, Callable}; pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; /// A type that cannot be instantiated. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum Never {} /// Create new implementations of the [`Get`](crate::traits::Get) trait. @@ -949,3 +949,978 @@ mod tests { }) } } + +/// prelude to be used alongside pallet macro, for ease of use. +pub mod pallet_prelude { + pub use sp_std::marker::PhantomData; + pub use frame_support::traits::{Get, Hooks, IsType, GetPalletVersion, EnsureOrigin}; + #[cfg(feature = "std")] + pub use frame_support::traits::GenesisBuild; + pub use frame_support::dispatch::{DispatchResultWithPostInfo, Parameter, DispatchError}; + pub use frame_support::storage::types::{ + StorageValue, StorageMap, StorageDoubleMap, ValueQuery, OptionQuery, + }; + pub use frame_support::{ + EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, DebugNoBound, CloneNoBound + }; + pub use codec::{Encode, Decode}; + pub use sp_inherents::{InherentData, InherentIdentifier, ProvideInherent}; + pub use crate::weights::{DispatchClass, Pays, Weight}; + pub use crate::{ + Twox256, Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, + debug, ensure, RuntimeDebug, storage + }; + pub use sp_runtime::{ + traits::{MaybeSerializeDeserialize, Member, ValidateUnsigned}, + transaction_validity::{ + TransactionSource, TransactionValidity, ValidTransaction, TransactionPriority, + TransactionTag, TransactionLongevity, TransactionValidityError, InvalidTransaction, + UnknownTransaction, + }, + }; +} + +/// `pallet` attribute macro allows to define a pallet to be used in `construct_runtime!`. +/// +/// It is define by a module item: +/// ```ignore +/// #[pallet] +/// mod pallet { +/// ... +/// } +/// ``` +/// +/// Inside the module the macro will parse item with the attribute: `#[pallet::*]`, some attributes +/// are mandatory, some other optional. +/// +/// The attribute are explained with the syntax of non instantiable pallets, to see how pallet with +/// instance work see below example. +/// +/// Note various type can be automatically imported using pallet_prelude in frame_support and +/// frame_system: +/// ```ignore +/// #[pallet] +/// mod { +/// use frame_support::pallet_prelude::*; +/// use frame_system::pallet_prelude::*; +/// ... +/// } +/// ``` +/// +/// # Config trait: `#[pallet::config]` mandatory +/// +/// The trait defining generics of the pallet. +/// +/// Item must be defined as +/// ```ignore +/// #[pallet::config] +/// pub trait Config: frame_system::Config + $optionally_some_other_supertraits +/// $optional_where_clause +/// { +/// ... +/// } +/// ``` +/// I.e. a regular trait definition named `Config`, with supertrait `frame_system::Config`, +/// optionally other supertrait and where clause. +/// +/// The associated type `Event` is reserved, if defined it must bounds `From` and +/// `IsType<::Event>`, see `#[pallet::event]` for more information. +/// +/// To put `Get` associated type into metadatas, use the attribute `#[pallet::constant]`, e.g.: +/// ```ignore +/// #[pallet::config] +/// pub trait Config: frame_system::Config { +/// #[pallet::constant] +/// type Foo: Get; +/// } +/// ``` +/// +/// To bypass the `frame_system::Config` supertrait check, use the attribute +/// `#[pallet::disable_frame_system_supertrait_check]`, e.g.: +/// ```ignore +/// #[pallet::config] +/// #[pallet::disable_frame_system_supertrait_check] +/// pub trait Config: pallet_timestamp::Config {} +/// ``` +/// +/// ### Macro expansion: +/// +/// The macro expand pallet constant metadata with the information given by `#[pallet::constant]`. +/// +/// # Pallet struct placeholder: `#[pallet::pallet]` mandatory +/// +/// The placeholder struct, on which is implemented pallet informations. +/// +/// Item must be defined as followed: +/// ```ignore +/// #[pallet::pallet] +/// pub struct Pallet(PhantomData); +/// ``` +/// I.e. a regular struct definition named `Pallet`, with generic T and no where clause. +/// +/// To generate a `Store` trait associating all storages, use the attribute +/// `#[pallet::generate_store($vis trait Store)]`, e.g.: +/// ```ignore +/// #[pallet::pallet] +/// #[pallet::generate_store(pub(super) trait Store)] +/// pub struct Pallet(PhantomData); +/// ``` +/// More precisely the store trait contains an associated type for each storage. It is implemented +/// for `Pallet` allowing to access the storage from pallet struct. +/// +/// ### Macro expansion: +/// +/// The macro add this attribute to the struct definition: +/// ```ignore +/// #[derive( +/// frame_support::CloneNoBound, +/// frame_support::EqNoBound, +/// frame_support::PartialEqNoBound, +/// frame_support::RuntimeDebugNoBound, +/// )] +/// ``` +/// +/// It implements on pallet: +/// * [`GetPalletVersion`] +/// * [`OnGenesis`]: contains some logic to write pallet version into storage. +/// * [`ModuleErrorMetadata`]: using error declared or no metadata. +/// +/// If attribute generate_store then macro create the trait `Store` and implement it on `Pallet`. +/// +/// # Hooks: `#[pallet::hooks]` mandatory +/// +/// Implementation of `Hooks` on `Pallet` allowing to define some specific pallet logic. +/// +/// Item must be defined as +/// ```ignore +/// #[pallet::hooks] +/// impl Hooks> for Pallet $optional_where_clause { +/// } +/// ``` +/// I.e. a regular trait implementation with generic bound: `T: Config`, for the trait +/// `Hooks>` (they are defined in preludes), for the type `Pallet` +/// and with an optional where clause. +/// +/// ### Macro expansion: +/// +/// The macro implements the traits `OnInitialize`, `OnFinalize`, `OnRuntimeUpgrade`, +/// `OffchainWorker`, `IntegrityTest` using `Hooks` implementation. +/// +/// NOTE: OnRuntimeUpgrade is implemented with `Hooks::on_runtime_upgrade` and some additional +/// logic. E.g. logic to write pallet version into storage. +/// +/// # Call: `#[pallet::call]` mandatory +/// +/// Implementation of pallet dispatchables. +/// +/// Item must be defined as: +/// ```ignore +/// #[pallet::call] +/// impl Pallet { +/// /// $some_doc +/// #[pallet::weight($ExpressionResultingInWeight)] +/// $vis fn $fn_name( +/// origin: OriginFor, +/// $some_arg: $some_type, +/// // or with compact attribute: #[pallet::compact] $some_arg: $some_type, +/// ... +/// ) -> DispatchResultWithPostInfo { +/// ... +/// } +/// ... +/// } +/// ``` +/// I.e. a regular type implementation, with generic `T: Config`, on type `Pallet`, with +/// optional where clause. +/// +/// Each dispatchable needs to define a weight with `#[pallet::weight($expr)]` attribute, +/// the first argument must be `origin: OriginFor`, compact encoding for argument can be used +/// using `#[pallet::compact]`, function must return DispatchResultWithPostInfo. +/// +/// All arguments must implement `Debug`, `PartialEq`, `Eq`, `Decode`, `Encode`, `Clone`. For ease +/// of use just bound trait `Member` available in frame_support::pallet_prelude. +/// +/// **WARNING**: modifying dispatchables, changing their order, removing some must be done with +/// care. Indeed this will change the outer runtime call type (which is an enum with one variant +/// per pallet), this outer runtime call can be stored on-chain (e.g. in pallet-scheduler). +/// Thus migration might be needed. +/// +/// ### Macro expansion +/// +/// The macro create an enum `Call` with one variant per dispatchable. This enum implements: +/// `Clone`, `Eq`, `PartialEq`, `Debug` (with stripped implementation in `not("std")`), `Encode`, +/// `Decode`, `GetDispatchInfo`, `GetCallName`, `UnfilteredDispatchable`. +/// +/// The macro implement on `Pallet`, the `Callable` trait and a function `call_functions` which +/// returns the dispatchable metadatas. +/// +/// # Extra constants: `#[pallet::extra_constants]` optional +/// +/// Allow to define some extra constants to put into constant metadata. +/// +/// Item must be defined as: +/// ```ignore +/// #[pallet::extra_constants] +/// impl Pallet where $optional_where_clause { +/// /// $some_doc +/// $vis fn $fn_name() -> $some_return_type { +/// ... +/// } +/// ... +/// } +/// ``` +/// I.e. a regular rust implement block with some optional where clause and functions with 0 args, +/// 0 generics, and some return type. +/// +/// ### Macro expansion +/// +/// The macro add some extra constant to pallet constant metadata. +/// +/// # Error: `#[pallet::error]` optional +/// +/// Allow to define an error type to be return from dispatchable on error. +/// This error type informations are put into metadata. +/// +/// Item must be defined as: +/// ```ignore +/// #[pallet::error] +/// pub enum Error { +/// /// $some_optional_doc +/// $SomeFieldLessVariant, +/// ... +/// } +/// ``` +/// I.e. a regular rust enum named `Error`, with generic `T` and fieldless variants. +/// +/// ### Macro expansion +/// +/// The macro implements `Debug` trait and functions `as_u8` using variant position, and `as_str` +/// using variant doc. +/// +/// The macro implements `From>` for `&'static str`. +/// The macro implements `From>` for `DispatchError`. +/// +/// The macro implements `ModuleErrorMetadata` on `Pallet` defining the `ErrorMetadata` of the +/// pallet. +/// +/// # Event: `#[pallet::event]` optional +/// +/// Allow to define pallet events, pallet events are stored in the block when they deposited (and +/// removed in next block). +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::event] +/// #[pallet::metadata($SomeType = "$Metadata", $SomeOtherType = "$Metadata", ..)] // Optional +/// #[pallet::generate_deposit($visbility fn deposit_event)] // Optional +/// pub enum Event<$some_generic> $optional_where_clause { +/// /// Some doc +/// $SomeName($SomeType, $YetanotherType, ...), +/// ... +/// } +/// ``` +/// I.e. an enum (with named or unnamed fields variant), named Event, with generic: none or `T` or +/// `T: Config`, and optional where clause. +/// +/// Each field must implement `Clone`, `Eq`, `PartialEq`, `Encode`, `Decode`, and `Debug` (on std +/// only). +/// For ease of use just bound trait `Member` available in frame_support::pallet_prelude. +/// +/// Variant documentations and field types are put into metadata. +/// The attribute `#[pallet::metadata(..)]` allows to specify the metadata to put for some types. +/// +/// The metadat of a type is defined by: +/// * if matching a type in `#[pallet::metadata(..)]`, then the corresponding metadata. +/// * otherwise the last segment of the type. +/// +/// E.g.: +/// ```ignore +/// #[pallet::event] +/// #[pallet::metadata(u32 = "SpecialU32")] +/// pub enum Event { +/// Proposed(u32, T::AccountId), +/// } +/// ``` +/// will write in event variant metadata `"SpecialU32"` and `"AccountId"`. +/// +/// The attribute `#[pallet::generate_deposit($visbility fn deposit_event)]` generate a helper +/// function on `Pallet` to deposit event. +/// +/// NOTE: For instantiable pallet, event must be generic over T and I. +/// +/// ### Macro expansion: +/// +/// Macro will add on enum `Event` the attributes: +/// * `#[derive(frame_support::CloneNoBound)]`, +/// * `#[derive(frame_support::EqNoBound)]`, +/// * `#[derive(frame_support::PartialEqNoBound)]`, +/// * `#[derive(codec::Encode)]`, +/// * `#[derive(codec::Decode)]`, +/// * `#[derive(frame_support::RuntimeDebugNoBound)]` +/// +/// Macro implements `From>` for (). +/// +/// Macro implements metadata function on `Event` returning the `EventMetadata`. +/// +/// If `#[pallet::generate_deposit]` then macro implement `fn deposit_event` on `Pallet`. +/// +/// # Storage: `#[pallet::storage]` optional +/// +/// Allow to define some abstract storage inside runtime storage and also set its metadata. +/// This attribute can be used multiple times. +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::storage] +/// #[pallet::getter(fn $getter_name)] // optional +/// $vis type $StorageName<$some_generic> $optional_where_clause = $StorageType<_, $some_generics, ...>; +/// ``` +/// I.e. it must be a type alias, with generics: `T` or `T: Config`, aliased type must be one +/// of `StorageValue`, `StorageMap` or `StorageDoubleMap` (defined in frame_support). +/// Their first generic must be `_` as it is written by the macro itself. +/// +/// The Prefix generic written by the macro is generated using PalletInfo::name and the name of the +/// storage type. +/// E.g. if runtime name the pallet MyExample the storage `type Foo = ...` use +/// prefixes: `Twox128(b"MyExample") ++ Twox128(b"Foo")`. +/// +/// The optional attribute `#[pallet::getter(fn $my_getter_fn_name)]` allow to define a +/// getter function on `Pallet`. +/// +/// E.g: +/// ```ignore +/// #[pallet::storage] +/// #[pallet::getter(fn my_storage)] +/// pub(super) type MyStorage = StorageMap<_, Blake2_128Concat, u32, u32>; +/// ``` +/// +/// NOTE: if the querykind generic parameter is still generic at this stage or is using some type +/// alias then the generation of the getter might fail. In this case getter can be implemented +/// manually. +/// +/// ### Macro expansion +/// +/// For each storage the macro generate a struct named +/// `_GeneratedPrefixForStorage$NameOfStorage`, implements StorageInstance on it using pallet +/// names and storage name. and use it as first generic of the aliased type. +/// +/// The macro implement the function `storage_metadata` on `Pallet` implementing the metadata for +/// storages. +/// +/// # Type value: `#[pallet::type_value]` optional +/// +/// Helper to define a struct implementing `Get` trait. To ease use of storage types. +/// This attribute can be used multiple time. +/// +/// Item is defined as +/// ```ignore +/// #[pallet::type_value] +/// fn $MyDefaultName<$some_generic>() -> $default_type $optional_where_clause { $expr } +/// ``` +/// I.e.: a function definition with generics none or `T: Config` and a returned type. +/// +/// E.g.: +/// ```ignore +/// #[pallet::type_value] +/// fn MyDefault() -> T::Balance { 3.into() } +/// ``` +/// +/// NOTE: This attribute is meant to be used alongside `#[pallet::storage]` to defined some +/// specific default value in storage. +/// +/// ### Macro expansion +/// +/// Macro generate struct with the name of the function and its generic, and implement +/// `Get<$ReturnType>` on it using the provided function block. +/// +/// # Genesis config: `#[pallet::genesis_config]` optional +/// +/// Allow to define the genesis configuration of the pallet. +/// +/// Item is defined as either a type alias or an enum or a struct. +/// It needs to be public and implement trait GenesisBuild with `#[pallet::genesis_build]`. +/// The type generics is constrained to be either none, or `T` or `T: Config`. +/// +/// E.g: +/// ```ignore +/// #[pallet::genesis_config] +/// pub struct GenesisConfig { +/// _myfield: BalanceOf, +/// } +/// ``` +/// +/// ### Macro expansion +/// +/// Macro will add the following attribute on it: +/// * `#[cfg(feature = "std")]` +/// * `#[derive(Serialize, Deserialize)]` +/// * `#[serde(rename_all = "camelCase")]` +/// * `#[serde(deny_unknown_fields)]` +/// * `#[serde(bound(serialize = ""))]` +/// * `#[serde(bound(deserialize = ""))]` +/// +/// # Genesis build: `#[pallet::genesis_build]` optional +/// +/// Allow to define how genesis_configuration is built. +/// +/// Item is defined as +/// ```ignore +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig<$maybe_generics> { +/// fn build(&self) { $expr } +/// } +/// ``` +/// I.e. a rust trait implementation with generic `T: Config`, of trait `GenesisBuild` on type +/// `GenesisConfig` with generics none or `T`. +/// +/// E.g.: +/// ```ignore +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig { +/// fn build(&self) {} +/// } +/// ``` +/// +/// ### Macro expansion +/// +/// Macro will add the following attribute on it: +/// * `#[cfg(feature = "std")]` +/// +/// Macro will implement `sp_runtime::BuildModuleGenesisStorage` using `()` as second generic for +/// non-instantiable pallets. +/// +/// # Inherent: `#[pallet::inherent]` optional +/// +/// Allow the pallet to provide some inherent: +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::inherent] +/// impl ProvideInherent for Pallet { +/// // ... regular trait implementation +/// } +/// ``` +/// I.e. a trait implementation with bound `T: Config`, of trait `ProvideInherent` for type +/// `Pallet`, and some optional where clause. +/// +/// ### Macro expansion +/// +/// Macro make currenlty no use of this information, but it might use this information in the +/// future to give information directly to construct_runtime. +/// +/// # Validate unsigned: `#[pallet::validate_unsigned]` optional +/// +/// Allow the pallet to validate some unsigned transaction: +/// +/// Item is defined as: +/// ```ignore +/// #[pallet::validate_unsigned] +/// impl ValidateUnsigned for Pallet { +/// // ... regular trait implementation +/// } +/// ``` +/// I.e. a trait implementation with bound `T: Config`, of trait `ValidateUnsigned` for type +/// `Pallet`, and some optional where clause. +/// +/// NOTE: There is also `sp_runtime::traits::SignedExtension` that can be used to add some specific +/// logic for transaction validation. +/// +/// ### Macro expansion +/// +/// Macro make currenlty no use of this information, but it might use this information in the +/// future to give information directly to construct_runtime. +/// +/// # Origin: `#[pallet::origin]` optional +/// +/// Allow to define some origin for the pallet. +/// +/// Item must be either a type alias or an enum or a struct. It needs to be public. +/// +/// E.g.: +/// ```ignore +/// #[pallet::origin] +/// pub struct Origin(PhantomData<(T)>); +/// ``` +/// +/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin can +/// be stored on-chain (e.g. in pallet-scheduler), thus any change must be done with care as it +/// might require some migration. +/// +/// NOTE: for instantiable pallet, origin must be generic over T and I. +/// +/// # General notes on instantiable pallet +/// +/// An instantiable pallet is one where Config is generic, i.e. `Config`. This allow runtime to +/// implement multiple instance of the pallet, by using different type for the generic. +/// This is the sole purpose of the generic `I`. +/// But because `PalletInfo` requires `Pallet` placeholder to be static it is important to bound +/// `'static` whenever `PalletInfo` can be used. +/// And in order to have instantiable pallet usable as a regular pallet without instance, it is +/// important to bound `= ()` on every types. +/// +/// Thus impl bound look like `impl, I: 'static>`, and types look like +/// `SomeType` or `SomeType, I: 'static = ()>`. +/// +/// # Example for pallet without instance. +/// +/// ``` +/// #[frame_support::pallet] +/// // NOTE: Example is name of the pallet, it will be used as unique identifier for storage +/// pub mod pallet { +/// use frame_support::pallet_prelude::*; // Import various types used in pallet definition +/// use frame_system::pallet_prelude::*; // OriginFor helper type for implementing dispatchables. +/// +/// type BalanceOf = ::Balance; +/// +/// // Define the generic parameter of the pallet +/// // The macro checks trait generics: is expected none or `I = ()`. +/// // The macro parses `#[pallet::constant]` attributes: used to generate constant metadata, +/// // expected syntax is `type $IDENT: Get<$TYPE>;`. +/// #[pallet::config] +/// pub trait Config: frame_system::Config { +/// #[pallet::constant] // put the constant in metadata +/// type MyGetParam: Get; +/// type Balance: Parameter + From; +/// type Event: From> + IsType<::Event>; +/// } +/// +/// // Define some additional constant to put into the constant metadata. +/// #[pallet::extra_constants] +/// impl Pallet { +/// /// Some description +/// fn exra_constant_name() -> u128 { 4u128 } +/// } +/// +/// // Define the pallet struct placeholder, various pallet function are implemented on it. +/// // The macro checks struct generics: is expected `T` or `T, I = DefaultInstance` +/// #[pallet::pallet] +/// #[pallet::generate_store(pub(super) trait Store)] +/// pub struct Pallet(PhantomData); +/// +/// // Implement on the pallet hooks on pallet. +/// // The macro checks: +/// // * trait is `Hooks` (imported from pallet_prelude) +/// // * struct is `Pallet` or `Pallet` +/// #[pallet::hooks] +/// impl Hooks> for Pallet { +/// } +/// +/// // Declare Call struct and implement dispatchables. +/// // +/// // WARNING: Each parameter used in functions must implement: Clone, Debug, Eq, PartialEq, +/// // Codec. +/// // +/// // The macro checks: +/// // * pallet is `Pallet` or `Pallet` +/// // * trait is `Call` +/// // * each dispatchable functions first argument is `origin: OriginFor` (OriginFor is +/// // imported from frame_system. +/// // +/// // The macro parse `#[pallet::compact]` attributes, function parameter with this attribute +/// // will be encoded/decoded using compact codec in implementation of codec for the enum +/// // `Call`. +/// // +/// // The macro generate the enum `Call` with a variant for each dispatchable and implements +/// // codec, Eq, PartialEq, Clone and Debug. +/// #[pallet::call] +/// impl Pallet { +/// /// Doc comment put in metadata +/// #[pallet::weight(0)] // Defines weight for call (function parameters are in scope) +/// fn toto( +/// origin: OriginFor, +/// #[pallet::compact] _foo: u32 +/// ) -> DispatchResultWithPostInfo { +/// let _ = origin; +/// unimplemented!(); +/// } +/// } +/// +/// // Declare pallet Error enum. (this is optional) +/// // The macro checks enum generics and that each variant is unit. +/// // The macro generate error metadata using doc comment on each variant. +/// #[pallet::error] +/// pub enum Error { +/// /// doc comment put into metadata +/// InsufficientProposersBalance, +/// } +/// +/// // Declare pallet Event enum. (this is optional) +/// // +/// // WARNING: Each type used in variants must implement: Clone, Debug, Eq, PartialEq, Codec. +/// // +/// // The macro generates event metadata, and derive Clone, Debug, Eq, PartialEq and Codec +/// #[pallet::event] +/// // Additional argument to specify the metadata to use for given type. +/// #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] +/// // Generate a funciton on Pallet to deposit an event. +/// #[pallet::generate_deposit(pub(super) fn deposit_event)] +/// pub enum Event { +/// /// doc comment put in metadata +/// // `::AccountId` is not defined in metadata list, the last +/// // segment is put into metadata, i.e. `AccountId` +/// Proposed(::AccountId), +/// /// doc +/// // here metadata will be `Balance` as define in metadata list +/// Spending(BalanceOf), +/// // here metadata will be `Other` as define in metadata list +/// Something(u32), +/// } +/// +/// // Define a struct which implements `frame_support::traits::Get` +/// #[pallet::type_value] +/// pub(super) fn MyDefault() -> T::Balance { 3.into() } +/// +/// // Declare a storage, any amount of storage can be declared. +/// // +/// // Is expected either `StorageValue`, `StorageMap` or `StorageDoubleMap`. +/// // The macro generates for struct `$identP` (for storage of name `$ident`) and implement +/// // storage instance on it. +/// // The macro macro expand the metadata for the storage with the type used: +/// // * For storage value the type for value will be copied into metadata +/// // * For storage map the type for value and the type for key will be copied into metadata +/// // * For storage double map the type for value, key1, and key2 will be copied into +/// // metadata. +/// // +/// // NOTE: for storage hasher, the type is not copied because storage hasher trait already +/// // implements metadata. Thus generic storage hasher is supported. +/// #[pallet::storage] +/// pub(super) type MyStorageValue = +/// StorageValue<_, T::Balance, ValueQuery, MyDefault>; +/// +/// // Another declaration +/// #[pallet::storage] +/// #[pallet::getter(fn my_storage)] +/// pub(super) type MyStorage = StorageMap<_, Blake2_128Concat, u32, u32>; +/// +/// // Declare genesis config. (This is optional) +/// // +/// // The macro accept either type alias or struct or enum, it checks generics are consistent. +/// // +/// // Type must implement `Default` traits +/// #[pallet::genesis_config] +/// #[derive(Default)] +/// pub struct GenesisConfig { +/// _myfield: u32, +/// } +/// +/// // Declare genesis builder. (This is need only if GenesisConfig is declared) +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig { +/// fn build(&self) {} +/// } +/// +/// // Declare a pallet origin. (this is optional) +/// // +/// // The macro accept type alias or struct or enum, it checks generics are consistent. +/// #[pallet::origin] +/// pub struct Origin(PhantomData); +/// +/// // Declare validate_unsigned implementation. +/// #[pallet::validate_unsigned] +/// impl ValidateUnsigned for Pallet { +/// type Call = Call; +/// fn validate_unsigned( +/// source: TransactionSource, +/// call: &Self::Call +/// ) -> TransactionValidity { +/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) +/// } +/// } +/// +/// // Declare inherent provider for pallet. (this is optional) +/// // +/// // The macro checks pallet is `Pallet` or `Pallet` and trait is `ProvideInherent` +/// #[pallet::inherent] +/// impl ProvideInherent for Pallet { +/// type Call = Call; +/// type Error = InherentError; +/// +/// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; +/// +/// fn create_inherent(_data: &InherentData) -> Option { +/// unimplemented!(); +/// } +/// } +/// +/// // Regular rust code needed for implementing ProvideInherent trait +/// +/// #[derive(codec::Encode, sp_runtime::RuntimeDebug)] +/// #[cfg_attr(feature = "std", derive(codec::Decode))] +/// pub enum InherentError { +/// } +/// +/// impl sp_inherents::IsFatalError for InherentError { +/// fn is_fatal_error(&self) -> bool { +/// unimplemented!(); +/// } +/// } +/// +/// pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +/// } +/// ``` +/// +/// # Example for pallet with instance. +/// +/// ``` +/// #[frame_support::pallet] +/// pub mod pallet { +/// use frame_support::pallet_prelude::*; +/// use frame_system::pallet_prelude::*; +/// +/// type BalanceOf = >::Balance; +/// +/// #[pallet::config] +/// pub trait Config: frame_system::Config { +/// #[pallet::constant] +/// type MyGetParam: Get; +/// type Balance: Parameter + From; +/// type Event: From> + IsType<::Event>; +/// } +/// +/// #[pallet::extra_constants] +/// impl, I: 'static> Pallet { +/// /// Some description +/// fn exra_constant_name() -> u128 { 4u128 } +/// } +/// +/// #[pallet::pallet] +/// #[pallet::generate_store(pub(super) trait Store)] +/// pub struct Pallet(PhantomData<(T, I)>); +/// +/// #[pallet::hooks] +/// impl, I: 'static> Hooks> for Pallet { +/// } +/// +/// #[pallet::call] +/// impl, I: 'static> Pallet { +/// /// Doc comment put in metadata +/// #[pallet::weight(0)] +/// fn toto(origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { +/// let _ = origin; +/// unimplemented!(); +/// } +/// } +/// +/// #[pallet::error] +/// pub enum Error { +/// /// doc comment put into metadata +/// InsufficientProposersBalance, +/// } +/// +/// #[pallet::event] +/// #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] +/// #[pallet::generate_deposit(pub(super) fn deposit_event)] +/// pub enum Event, I: 'static = ()> { +/// /// doc comment put in metadata +/// Proposed(::AccountId), +/// /// doc +/// Spending(BalanceOf), +/// Something(u32), +/// } +/// +/// #[pallet::type_value] +/// pub(super) fn MyDefault, I: 'static>() -> T::Balance { 3.into() } +/// +/// #[pallet::storage] +/// pub(super) type MyStorageValue, I: 'static = ()> = +/// StorageValue<_, T::Balance, ValueQuery, MyDefault>; +/// +/// #[pallet::storage] +/// #[pallet::getter(fn my_storage)] +/// pub(super) type MyStorage = +/// StorageMap<_, Blake2_128Concat, u32, u32>; +/// +/// #[pallet::genesis_config] +/// #[derive(Default)] +/// pub struct GenesisConfig { +/// _myfield: u32, +/// } +/// +/// #[pallet::genesis_build] +/// impl, I: 'static> GenesisBuild for GenesisConfig { +/// fn build(&self) {} +/// } +/// +/// #[pallet::origin] +/// pub struct Origin(PhantomData<(T, I)>); +/// +/// #[pallet::validate_unsigned] +/// impl, I: 'static> ValidateUnsigned for Pallet { +/// type Call = Call; +/// fn validate_unsigned( +/// source: TransactionSource, +/// call: &Self::Call +/// ) -> TransactionValidity { +/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) +/// } +/// } +/// +/// #[pallet::inherent] +/// impl, I: 'static> ProvideInherent for Pallet { +/// type Call = Call; +/// type Error = InherentError; +/// +/// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; +/// +/// fn create_inherent(_data: &InherentData) -> Option { +/// unimplemented!(); +/// } +/// } +/// +/// // Regular rust code needed for implementing ProvideInherent trait +/// +/// #[derive(codec::Encode, sp_runtime::RuntimeDebug)] +/// #[cfg_attr(feature = "std", derive(codec::Decode))] +/// pub enum InherentError { +/// } +/// +/// impl sp_inherents::IsFatalError for InherentError { +/// fn is_fatal_error(&self) -> bool { +/// unimplemented!(); +/// } +/// } +/// +/// pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +/// } +/// ``` +/// +/// ## Upgrade guidelines: +/// +/// 1. make crate compiling: rename usage of frame_system::Trait to frame_system::Config. +/// 2. export metadata of the pallet for later checks +/// 3. reorganize pallet to have trait Trait, decl_* macros, ValidateUnsigned, ProvideInherent, +/// Origin all together in one file. suggested order: +/// * trait, +/// * decl_module, +/// * decl_event, +/// * decl_error, +/// * decl_storage, +/// * origin, +/// * validate_unsigned, +/// * provide_inherent, +/// so far it should compile and all be correct. +/// 4. start writing new pallet module +/// ```ignore +/// pub use pallet::*; +/// #[frame_support::pallet] +/// mod pallet { +/// pub use frame_support::pallet_prelude::*; +/// pub use frame_system::pallet_prelude::*; +/// use super::*; +/// +/// #[pallet::pallet] +/// #[pallet::generete($visibility_of_trait_store trait Store)] +/// // NOTE: if the visibility of trait store is private but you want to make it available +/// // in super, then use `pub(super)` or `pub(crate)` to make it available in crate. +/// pub struct Pallet(PhantomData); +/// // pub struct Pallet(PhantomData); // for instantiable pallet +/// } +/// ``` +/// 5. **migrate trait**: move trait into the module with +/// * rename `Trait` to `Config` +/// * all const in decl_module to `#[pallet::constant]` +/// 6. **migrate decl_module**: write: +/// ```ignore +/// #[pallet::hooks] +/// impl Hooks for Pallet { +/// } +/// ``` +/// and write inside on_initialize/on_finalize/on_runtime_upgrade/offchain_worker/integrity_test +/// +/// then write: +/// ```ignore +/// #[pallet::call] +/// impl Pallet { +/// } +/// ``` +/// and write inside all the call in decl_module with a few changes in the signature: +/// - origin must now be written completly, e.g. `origin: OriginFor` +/// - result type must be `DispatchResultWithPostInfo`, you need to write it and also you might +/// need to put `Ok(().into())` at the end or the function. +/// - `#[compact]` must now be written `#[pallet::compact]` +/// - `#[weight = ..]` must now be written `#[pallet::weight(..)]` +/// +/// 7. **migrate event**: +/// rewrite as a simple enum under with the attribute `#[pallet::event]`, +/// use `#[pallet::generate_deposit($vis fn deposit_event)]` to generate deposit_event, +/// use `#[pallet::metadata(...)]` to configure the metadata for types in order not to break them. +/// 8. **migrate error**: just rewrite it with attribute `#[pallet::error]`. +/// 9. **migrate storage**: +/// first migrate the genesis logic. write: +/// ```ignore +/// #[pallet::genesis_config] +/// struct GenesisConfig { +/// // fields of add_extra_genesis +/// } +/// impl Default for GenesisConfig { +/// // type default or default provided for fields +/// } +/// #[pallet::genesis_build] +/// impl GenesisBuild for GenesisConfig { +/// // impl GenesisBuild for GenesisConfig { for instantiable pallet +/// fn build() { +/// // The add_extra_genesis build logic +/// } +/// } +/// ``` +/// for each storages, if it contains config(..) then add a fields, and make its default to the +/// value in `= ..;` or the type default if none, if it contains no build then also add the +/// logic to build the value. +/// for each storages if it contains build(..) then add the logic to genesis_build. +/// +/// NOTE: in decl_storage: is executed first the individual config and build and at the end the +/// add_extra_genesis build +/// +/// Once this is done you can migrate storage individually, a few notes: +/// - for private storage use `pub(crate) type ` or `pub(super) type` or nothing, +/// - for storage with `get(fn ..)` use `#[pallet::getter(fn ...)]` +/// - for storage with value being `Option<$something>` make generic `Value` being `$something` +/// and generic `QueryKind` being `OptionQuery` (note: this is default). Otherwise make +/// `Value` the complete value type and `QueryKind` being `ValueQuery`. +/// - for storage with default value: `= $expr;` provide some specific OnEmpty generic. To do so +/// use of `#[pallet::type_value]` to generate the wanted struct to put. +/// example: `MyStorage: u32 = 3u32` would be written: +/// ```ignore +/// #[pallet::type_value] fn MyStorageOnEmpty() -> u32 { 3u32 } +/// #[pallet::storage] +/// pub(super) type MyStorage = StorageValue; +/// ``` +/// +/// NOTE: decl_storage also generates functions `assimilate_storage` and `build_storage` +/// directly on GenesisConfig, those are sometimes used in tests. In order not to break they +/// can be implemented manually, just implement those functions by calling `GenesisBuild` +/// implementation. +/// +/// 10. **migrate origin**: just move the origin to the pallet module under `#[pallet::origin]` +/// 11. **migrate validate_unsigned**: just move the ValidateUnsigned implementation to the pallet +/// module under `#[pallet::validate_unsigned]` +/// 12. **migrate provide_inherent**: just move the ValidateUnsigned implementation to the pallet +/// module under `#[pallet::provide_inherent]` +/// 13. rename the usage of Module to Pallet and the usage of Config to Trait inside the crate. +/// 14. migration is done, now double check migration with the checking migration guidelines. +/// +/// ## Checking upgrade guidelines: +/// +/// * compare metadata. This checks for: +/// * call, names, signature, doc +/// * event names, docs +/// * error names, docs +/// * storage names, hasher, prefixes, default value +/// * error , error, constant, +/// * manually check that: +/// * Origin is moved inside macro unser `#[pallet::origin]` if it exists +/// * ValidateUnsigned is moved inside macro under `#[pallet::validate_unsigned)]` if it exists +/// * ProvideInherent is moved inside macro under `#[pallet::inherent)]` if it exists +/// * on_initialize/on_finalize/on_runtime_upgrade/offchain_worker are moved to Hooks +/// implementation +/// * storages with `config(..)` are converted to genesis_config field, and their default is +/// `= $expr;` if the storage have default value +/// * storages with `build($expr)` or `config(..)` are built in genesis_build +/// * add_extra_genesis fields are converted to genesis_config field with their correct default +/// if specified +/// * add_extra_genesis build is written into genesis_build +/// * storages now use PalletInfo for module_prefix instead of the one given to decl_storage: +/// Thus any use of this pallet in `construct_runtime!` should be careful to update name in +/// order not to break storage or to upgrade storage (moreover for instantiable pallet). +/// If pallet is published, make sure to warn about this breaking change. +pub use frame_support_procedural::pallet; diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index bc1700a43c3ee..81640e691ff19 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1856,6 +1856,79 @@ pub trait IsSubType { fn is_sub_type(&self) -> Option<&T>; } +/// The pallet hooks trait. Implementing this lets you express some logic to execute. +pub trait Hooks { + /// The block is being finalized. Implement to have something happen. + fn on_finalize(_n: BlockNumber) {} + + /// The block is being initialized. Implement to have something happen. + /// + /// Return the non-negotiable weight consumed in the block. + fn on_initialize(_n: BlockNumber) -> crate::weights::Weight { 0 } + + /// Perform a module upgrade. + /// + /// NOTE: this doesn't include all pallet logic triggered on runtime upgrade. For instance it + /// doesn't include the write of the pallet version in storage. The final complete logic + /// triggered on runtime upgrade is given by implementation of `OnRuntimeUpgrade` trait by + /// `Pallet`. + /// + /// # Warning + /// + /// This function will be called before we initialized any runtime state, aka `on_initialize` + /// wasn't called yet. So, information like the block number and any other + /// block local data are not accessible. + /// + /// Return the non-negotiable weight consumed for runtime upgrade. + fn on_runtime_upgrade() -> crate::weights::Weight { 0 } + + /// Implementing this function on a module allows you to perform long-running tasks + /// that make (by default) validators generate transactions that feed results + /// of those long-running computations back on chain. + /// + /// NOTE: This function runs off-chain, so it can access the block state, + /// but cannot preform any alterations. More specifically alterations are + /// not forbidden, but they are not persisted in any way after the worker + /// has finished. + /// + /// This function is being called after every block import (when fully synced). + /// + /// Implement this and use any of the `Offchain` `sp_io` set of APIs + /// to perform off-chain computations, calls and submit transactions + /// with results to trigger any on-chain changes. + /// Any state alterations are lost and are not persisted. + fn offchain_worker(_n: BlockNumber) {} + + /// Run integrity test. + /// + /// The test is not executed in a externalities provided environment. + fn integrity_test() {} +} + +/// A trait to define the build function of a genesis config, T and I are placeholder for pallet +/// trait and pallet instance. +#[cfg(feature = "std")] +pub trait GenesisBuild: Default + MaybeSerializeDeserialize { + /// The build function is called within an externalities allowing storage APIs. + /// Thus one can write to storage using regular pallet storages. + fn build(&self); + + /// Build the storage using `build` inside default storage. + fn build_storage(&self) -> Result { + let mut storage = Default::default(); + self.assimilate_storage(&mut storage)?; + Ok(storage) + } + + /// Assimilate the storage for this module into pre-existing overlays. + fn assimilate_storage(&self, storage: &mut sp_runtime::Storage) -> Result<(), String> { + sp_state_machine::BasicExternalities::execute_with_storage(storage, || { + self.build(); + Ok(()) + }) + } +} + /// The storage key postfix that is used to store the [`PalletVersion`] per pallet. /// /// The full storage key is built by using: diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index ee8ace5c983c5..45b44b8282964 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -24,6 +24,7 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../../primiti trybuild = "1.0.33" pretty_assertions = "0.6.1" rustversion = "1.0.0" +frame-system = { version = "2.0.0", default-features = false, path = "../../system" } frame-metadata = { version = "12.0.0", default-features = false, path = "../../metadata" } [features] @@ -38,4 +39,5 @@ std = [ "sp-std/std", "sp-runtime/std", "sp-state-machine", + "frame-system/std", ] diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs new file mode 100644 index 0000000000000..143f32802bf9c --- /dev/null +++ b/frame/support/test/tests/pallet.rs @@ -0,0 +1,675 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use frame_support::{ + weights::{DispatchInfo, DispatchClass, Pays, GetDispatchInfo}, + traits::{GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade, GetPalletVersion, OnGenesis}, + dispatch::{UnfilteredDispatchable, Parameter}, + storage::unhashed, +}; +use sp_runtime::{traits::Block as _, DispatchError}; +use sp_io::{TestExternalities, hashing::{twox_64, twox_128, blake2_128}}; + +pub struct SomeType1; +impl From for u64 { fn from(_t: SomeType1) -> Self { 0u64 } } + +pub struct SomeType2; +impl From for u64 { fn from(_t: SomeType2) -> Self { 100u64 } } + +pub struct SomeType3; +impl From for u64 { fn from(_t: SomeType3) -> Self { 0u64 } } + +pub struct SomeType4; +impl From for u64 { fn from(_t: SomeType4) -> Self { 0u64 } } + +pub struct SomeType5; +impl From for u64 { fn from(_t: SomeType5) -> Self { 0u64 } } + +pub struct SomeType6; +impl From for u64 { fn from(_t: SomeType6) -> Self { 0u64 } } + +pub struct SomeType7; +impl From for u64 { fn from(_t: SomeType7) -> Self { 0u64 } } + +pub trait SomeAssociation1 { type _1: Parameter; } +impl SomeAssociation1 for u64 { type _1 = u64; } + +pub trait SomeAssociation2 { type _2: Parameter; } +impl SomeAssociation2 for u64 { type _2 = u64; } + +#[frame_support::pallet] +pub mod pallet { + use super::{ + SomeType1, SomeType2, SomeType3, SomeType4, SomeType5, SomeType6, SomeType7, + SomeAssociation1, SomeAssociation2, + }; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + type BalanceOf = ::Balance; + + #[pallet::config] + pub trait Config: frame_system::Config + where ::AccountId: From + SomeAssociation1, + { + /// Some comment + /// Some comment + #[pallet::constant] + type MyGetParam: Get; + + /// Some comment + /// Some comment + #[pallet::constant] + type MyGetParam2: Get; + + #[pallet::constant] + type MyGetParam3: Get<::_1>; + + type Balance: Parameter + Default; + + type Event: From> + IsType<::Event>; + } + + #[pallet::extra_constants] + impl Pallet + where T::AccountId: From + SomeAssociation1 + From, + { + /// Some doc + /// Some doc + fn some_extra() -> T::AccountId { SomeType2.into() } + + /// Some doc + fn some_extra_extra() -> T::AccountId { SomeType1.into() } + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet + where T::AccountId: From + From + SomeAssociation1, + { + fn on_initialize(_: BlockNumberFor) -> Weight { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + Self::deposit_event(Event::Something(10)); + 10 + } + fn on_finalize(_: BlockNumberFor) { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + Self::deposit_event(Event::Something(20)); + } + fn on_runtime_upgrade() -> Weight { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + Self::deposit_event(Event::Something(30)); + 30 + } + fn integrity_test() { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType2); // Test for where clause + } + } + + #[pallet::call] + impl Pallet + where T::AccountId: From + From + SomeAssociation1 + { + /// Doc comment put in metadata + #[pallet::weight(Weight::from(*_foo))] + fn foo(origin: OriginFor, #[pallet::compact] _foo: u32, _bar: u32) -> DispatchResultWithPostInfo { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType3); // Test for where clause + let _ = origin; + Self::deposit_event(Event::Something(3)); + Ok(().into()) + } + + /// Doc comment put in metadata + #[pallet::weight(1)] + #[frame_support::transactional] + fn foo_transactional(_origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { + Ok(().into()) + } + } + + #[pallet::error] + pub enum Error { + /// doc comment put into metadata + InsufficientProposersBalance, + } + + #[pallet::event] + #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event where T::AccountId: SomeAssociation1 + From{ + /// doc comment put in metadata + Proposed(::AccountId), + /// doc + Spending(BalanceOf), + Something(u32), + SomethingElse(::_1), + } + + #[pallet::storage] + pub type ValueWhereClause where T::AccountId: SomeAssociation2 = + StorageValue<_, ::_2>; + + #[pallet::storage] + pub type Value = StorageValue<_, u32>; + + #[pallet::type_value] + pub fn MyDefault() -> u16 where T::AccountId: From + From + SomeAssociation1 { + T::AccountId::from(SomeType7); // Test where clause works + 4u16 + } + + #[pallet::storage] + pub type Map where T::AccountId: From = + StorageMap<_, Blake2_128Concat, u8, u16, ValueQuery, MyDefault>; + + #[pallet::storage] + pub type Map2 = StorageMap<_, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap = StorageDoubleMap<_, Blake2_128Concat, u8, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap2 = StorageDoubleMap<_, Twox64Concat, u16, Blake2_128Concat, u32, u64>; + + #[pallet::genesis_config] + #[derive(Default)] + pub struct GenesisConfig { + _myfield: u32, + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig + where T::AccountId: From + SomeAssociation1 + From + { + fn build(&self) { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType4); // Test for where clause + } + } + + #[pallet::origin] + #[derive(EqNoBound, RuntimeDebugNoBound, CloneNoBound, PartialEqNoBound, Encode, Decode)] + pub struct Origin(PhantomData); + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet + where T::AccountId: From + SomeAssociation1 + From + From + { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call + ) -> TransactionValidity { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType5); // Test for where clause + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } + + #[pallet::inherent] + impl ProvideInherent for Pallet + where T::AccountId: From + SomeAssociation1 + From + From + { + type Call = Call; + type Error = InherentError; + + const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; + + fn create_inherent(_data: &InherentData) -> Option { + T::AccountId::from(SomeType1); // Test for where clause + T::AccountId::from(SomeType6); // Test for where clause + unimplemented!(); + } + } + + #[derive(codec::Encode, sp_runtime::RuntimeDebug)] + #[cfg_attr(feature = "std", derive(codec::Decode))] + pub enum InherentError { + } + + impl sp_inherents::IsFatalError for InherentError { + fn is_fatal_error(&self) -> bool { + unimplemented!(); + } + } + + pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +} + +frame_support::parameter_types!( + pub const MyGetParam: u32= 10; + pub const MyGetParam2: u32= 11; + pub const MyGetParam3: u32= 12; + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: frame_support::weights::Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one(); +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + type Hash = sp_runtime::testing::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = frame_support::weights::constants::RocksDbWeight; + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type MyGetParam = MyGetParam; + type MyGetParam2 = MyGetParam2; + type MyGetParam3 = MyGetParam3; + type Balance = u64; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Pallet, Call, Event}, + Example: pallet::{Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + } +); + +#[test] +fn call_expand() { + let call_foo = pallet::Call::::foo(3, 0); + assert_eq!( + call_foo.get_dispatch_info(), + DispatchInfo { + weight: 3, + class: DispatchClass::Normal, + pays_fee: Pays::Yes, + } + ); + assert_eq!(call_foo.get_call_name(), "foo"); + assert_eq!( + pallet::Call::::get_call_names(), + &["foo", "foo_transactional"], + ); +} + +#[test] +fn error_expand() { + assert_eq!( + format!("{:?}", pallet::Error::::InsufficientProposersBalance), + String::from("InsufficientProposersBalance"), + ); + assert_eq!( + <&'static str>::from(pallet::Error::::InsufficientProposersBalance), + "InsufficientProposersBalance", + ); + assert_eq!( + DispatchError::from(pallet::Error::::InsufficientProposersBalance), + DispatchError::Module { + index: 1, + error: 0, + message: Some("InsufficientProposersBalance"), + }, + ); +} + +#[test] +fn instance_expand() { + // Assert same type. + let _: pallet::__InherentHiddenInstance = (); +} + +#[test] +fn pallet_expand_deposit_event() { + TestExternalities::default().execute_with(|| { + frame_system::Pallet::::set_block_number(1); + pallet::Call::::foo(3, 0).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Pallet::::events()[0].event, + Event::pallet(pallet::Event::Something(3)), + ); + }) +} + +#[test] +fn storage_expand() { + use frame_support::pallet_prelude::*; + use frame_support::StoragePrefixedMap; + + fn twox_64_concat(d: &[u8]) -> Vec { + let mut v = twox_64(d).to_vec(); + v.extend_from_slice(d); + v + } + + fn blake2_128_concat(d: &[u8]) -> Vec { + let mut v = blake2_128(d).to_vec(); + v.extend_from_slice(d); + v + } + + TestExternalities::default().execute_with(|| { + pallet::Value::::put(1); + let k = [twox_128(b"Example"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); + + pallet::Map::::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(2u16)); + assert_eq!(&k[..32], &>::final_prefix()); + + pallet::Map2::::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + pallet::DoubleMap::::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + k.extend(2u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + pallet::DoubleMap2::::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + k.extend(2u32.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(3u64)); + assert_eq!(&k[..32], &>::final_prefix()); + }) +} + +#[test] +fn pallet_hooks_expand() { + TestExternalities::default().execute_with(|| { + frame_system::Pallet::::set_block_number(1); + + assert_eq!(AllModules::on_initialize(1), 10); + AllModules::on_finalize(1); + + assert_eq!(pallet::Pallet::::storage_version(), None); + assert_eq!( + AllModules::on_runtime_upgrade(), + 30 + ::DbWeight::get().writes(1) + ); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + + assert_eq!( + frame_system::Pallet::::events()[0].event, + Event::pallet(pallet::Event::Something(10)), + ); + assert_eq!( + frame_system::Pallet::::events()[1].event, + Event::pallet(pallet::Event::Something(20)), + ); + assert_eq!( + frame_system::Pallet::::events()[2].event, + Event::pallet(pallet::Event::Something(30)), + ); + }) +} + +#[test] +fn pallet_on_genesis() { + TestExternalities::default().execute_with(|| { + assert_eq!(pallet::Pallet::::storage_version(), None); + pallet::Pallet::::on_genesis(); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + }) +} + +#[test] +fn metadata() { + use frame_metadata::*; + use codec::{Decode, Encode}; + + let expected_pallet_metadata = ModuleMetadata { + index: 1, + name: DecodeDifferent::Decoded("Example".to_string()), + storage: Some(DecodeDifferent::Decoded(StorageMetadata { + prefix: DecodeDifferent::Decoded("Example".to_string()), + entries: DecodeDifferent::Decoded(vec![ + StorageEntryMetadata { + name: DecodeDifferent::Decoded("ValueWhereClause".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain( + DecodeDifferent::Decoded( + "::_2".to_string() + ), + ), + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Value".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Decoded("u32".to_string())), + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map".to_string()), + modifier: StorageEntryModifier::Default, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u8".to_string()), + value: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![4, 0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u16".to_string()), + value: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u32".to_string()), + key1: DecodeDifferent::Decoded("u8".to_string()), + key2: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + key2_hasher: StorageHasher::Twox64Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u64".to_string()), + key1: DecodeDifferent::Decoded("u16".to_string()), + key2: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + key2_hasher: StorageHasher::Blake2_128Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ]), + })), + calls: Some(DecodeDifferent::Decoded(vec![ + FunctionMetadata { + name: DecodeDifferent::Decoded("foo".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + }, + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_bar".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + FunctionMetadata { + name: DecodeDifferent::Decoded("foo_transactional".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + ])), + event: Some(DecodeDifferent::Decoded(vec![ + EventMetadata { + name: DecodeDifferent::Decoded("Proposed".to_string()), + arguments: DecodeDifferent::Decoded(vec!["AccountId".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put in metadata".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Spending".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Balance".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Something".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Other".to_string()]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("SomethingElse".to_string()), + arguments: DecodeDifferent::Decoded(vec!["_1".to_string()]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ])), + constants: DecodeDifferent::Decoded(vec![ + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + value: DecodeDifferent::Decoded(vec![10, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some comment".to_string(), + " Some comment".to_string(), + ]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam2".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + value: DecodeDifferent::Decoded(vec![11, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some comment".to_string(), + " Some comment".to_string(), + ]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam3".to_string()), + ty: DecodeDifferent::Decoded("::_1".to_string()), + value: DecodeDifferent::Decoded(vec![12, 0, 0, 0, 0, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("some_extra".to_string()), + ty: DecodeDifferent::Decoded("T::AccountId".to_string()), + value: DecodeDifferent::Decoded(vec![100, 0, 0, 0, 0, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some doc".to_string(), + " Some doc".to_string(), + ]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("some_extra_extra".to_string()), + ty: DecodeDifferent::Decoded("T::AccountId".to_string()), + value: DecodeDifferent::Decoded(vec![0, 0, 0, 0, 0, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![ + " Some doc".to_string(), + ]), + }, + ]), + errors: DecodeDifferent::Decoded(vec![ + ErrorMetadata { + name: DecodeDifferent::Decoded("InsufficientProposersBalance".to_string()), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put into metadata".to_string(), + ]), + }, + ]), + }; + + let metadata = match Runtime::metadata().1 { + RuntimeMetadata::V12(metadata) => metadata, + _ => panic!("metadata has been bump, test needs to be updated"), + }; + + let modules_metadata = match metadata.modules { + DecodeDifferent::Encode(modules_metadata) => modules_metadata, + _ => unreachable!(), + }; + + let pallet_metadata = ModuleMetadata::decode(&mut &modules_metadata[1].encode()[..]).unwrap(); + + pretty_assertions::assert_eq!(pallet_metadata, expected_pallet_metadata); +} diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs new file mode 100644 index 0000000000000..48418ae57611f --- /dev/null +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -0,0 +1,300 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use sp_runtime::traits::Block as _; + +pub trait SomeAssociation { + type A: frame_support::dispatch::Parameter + Default; +} +impl SomeAssociation for u64 { + type A = u64; +} + +mod pallet_old { + use frame_support::{ + decl_storage, decl_error, decl_event, decl_module, weights::Weight, traits::Get, Parameter + }; + use frame_system::ensure_root; + use super::SomeAssociation; + + pub trait Trait: frame_system::Trait { + type SomeConst: Get; + type Balance: Parameter + codec::HasCompact + From + Into + Default + + SomeAssociation; + type Event: From> + Into<::Event>; + } + + decl_storage! { + trait Store for Module as Example { + /// Some documentation + Dummy get(fn dummy) config(): Option; + Bar get(fn bar) config(): map hasher(blake2_128_concat) T::AccountId => T::Balance; + Foo get(fn foo) config(): T::Balance = 3.into(); + Double get(fn double): double_map + hasher(blake2_128_concat) u32, + hasher(twox_64_concat) u64 + => ::A; + } + } + + decl_event!( + pub enum Event where Balance = ::Balance { + /// Dummy event, just here so there's a generic type that's used. + Dummy(Balance), + } + ); + + decl_module! { + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + fn deposit_event() = default; + const SomeConst: T::Balance = T::SomeConst::get(); + + #[weight = >::into(new_value.clone())] + fn set_dummy(origin, #[compact] new_value: T::Balance) { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(RawEvent::Dummy(new_value)); + } + + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + } + + decl_error! { + pub enum Error for Module { + /// Some wrong behavior + Wrong, + } + } +} + +#[frame_support::pallet] +pub mod pallet { + use super::SomeAssociation; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use frame_system::ensure_root; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Balance: Parameter + codec::HasCompact + From + Into + Default + + MaybeSerializeDeserialize + SomeAssociation; + #[pallet::constant] + type SomeConst: Get; + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks for Pallet { + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + + #[pallet::call] + impl Pallet { + #[pallet::weight(>::into(new_value.clone()))] + fn set_dummy( + origin: OriginFor, + #[pallet::compact] new_value: T::Balance + ) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(Event::Dummy(new_value)); + + Ok(().into()) + } + } + + #[pallet::error] + pub enum Error { + /// Some wrong behavior + Wrong, + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event { + /// Dummy event, just here so there's a generic type that's used. + Dummy(T::Balance), + } + + #[pallet::storage] + /// Some documentation + type Dummy = StorageValue<_, T::Balance, OptionQuery>; + + #[pallet::storage] + type Bar = StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, ValueQuery>; + + #[pallet::type_value] pub fn OnFooEmpty() -> T::Balance { 3.into() } + #[pallet::storage] + type Foo = StorageValue<_, T::Balance, ValueQuery, OnFooEmpty>; + + #[pallet::storage] + type Double = StorageDoubleMap< + _, Blake2_128Concat, u32, Twox64Concat, u64, ::A, ValueQuery + >; + + #[pallet::genesis_config] + pub struct GenesisConfig { + dummy: Option, + bar: Vec<(T::AccountId, T::Balance)>, + foo: T::Balance, + } + + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + dummy: Default::default(), + bar: Default::default(), + foo: OnFooEmpty::::get(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + if let Some(dummy) = self.dummy.as_ref() { + >::put(dummy); + } + for (k, v) in &self.bar { + >::insert(k, v); + } + >::put(&self.foo); + } + } +} + +frame_support::parameter_types!( + pub const SomeConst: u64 = 10; + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: frame_support::weights::Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one(); +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + type Hash = sp_runtime::testing::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = frame_support::weights::constants::RocksDbWeight; + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Trait for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Module, Call, Event}, + // NOTE: name Example here is needed in order to have same module prefix + Example: pallet::{Pallet, Call, Event, Config, Storage}, + PalletOld: pallet_old::{Module, Call, Event, Config, Storage}, + } +); + +#[cfg(test)] +mod test { + use super::Runtime; + use super::pallet; + use super::pallet_old; + use codec::{Decode, Encode}; + + #[test] + fn metadata() { + let metadata = Runtime::metadata(); + let modules = match metadata.1 { + frame_metadata::RuntimeMetadata::V12(frame_metadata::RuntimeMetadataV12 { + modules: frame_metadata::DecodeDifferent::Encode(m), + .. + }) => m, + _ => unreachable!(), + }; + pretty_assertions::assert_eq!(modules[1].storage, modules[2].storage); + pretty_assertions::assert_eq!(modules[1].calls, modules[2].calls); + pretty_assertions::assert_eq!(modules[1].event, modules[2].event); + pretty_assertions::assert_eq!(modules[1].constants, modules[2].constants); + pretty_assertions::assert_eq!(modules[1].errors, modules[2].errors); + } + + #[test] + fn types() { + assert_eq!( + pallet_old::Event::::decode(&mut &pallet::Event::::Dummy(10).encode()[..]).unwrap(), + pallet_old::Event::::Dummy(10), + ); + + assert_eq!( + pallet_old::Call::::decode(&mut &pallet::Call::::set_dummy(10).encode()[..]).unwrap(), + pallet_old::Call::::set_dummy(10), + ); + } +} diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs new file mode 100644 index 0000000000000..7da9d7ed83e20 --- /dev/null +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -0,0 +1,311 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use sp_runtime::traits::Block as _; + +mod pallet_old { + use frame_support::{ + decl_storage, decl_error, decl_event, decl_module, weights::Weight, traits::Get, Parameter + }; + use frame_system::ensure_root; + + pub trait Trait: frame_system::Trait { + type SomeConst: Get; + type Balance: Parameter + codec::HasCompact + From + Into + Default; + type Event: From> + Into<::Event>; + } + + decl_storage! { + trait Store for Module, I: Instance = DefaultInstance> as Example { + /// Some documentation + Dummy get(fn dummy) config(): Option; + Bar get(fn bar) config(): map hasher(blake2_128_concat) T::AccountId => T::Balance; + Foo get(fn foo) config(): T::Balance = 3.into(); + Double get(fn double): double_map hasher(blake2_128_concat) u32, hasher(twox_64_concat) u64 => u16; + } + } + + decl_event!( + pub enum Event where Balance = >::Balance { + /// Dummy event, just here so there's a generic type that's used. + Dummy(Balance), + } + ); + + decl_module! { + pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { + type Error = Error; + fn deposit_event() = default; + const SomeConst: T::Balance = T::SomeConst::get(); + + #[weight = >::into(new_value.clone())] + fn set_dummy(origin, #[compact] new_value: T::Balance) { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(RawEvent::Dummy(new_value)); + } + + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + } + + decl_error! { + pub enum Error for Module, I: Instance> { + /// Some wrong behavior + Wrong, + } + } +} + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use frame_system::ensure_root; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Balance: Parameter + codec::HasCompact + From + Into + Default + + MaybeSerializeDeserialize; + #[pallet::constant] + type SomeConst: Get; + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks for Pallet { + fn on_initialize(_n: T::BlockNumber) -> Weight { + >::put(T::Balance::from(10)); + 10 + } + + fn on_finalize(_n: T::BlockNumber) { + >::put(T::Balance::from(11)); + } + } + + #[pallet::call] + impl, I: 'static> Pallet { + #[pallet::weight(>::into(new_value.clone()))] + fn set_dummy(origin: OriginFor, #[pallet::compact] new_value: T::Balance) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + + >::put(&new_value); + Self::deposit_event(Event::Dummy(new_value)); + + Ok(().into()) + } + } + + #[pallet::error] + pub enum Error { + /// Some wrong behavior + Wrong, + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// Dummy event, just here so there's a generic type that's used. + Dummy(T::Balance), + } + + #[pallet::storage] + /// Some documentation + type Dummy, I: 'static = ()> = StorageValue<_, T::Balance, OptionQuery>; + + #[pallet::storage] + type Bar, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, T::AccountId, T::Balance, ValueQuery>; + + #[pallet::storage] + type Foo, I: 'static = ()> = + StorageValue<_, T::Balance, ValueQuery, OnFooEmpty>; + #[pallet::type_value] pub fn OnFooEmpty, I: 'static>() -> T::Balance { 3.into() } + + #[pallet::storage] + type Double = StorageDoubleMap< + _, Blake2_128Concat, u32, Twox64Concat, u64, u16, ValueQuery + >; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + dummy: Option, + bar: Vec<(T::AccountId, T::Balance)>, + foo: T::Balance, + } + + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + dummy: Default::default(), + bar: Default::default(), + foo: OnFooEmpty::::get(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + if let Some(dummy) = self.dummy.as_ref() { + >::put(dummy); + } + for (k, v) in &self.bar { + >::insert(k, v); + } + >::put(&self.foo); + } + } +} + +frame_support::parameter_types!( + pub const SomeConst: u64 = 10; + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: frame_support::weights::Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one(); +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + type Hash = sp_runtime::testing::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = frame_support::weights::constants::RocksDbWeight; + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet::Config for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Trait for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Trait for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} +impl pallet_old::Trait for Runtime { + type Event = Event; + type SomeConst = SomeConst; + type Balance = u64; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Pallet, Call, Event}, + Example: pallet::{Pallet, Call, Event, Config, Storage}, + PalletOld: pallet_old::{Module, Call, Event, Config, Storage}, + Instance2Example: pallet::::{Pallet, Call, Event, Config, Storage}, + PalletOld2: pallet_old::::{Module, Call, Event, Config, Storage}, + Instance3Example: pallet::::{Pallet, Call, Event, Config, Storage}, + PalletOld3: pallet_old::::{Module, Call, Event, Config, Storage}, + } +); + +#[cfg(test)] +mod test { + use super::Runtime; + use super::pallet; + use super::pallet_old; + use codec::{Decode, Encode}; + + #[test] + fn metadata() { + let metadata = Runtime::metadata(); + let modules = match metadata.1 { + frame_metadata::RuntimeMetadata::V12(frame_metadata::RuntimeMetadataV12 { + modules: frame_metadata::DecodeDifferent::Encode(m), + .. + }) => m, + _ => unreachable!(), + }; + for i in vec![1, 3, 5].into_iter() { + pretty_assertions::assert_eq!(modules[i].storage, modules[i+1].storage); + pretty_assertions::assert_eq!(modules[i].calls, modules[i+1].calls); + pretty_assertions::assert_eq!(modules[i].event, modules[i+1].event); + pretty_assertions::assert_eq!(modules[i].constants, modules[i+1].constants); + pretty_assertions::assert_eq!(modules[i].errors, modules[i+1].errors); + } + } + + #[test] + fn types() { + assert_eq!( + pallet_old::Event::::decode(&mut &pallet::Event::::Dummy(10).encode()[..]).unwrap(), + pallet_old::Event::::Dummy(10), + ); + + assert_eq!( + pallet_old::Call::::decode(&mut &pallet::Call::::set_dummy(10).encode()[..]).unwrap(), + pallet_old::Call::::set_dummy(10), + ); + } +} diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs new file mode 100644 index 0000000000000..f9e20324705e7 --- /dev/null +++ b/frame/support/test/tests/pallet_instance.rs @@ -0,0 +1,657 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +use frame_support::{ + weights::{DispatchInfo, DispatchClass, Pays, GetDispatchInfo}, + traits::{GetCallName, GetPalletVersion, OnInitialize, OnFinalize, OnRuntimeUpgrade, OnGenesis}, + dispatch::UnfilteredDispatchable, +}; +use sp_runtime::{traits::Block as _, DispatchError}; +use sp_io::{TestExternalities, hashing::{twox_64, twox_128, blake2_128}}; +use frame_support::storage::unhashed; + +#[frame_support::pallet] +pub mod pallet { + use sp_std::any::TypeId; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + type BalanceOf = >::Balance; + + #[pallet::config] + pub trait Config: frame_system::Config { + #[pallet::constant] + type MyGetParam: Get; + type Balance: Parameter + Default; + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn on_initialize(_: BlockNumberFor) -> Weight { + if TypeId::of::() == TypeId::of::<()>() { + Self::deposit_event(Event::Something(10)); + 10 + } else { + Self::deposit_event(Event::Something(11)); + 11 + } + } + fn on_finalize(_: BlockNumberFor) { + if TypeId::of::() == TypeId::of::<()>() { + Self::deposit_event(Event::Something(20)); + } else { + Self::deposit_event(Event::Something(21)); + } + } + fn on_runtime_upgrade() -> Weight { + if TypeId::of::() == TypeId::of::<()>() { + Self::deposit_event(Event::Something(30)); + 30 + } else { + Self::deposit_event(Event::Something(31)); + 31 + } + } + fn integrity_test() { + } + } + + #[pallet::call] + impl, I: 'static> Pallet { + /// Doc comment put in metadata + #[pallet::weight(Weight::from(*_foo))] + fn foo(origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { + let _ = origin; + Self::deposit_event(Event::Something(3)); + Ok(().into()) + } + + /// Doc comment put in metadata + #[pallet::weight(1)] + #[frame_support::transactional] + fn foo_transactional(origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { + let _ = origin; + Ok(().into()) + } + } + + + #[pallet::error] + pub enum Error { + /// doc comment put into metadata + InsufficientProposersBalance, + } + + #[pallet::event] + #[pallet::metadata(BalanceOf = "Balance", u32 = "Other")] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event, I: 'static = ()> { + /// doc comment put in metadata + Proposed(::AccountId), + /// doc + Spending(BalanceOf), + Something(u32), + } + + #[pallet::storage] + pub type Value = StorageValue<_, u32>; + + #[pallet::storage] + pub type Map = StorageMap<_, Blake2_128Concat, u8, u16>; + + #[pallet::storage] + pub type Map2 = StorageMap<_, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap = + StorageDoubleMap<_, Blake2_128Concat, u8, Twox64Concat, u16, u32>; + + #[pallet::storage] + pub type DoubleMap2 = + StorageDoubleMap<_, Twox64Concat, u16, Blake2_128Concat, u32, u64>; + + #[pallet::genesis_config] + #[derive(Default)] + pub struct GenesisConfig { + _myfield: u32, + } + + #[pallet::genesis_build] + impl, I:'static> GenesisBuild for GenesisConfig { + fn build(&self) {} + } + + #[pallet::origin] + #[derive(EqNoBound, RuntimeDebugNoBound, CloneNoBound, PartialEqNoBound, Encode, Decode)] + pub struct Origin(PhantomData<(T, I)>); + + #[pallet::validate_unsigned] + impl, I: 'static> ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned( + _source: TransactionSource, + _call: &Self::Call + ) -> TransactionValidity { + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + } + } + + #[pallet::inherent] + impl, I: 'static> ProvideInherent for Pallet { + type Call = Call; + type Error = InherentError; + + const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER; + + fn create_inherent(_data: &InherentData) -> Option { + unimplemented!(); + } + } + + #[derive(codec::Encode, sp_runtime::RuntimeDebug)] + #[cfg_attr(feature = "std", derive(codec::Decode))] + pub enum InherentError { + } + + impl sp_inherents::IsFatalError for InherentError { + fn is_fatal_error(&self) -> bool { + unimplemented!(); + } + } + + pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; +} + +frame_support::parameter_types!( + pub const MyGetParam: u32= 10; + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: frame_support::weights::Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one(); +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u32; + type Call = Call; + type Hash = sp_runtime::testing::H256; + type Hashing = sp_runtime::traits::BlakeTwo256; + type AccountId = u64; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = frame_support::weights::constants::RocksDbWeight; + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +impl pallet::Config for Runtime { + type Event = Event; + type MyGetParam= MyGetParam; + type Balance = u64; +} +impl pallet::Config for Runtime { + type Event = Event; + type MyGetParam= MyGetParam; + type Balance = u64; +} + +pub type Header = sp_runtime::generic::Header; +pub type Block = sp_runtime::generic::Block; +pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: frame_system::{Pallet, Call, Event}, + Example: pallet::{Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + Instance1Example: pallet::::{Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + } +); + +#[test] +fn call_expand() { + let call_foo = pallet::Call::::foo(3); + assert_eq!( + call_foo.get_dispatch_info(), + DispatchInfo { + weight: 3, + class: DispatchClass::Normal, + pays_fee: Pays::Yes, + } + ); + assert_eq!(call_foo.get_call_name(), "foo"); + assert_eq!( + pallet::Call::::get_call_names(), + &["foo", "foo_transactional"], + ); + + let call_foo = pallet::Call::::foo(3); + assert_eq!( + call_foo.get_dispatch_info(), + DispatchInfo { + weight: 3, + class: DispatchClass::Normal, + pays_fee: Pays::Yes, + } + ); + assert_eq!(call_foo.get_call_name(), "foo"); + assert_eq!( + pallet::Call::::get_call_names(), + &["foo", "foo_transactional"], + ); +} + +#[test] +fn error_expand() { + assert_eq!( + format!("{:?}", pallet::Error::::InsufficientProposersBalance), + String::from("InsufficientProposersBalance"), + ); + assert_eq!( + <&'static str>::from(pallet::Error::::InsufficientProposersBalance), + "InsufficientProposersBalance", + ); + assert_eq!( + DispatchError::from(pallet::Error::::InsufficientProposersBalance), + DispatchError::Module { + index: 1, + error: 0, + message: Some("InsufficientProposersBalance"), + }, + ); + + assert_eq!( + format!("{:?}", pallet::Error::::InsufficientProposersBalance), + String::from("InsufficientProposersBalance"), + ); + assert_eq!( + <&'static str>::from(pallet::Error::::InsufficientProposersBalance), + "InsufficientProposersBalance", + ); + assert_eq!( + DispatchError::from(pallet::Error::::InsufficientProposersBalance), + DispatchError::Module { + index: 2, + error: 0, + message: Some("InsufficientProposersBalance"), + }, + ); +} + +#[test] +fn instance_expand() { + // assert same type + let _: pallet::__InherentHiddenInstance = (); +} + +#[test] +fn pallet_expand_deposit_event() { + TestExternalities::default().execute_with(|| { + frame_system::Module::::set_block_number(1); + pallet::Call::::foo(3).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Module::::events()[0].event, + Event::pallet(pallet::Event::Something(3)), + ); + }); + + TestExternalities::default().execute_with(|| { + frame_system::Module::::set_block_number(1); + pallet::Call::::foo(3).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Module::::events()[0].event, + Event::pallet_Instance1(pallet::Event::Something(3)), + ); + }); +} + +#[test] +fn storage_expand() { + use frame_support::pallet_prelude::*; + use frame_support::StoragePrefixedMap; + + fn twox_64_concat(d: &[u8]) -> Vec { + let mut v = twox_64(d).to_vec(); + v.extend_from_slice(d); + v + } + + fn blake2_128_concat(d: &[u8]) -> Vec { + let mut v = blake2_128(d).to_vec(); + v.extend_from_slice(d); + v + } + + TestExternalities::default().execute_with(|| { + >::put(1); + let k = [twox_128(b"Example"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); + + >::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(2u16)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(1, 2); + let mut k = [twox_128(b"Example"), twox_128(b"Map2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + k.extend(2u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Example"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + k.extend(2u32.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(3u64)); + assert_eq!(&k[..32], &>::final_prefix()); + }); + + TestExternalities::default().execute_with(|| { + >::put(1); + let k = [twox_128(b"Instance1Example"), twox_128(b"Value")].concat(); + assert_eq!(unhashed::get::(&k), Some(1u32)); + + >::insert(1, 2); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"Map")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(2u16)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(1, 2); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"Map2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(2u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"DoubleMap")].concat(); + k.extend(1u8.using_encoded(blake2_128_concat)); + k.extend(2u16.using_encoded(twox_64_concat)); + assert_eq!(unhashed::get::(&k), Some(3u32)); + assert_eq!(&k[..32], &>::final_prefix()); + + >::insert(&1, &2, &3); + let mut k = [twox_128(b"Instance1Example"), twox_128(b"DoubleMap2")].concat(); + k.extend(1u16.using_encoded(twox_64_concat)); + k.extend(2u32.using_encoded(blake2_128_concat)); + assert_eq!(unhashed::get::(&k), Some(3u64)); + assert_eq!(&k[..32], &>::final_prefix()); + }); +} + +#[test] +fn pallet_hooks_expand() { + TestExternalities::default().execute_with(|| { + frame_system::Module::::set_block_number(1); + + assert_eq!(AllModules::on_initialize(1), 21); + AllModules::on_finalize(1); + + assert_eq!(pallet::Pallet::::storage_version(), None); + assert_eq!(pallet::Pallet::::storage_version(), None); + assert_eq!( + AllModules::on_runtime_upgrade(), + 61 + ::DbWeight::get().writes(2) + ); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + + // The order is indeed reversed due to https://github.com/paritytech/substrate/issues/6280 + assert_eq!( + frame_system::Module::::events()[0].event, + Event::pallet_Instance1(pallet::Event::Something(11)), + ); + assert_eq!( + frame_system::Module::::events()[1].event, + Event::pallet(pallet::Event::Something(10)), + ); + assert_eq!( + frame_system::Module::::events()[2].event, + Event::pallet_Instance1(pallet::Event::Something(21)), + ); + assert_eq!( + frame_system::Module::::events()[3].event, + Event::pallet(pallet::Event::Something(20)), + ); + assert_eq!( + frame_system::Module::::events()[4].event, + Event::pallet_Instance1(pallet::Event::Something(31)), + ); + assert_eq!( + frame_system::Module::::events()[5].event, + Event::pallet(pallet::Event::Something(30)), + ); + }) +} + +#[test] +fn pallet_on_genesis() { + TestExternalities::default().execute_with(|| { + assert_eq!(pallet::Pallet::::storage_version(), None); + pallet::Pallet::::on_genesis(); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + + assert_eq!(pallet::Pallet::::storage_version(), None); + pallet::Pallet::::on_genesis(); + assert_eq!( + pallet::Pallet::::storage_version(), + Some(pallet::Pallet::::current_version()), + ); + }) +} + +#[test] +fn metadata() { + use frame_metadata::*; + use codec::{Decode, Encode}; + + let expected_pallet_metadata = ModuleMetadata { + index: 1, + name: DecodeDifferent::Decoded("Example".to_string()), + storage: Some(DecodeDifferent::Decoded(StorageMetadata { + prefix: DecodeDifferent::Decoded("Example".to_string()), + entries: DecodeDifferent::Decoded(vec![ + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Value".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Decoded("u32".to_string())), + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u8".to_string()), + value: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("Map2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Map { + key: DecodeDifferent::Decoded("u16".to_string()), + value: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + unused: false, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u32".to_string()), + key1: DecodeDifferent::Decoded("u8".to_string()), + key2: DecodeDifferent::Decoded("u16".to_string()), + hasher: StorageHasher::Blake2_128Concat, + key2_hasher: StorageHasher::Twox64Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + StorageEntryMetadata { + name: DecodeDifferent::Decoded("DoubleMap2".to_string()), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::DoubleMap { + value: DecodeDifferent::Decoded("u64".to_string()), + key1: DecodeDifferent::Decoded("u16".to_string()), + key2: DecodeDifferent::Decoded("u32".to_string()), + hasher: StorageHasher::Twox64Concat, + key2_hasher: StorageHasher::Blake2_128Concat, + }, + default: DecodeDifferent::Decoded(vec![0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ]), + })), + calls: Some(DecodeDifferent::Decoded(vec![ + FunctionMetadata { + name: DecodeDifferent::Decoded("foo".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + FunctionMetadata { + name: DecodeDifferent::Decoded("foo_transactional".to_string()), + arguments: DecodeDifferent::Decoded(vec![ + FunctionArgumentMetadata { + name: DecodeDifferent::Decoded("_foo".to_string()), + ty: DecodeDifferent::Decoded("Compact".to_string()), + } + ]), + documentation: DecodeDifferent::Decoded(vec![ + " Doc comment put in metadata".to_string(), + ]), + }, + ])), + event: Some(DecodeDifferent::Decoded(vec![ + EventMetadata { + name: DecodeDifferent::Decoded("Proposed".to_string()), + arguments: DecodeDifferent::Decoded(vec!["AccountId".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put in metadata".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Spending".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Balance".to_string()]), + documentation: DecodeDifferent::Decoded(vec![ + " doc".to_string() + ]), + }, + EventMetadata { + name: DecodeDifferent::Decoded("Something".to_string()), + arguments: DecodeDifferent::Decoded(vec!["Other".to_string()]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ])), + constants: DecodeDifferent::Decoded(vec![ + ModuleConstantMetadata { + name: DecodeDifferent::Decoded("MyGetParam".to_string()), + ty: DecodeDifferent::Decoded("u32".to_string()), + value: DecodeDifferent::Decoded(vec![10, 0, 0, 0]), + documentation: DecodeDifferent::Decoded(vec![]), + }, + ]), + errors: DecodeDifferent::Decoded(vec![ + ErrorMetadata { + name: DecodeDifferent::Decoded("InsufficientProposersBalance".to_string()), + documentation: DecodeDifferent::Decoded(vec![ + " doc comment put into metadata".to_string(), + ]), + }, + ]), + }; + + let mut expected_pallet_instance1_metadata = expected_pallet_metadata.clone(); + expected_pallet_instance1_metadata.name = DecodeDifferent::Decoded("Instance1Example".to_string()); + expected_pallet_instance1_metadata.index = 2; + match expected_pallet_instance1_metadata.storage { + Some(DecodeDifferent::Decoded(ref mut storage_meta)) => { + storage_meta.prefix = DecodeDifferent::Decoded("Instance1Example".to_string()); + }, + _ => unreachable!(), + } + + + let metadata = match Runtime::metadata().1 { + RuntimeMetadata::V12(metadata) => metadata, + _ => panic!("metadata has been bump, test needs to be updated"), + }; + + let modules_metadata = match metadata.modules { + DecodeDifferent::Encode(modules_metadata) => modules_metadata, + _ => unreachable!(), + }; + + let pallet_metadata = ModuleMetadata::decode(&mut &modules_metadata[1].encode()[..]).unwrap(); + let pallet_instance1_metadata = + ModuleMetadata::decode(&mut &modules_metadata[2].encode()[..]).unwrap(); + + pretty_assertions::assert_eq!(pallet_metadata, expected_pallet_metadata); + pretty_assertions::assert_eq!(pallet_instance1_metadata, expected_pallet_instance1_metadata); +} diff --git a/frame/support/test/tests/pallet_ui.rs b/frame/support/test/tests/pallet_ui.rs new file mode 100644 index 0000000000000..80a28ee826940 --- /dev/null +++ b/frame/support/test/tests/pallet_ui.rs @@ -0,0 +1,26 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 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. + +#[rustversion::attr(not(stable), ignore)] +#[test] +fn pallet_ui() { + // As trybuild is using `cargo check`, we don't need the real WASM binaries. + std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/pallet_ui/*.rs"); +} diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs new file mode 100644 index 0000000000000..69d35344d5761 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.rs @@ -0,0 +1,27 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar: codec::Codec; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + Ok(().into()) + } + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr new file mode 100644 index 0000000000000..e9e35d50ad4cc --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr @@ -0,0 +1,28 @@ +error[E0369]: binary operation `==` cannot be applied to type `&::Bar` + --> $DIR/call_argument_invalid_bound.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ + | +help: consider further restricting this bound + | +1 | #[frame_support::pallet] + std::cmp::PartialEq + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `::Bar: std::clone::Clone` is not satisfied + --> $DIR/call_argument_invalid_bound.rs:20:37 + | +20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + | ^ the trait `std::clone::Clone` is not implemented for `::Bar` + | + = note: required by `std::clone::Clone::clone` + +error[E0277]: `::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/call_argument_invalid_bound.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/call_argument_invalid_bound_2.rs b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.rs new file mode 100644 index 0000000000000..581c72a4240a0 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.rs @@ -0,0 +1,27 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { + Ok(().into()) + } + } +} + +fn main() { +} 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 new file mode 100644 index 0000000000000..1fc092423629b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_2.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `pallet::Call: pallet::_::_parity_scale_codec::Decode` is not satisfied + --> $DIR/call_argument_invalid_bound_2.rs:17:12 + | +17 | #[pallet::call] + | ^^^^ the trait `pallet::_::_parity_scale_codec::Decode` is not implemented for `pallet::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` diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs new file mode 100644 index 0000000000000..97f362551037d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.rs @@ -0,0 +1,29 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + use codec::{Encode, Decode}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[derive(Encode, Decode)] + struct Bar; + + #[pallet::call] + impl Pallet { + #[pallet::weight(0)] + fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + Ok(().into()) + } + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr new file mode 100644 index 0000000000000..cf327754abfb9 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr @@ -0,0 +1,26 @@ +error[E0369]: binary operation `==` cannot be applied to type `&pallet::Bar` + --> $DIR/call_argument_invalid_bound_3.rs:22:37 + | +22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + | ^^^ + | + = note: an implementation of `std::cmp::PartialEq` might be missing for `&pallet::Bar` + +error[E0277]: the trait bound `pallet::Bar: std::clone::Clone` is not satisfied + --> $DIR/call_argument_invalid_bound_3.rs:22:37 + | +22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + | ^^^ the trait `std::clone::Clone` is not implemented for `pallet::Bar` + | + = note: required by `std::clone::Clone::clone` + +error[E0277]: `pallet::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/call_argument_invalid_bound_3.rs:22:37 + | +22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { + | ^^^ `pallet::Bar` cannot be formatted using `{:?}` + | + = help: the trait `std::fmt::Debug` is not implemented for `pallet::Bar` + = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&pallet::Bar` + = note: required for the cast to the object type `dyn std::fmt::Debug` diff --git a/frame/support/test/tests/pallet_ui/call_invalid_const.rs b/frame/support/test/tests/pallet_ui/call_invalid_const.rs new file mode 100644 index 0000000000000..1a28bc32e65c6 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_const.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + const Foo: u8 = 3u8; + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_invalid_const.stderr b/frame/support/test/tests/pallet_ui/call_invalid_const.stderr new file mode 100644 index 0000000000000..0acb3e864a512 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_const.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, only method accepted + --> $DIR/call_invalid_const.rs:17:3 + | +17 | const Foo: u8 = 3u8; + | ^^^^^ diff --git a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs new file mode 100644 index 0000000000000..edf953b5976c0 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo(origin: u8) {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr new file mode 100644 index 0000000000000..9cf933698ff32 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr @@ -0,0 +1,11 @@ +error: Invalid ty: expect `OriginFor` + --> $DIR/call_invalid_origin_type.rs:17:18 + | +17 | fn foo(origin: u8) {} + | ^^ + +error: expected `OriginFor` + --> $DIR/call_invalid_origin_type.rs:17:18 + | +17 | fn foo(origin: u8) {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/call_missing_weight.rs b/frame/support/test/tests/pallet_ui/call_missing_weight.rs new file mode 100644 index 0000000000000..2ce607c53ac3a --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_missing_weight.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, DispatchResultWithPostInfo}; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo(origin: OriginFor) -> DispatchResultWithPostInfo {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_missing_weight.stderr b/frame/support/test/tests/pallet_ui/call_missing_weight.stderr new file mode 100644 index 0000000000000..f499e8a65da27 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_missing_weight.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, require weight attribute i.e. `#[pallet::weight = $expr]` + --> $DIR/call_missing_weight.rs:17:3 + | +17 | fn foo(origin: OriginFor) -> DispatchResultWithPostInfo {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/call_no_origin.rs b/frame/support/test/tests/pallet_ui/call_no_origin.rs new file mode 100644 index 0000000000000..83d10b6b08b4f --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_origin.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo() {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_no_origin.stderr b/frame/support/test/tests/pallet_ui/call_no_origin.stderr new file mode 100644 index 0000000000000..42afd02c42639 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_origin.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, must have at least origin arg + --> $DIR/call_no_origin.rs:17:3 + | +17 | fn foo() {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/call_no_return.rs b/frame/support/test/tests/pallet_ui/call_no_return.rs new file mode 100644 index 0000000000000..a18c30f6d6d90 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_return.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::{BlockNumberFor, OriginFor}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet { + fn foo(origin: OriginFor) {} + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/call_no_return.stderr b/frame/support/test/tests/pallet_ui/call_no_return.stderr new file mode 100644 index 0000000000000..b16d401355c12 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/call_no_return.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::call, require return type DispatchResultWithPostInfo + --> $DIR/call_no_return.rs:17:3 + | +17 | fn foo(origin: OriginFor) {} + | ^^ diff --git a/frame/support/test/tests/pallet_ui/duplicate_call_attr.rs b/frame/support/test/tests/pallet_ui/duplicate_call_attr.rs new file mode 100644 index 0000000000000..b8a32a0bd9f69 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_call_attr.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + use frame_support::pallet_prelude::StorageValue; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + #[pallet::generate_store(trait Store)] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue<_, u8>; + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr b/frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr new file mode 100644 index 0000000000000..c2956717bb2bb --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_call_attr.stderr @@ -0,0 +1,5 @@ +error: Invalid duplicated attribute + --> $DIR/duplicate_call_attr.rs:23:12 + | +23 | #[pallet::call] + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs b/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs new file mode 100644 index 0000000000000..d675ddefe985b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_store_attr.rs @@ -0,0 +1,26 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + use frame_support::pallet_prelude::StorageValue; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + #[pallet::generate_store(trait Store)] + #[pallet::generate_store(trait Store)] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue<_, u8>; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr b/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr new file mode 100644 index 0000000000000..eed6ad4494edc --- /dev/null +++ b/frame/support/test/tests/pallet_ui/duplicate_store_attr.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::pallet, multiple argument pallet::generate_store found + --> $DIR/duplicate_store_attr.rs:12:33 + | +12 | #[pallet::generate_store(trait Store)] + | ^^^^^ diff --git a/frame/support/test/tests/pallet_ui/error_no_fieldless.rs b/frame/support/test/tests/pallet_ui/error_no_fieldless.rs new file mode 100644 index 0000000000000..c9d444d6f90dd --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_no_fieldless.rs @@ -0,0 +1,25 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::error] + pub enum Error { + U8(u8), + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/error_no_fieldless.stderr b/frame/support/test/tests/pallet_ui/error_no_fieldless.stderr new file mode 100644 index 0000000000000..1d69fbeff9aac --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_no_fieldless.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::error, unexpected fields, must be `Unit` + --> $DIR/error_no_fieldless.rs:20:5 + | +20 | U8(u8), + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item.rs b/frame/support/test/tests/pallet_ui/error_wrong_item.rs new file mode 100644 index 0000000000000..50e66dc8c0dce --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::error] + pub struct Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item.stderr b/frame/support/test/tests/pallet_ui/error_wrong_item.stderr new file mode 100644 index 0000000000000..e028616acc95f --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::error, expect item enum + --> $DIR/error_wrong_item.rs:19:2 + | +19 | pub struct Foo; + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item_name.rs b/frame/support/test/tests/pallet_ui/error_wrong_item_name.rs new file mode 100644 index 0000000000000..14107fafb06ea --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item_name.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::error] + pub enum Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr b/frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr new file mode 100644 index 0000000000000..d7e54ad8a7516 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/error_wrong_item_name.stderr @@ -0,0 +1,5 @@ +error: expected `Error` + --> $DIR/error_wrong_item_name.rs:19:11 + | +19 | pub enum Foo {} + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/event_field_not_member.rs b/frame/support/test/tests/pallet_ui/event_field_not_member.rs new file mode 100644 index 0000000000000..0ecde4c130878 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_field_not_member.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, IsType}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + type Event: IsType<::Event> + From>; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_field_not_member.stderr b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr new file mode 100644 index 0000000000000..7275476936235 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr @@ -0,0 +1,28 @@ +error[E0277]: `::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/event_field_not_member.rs:23:7 + | +23 | B { b: T::Bar }, + | ^ `::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` + +error[E0369]: binary operation `==` cannot be applied to type `&::Bar` + --> $DIR/event_field_not_member.rs:23:7 + | +23 | B { b: T::Bar }, + | ^ + | +help: consider further restricting this bound + | +22 | pub enum Event { + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `::Bar: std::clone::Clone` is not satisfied + --> $DIR/event_field_not_member.rs:23:7 + | +23 | B { b: T::Bar }, + | ^ the trait `std::clone::Clone` is not implemented for `::Bar` + | + = note: required by `std::clone::Clone::clone` diff --git a/frame/support/test/tests/pallet_ui/event_not_in_trait.rs b/frame/support/test/tests/pallet_ui/event_not_in_trait.rs new file mode 100644 index 0000000000000..94151ba4c3d9d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_not_in_trait.rs @@ -0,0 +1,27 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_not_in_trait.stderr b/frame/support/test/tests/pallet_ui/event_not_in_trait.stderr new file mode 100644 index 0000000000000..dd96c700ce7e5 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_not_in_trait.stderr @@ -0,0 +1,7 @@ +error: Invalid usage of Event, `Config` contains no associated type `Event`, but enum `Event` is declared (in use of `#[pallet::event]`). An Event associated type must be declare on trait `Config`. + --> $DIR/event_not_in_trait.rs:1:1 + | +1 | #[frame_support::pallet] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs new file mode 100644 index 0000000000000..fa3bf04d3530d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + type Event; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr new file mode 100644 index 0000000000000..1f58a37576d0d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound.stderr @@ -0,0 +1,5 @@ +error: Invalid `type Event`, associated type `Event` is reserved and must bound: `IsType<::Event>` + --> $DIR/event_type_invalid_bound.rs:9:3 + | +9 | type Event; + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs new file mode 100644 index 0000000000000..564a539b89f57 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.rs @@ -0,0 +1,28 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, IsType}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Bar; + type Event: IsType<::Event>; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Event { + B { b: T::Bar }, + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr new file mode 100644 index 0000000000000..8b8946f3b25eb --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_type_invalid_bound_2.stderr @@ -0,0 +1,5 @@ +error: Invalid `type Event`, associated type `Event` is reserved and must bound: `From` or `From>` or `From>` + --> $DIR/event_type_invalid_bound_2.rs:9:3 + | +9 | type Event: IsType<::Event>; + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item.rs b/frame/support/test/tests/pallet_ui/event_wrong_item.rs new file mode 100644 index 0000000000000..d6690557c39d8 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub struct Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item.stderr b/frame/support/test/tests/pallet_ui/event_wrong_item.stderr new file mode 100644 index 0000000000000..d3ddb6cb0fd4d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::event, expect item enum + --> $DIR/event_wrong_item.rs:19:2 + | +19 | pub struct Foo; + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item_name.rs b/frame/support/test/tests/pallet_ui/event_wrong_item_name.rs new file mode 100644 index 0000000000000..d828965c5173c --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item_name.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::event] + pub enum Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr b/frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr new file mode 100644 index 0000000000000..14e8615c56199 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/event_wrong_item_name.stderr @@ -0,0 +1,5 @@ +error: expected `Event` + --> $DIR/event_wrong_item_name.rs:19:11 + | +19 | pub enum Foo {} + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs new file mode 100644 index 0000000000000..da5e8d0c4da52 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.rs @@ -0,0 +1,26 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, GenesisBuild}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_config] + pub struct GenesisConfig; + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr new file mode 100644 index 0000000000000..b699288db0d7f --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr @@ -0,0 +1,10 @@ +error[E0277]: the trait bound `pallet::GenesisConfig: std::default::Default` is not satisfied + --> $DIR/genesis_default_not_satisfied.rs:22:18 + | +22 | impl GenesisBuild for GenesisConfig {} + | ^^^^^^^^^^^^^^^ the trait `std::default::Default` is not implemented for `pallet::GenesisConfig` + | + ::: $WORKSPACE/frame/support/src/traits.rs + | + | pub trait GenesisBuild: Default + MaybeSerializeDeserialize { + | ------- required by this bound in `frame_support::traits::GenesisBuild` diff --git a/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs new file mode 100644 index 0000000000000..9ae851005acb3 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr new file mode 100644 index 0000000000000..9afc1037a48ae --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_inconsistent_build_config.stderr @@ -0,0 +1,5 @@ +error: `#[pallet::genesis_config]` and `#[pallet::genesis_build]` attributes must be either both used or both not used, instead genesis_config is unused and genesis_build is used + --> $DIR/genesis_inconsistent_build_config.rs:2:1 + | +2 | mod pallet { + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs new file mode 100644 index 0000000000000..f1eae16f49600 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr new file mode 100644 index 0000000000000..619b5ffe9db98 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr @@ -0,0 +1,13 @@ +error: Invalid genesis builder: expect `GenesisBuild` or `GenesisBuild` + --> $DIR/genesis_invalid_generic.rs:19:7 + | +19 | impl GenesisBuild for GenesisConfig {} + | ^^^^^^^^^^^^ + +error: expected `<` + --> $DIR/genesis_invalid_generic.rs:1:1 + | +1 | #[frame_support::pallet] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/frame/support/test/tests/pallet_ui/genesis_wrong_name.rs b/frame/support/test/tests/pallet_ui/genesis_wrong_name.rs new file mode 100644 index 0000000000000..5e8b297ba4ccf --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_wrong_name.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::genesis_build] + impl Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr b/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr new file mode 100644 index 0000000000000..82c030ac64417 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::genesis_build, expect impl<..> GenesisBuild<..> for GenesisConfig<..> + --> $DIR/genesis_wrong_name.rs:19:2 + | +19 | impl Foo {} + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/hooks_invalid_item.rs b/frame/support/test/tests/pallet_ui/hooks_invalid_item.rs new file mode 100644 index 0000000000000..fae12f133b6a0 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/hooks_invalid_item.rs @@ -0,0 +1,19 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr b/frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr new file mode 100644 index 0000000000000..0379448f694fc --- /dev/null +++ b/frame/support/test/tests/pallet_ui/hooks_invalid_item.stderr @@ -0,0 +1,5 @@ +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/hooks_invalid_item.rs:12:18 + | +12 | impl Hooks for Pallet {} + | ^^^^^ expected 1 type argument diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs new file mode 100644 index 0000000000000..00b57a01235c3 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.rs @@ -0,0 +1,20 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr new file mode 100644 index 0000000000000..352c21013cab0 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_1.stderr @@ -0,0 +1,29 @@ +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:16:7 + | +16 | impl Pallet {} + | ^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:16:18 + | +16 | impl Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:10:20 + | +10 | pub struct Pallet(core::marker::PhantomData); + | ^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:13:47 + | +13 | impl Hooks> for Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined with instance but generic use none + --> $DIR/inconsistent_instance_1.rs:13:7 + | +13 | impl Hooks> for Pallet {} + | ^ diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs new file mode 100644 index 0000000000000..e7b51cb5ebef5 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.rs @@ -0,0 +1,20 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet {} + + #[pallet::call] + impl, I: 'static> Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr new file mode 100644 index 0000000000000..9f5d3c740cbd1 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inconsistent_instance_2.stderr @@ -0,0 +1,29 @@ +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:16:7 + | +16 | impl, I: 'static> Pallet {} + | ^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:16:33 + | +16 | impl, I: 'static> Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:10:20 + | +10 | pub struct Pallet(core::marker::PhantomData<(T, I)>); + | ^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:13:62 + | +13 | impl, I: 'static> Hooks> for Pallet {} + | ^^^^^^ + +error: Invalid generic declaration, trait is defined without instance but generic use some + --> $DIR/inconsistent_instance_2.rs:13:7 + | +13 | impl, I: 'static> Hooks> for Pallet {} + | ^ diff --git a/frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs new file mode 100644 index 0000000000000..9704a7e1a442e --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, ProvideInherent}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::inherent] + impl ProvideInherent for Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr new file mode 100644 index 0000000000000..f44b6da415344 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr @@ -0,0 +1,10 @@ +error[E0046]: not all trait items implemented, missing: `Call`, `Error`, `INHERENT_IDENTIFIER`, `create_inherent` + --> $DIR/inherent_check_inner_span.rs:19:2 + | +19 | impl ProvideInherent for Pallet {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Call`, `Error`, `INHERENT_IDENTIFIER`, `create_inherent` in implementation + | + = help: implement the missing item: `type Call = Type;` + = help: implement the missing item: `type Error = Type;` + = help: implement the missing item: `const INHERENT_IDENTIFIER: [u8; 8] = value;` + = help: implement the missing item: `fn create_inherent(_: &frame_support::inherent::InherentData) -> std::option::Option<::Call> { todo!() }` diff --git a/frame/support/test/tests/pallet_ui/inherent_invalid_item.rs b/frame/support/test/tests/pallet_ui/inherent_invalid_item.rs new file mode 100644 index 0000000000000..97eda44721307 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_invalid_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::inherent] + impl Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr b/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr new file mode 100644 index 0000000000000..4dc1193b74fe7 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::inherent, expect impl<..> ProvideInherent for Pallet<..> + --> $DIR/inherent_invalid_item.rs:19:2 + | +19 | impl Foo {} + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/mod_not_inlined.rs b/frame/support/test/tests/pallet_ui/mod_not_inlined.rs new file mode 100644 index 0000000000000..c74c7f5ef2a2b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/mod_not_inlined.rs @@ -0,0 +1,5 @@ +#[frame_support::pallet] +mod foo; + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr b/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr new file mode 100644 index 0000000000000..1acff2e678ece --- /dev/null +++ b/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr @@ -0,0 +1,13 @@ +error[E0658]: non-inline modules in proc macro input are unstable + --> $DIR/mod_not_inlined.rs:2:1 + | +2 | mod foo; + | ^^^^^^^^ + | + = note: see issue #54727 for more information + +error: Invalid pallet definition, expect mod to be inlined. + --> $DIR/mod_not_inlined.rs:2:1 + | +2 | mod foo; + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/storage_incomplete_item.rs b/frame/support/test/tests/pallet_ui/storage_incomplete_item.rs new file mode 100644 index 0000000000000..e451df8c78a02 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_incomplete_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr new file mode 100644 index 0000000000000..571caa0bf40ed --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr @@ -0,0 +1,13 @@ +error: free type alias without body + --> $DIR/storage_incomplete_item.rs:19:2 + | +19 | type Foo; + | ^^^^^^^^- + | | + | help: provide a definition for the type: `= ;` + +error[E0433]: failed to resolve: use of undeclared type or module `pallet` + --> $DIR/storage_incomplete_item.rs:18:4 + | +18 | #[pallet::storage] + | ^^^^^^ use of undeclared type or module `pallet` diff --git a/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs new file mode 100644 index 0000000000000..c8df93c9b323d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr new file mode 100644 index 0000000000000..d332e6c2d3d1b --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_invalid_first_generic.stderr @@ -0,0 +1,11 @@ +error: Invalid use of `#[pallet::storage]`, the type first generic argument must be `_`, the final argument is automatically set by macro. + --> $DIR/storage_invalid_first_generic.rs:19:29 + | +19 | type Foo = StorageValue; + | ^^ + +error: expected `_` + --> $DIR/storage_invalid_first_generic.rs:19:29 + | +19 | type Foo = StorageValue; + | ^^ diff --git a/frame/support/test/tests/pallet_ui/storage_not_storage_type.rs b/frame/support/test/tests/pallet_ui/storage_not_storage_type.rs new file mode 100644 index 0000000000000..03eee6fc8ec7d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_not_storage_type.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = u8; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr b/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr new file mode 100644 index 0000000000000..9f190ae1dbfaa --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::storage, expect ident: `StorageValue` or `StorageMap` or `StorageDoubleMap` in order to expand metadata, found `u8` + --> $DIR/storage_not_storage_type.rs:19:16 + | +19 | type Foo = u8; + | ^^ diff --git a/frame/support/test/tests/pallet_ui/storage_value_no_generic.rs b/frame/support/test/tests/pallet_ui/storage_value_no_generic.rs new file mode 100644 index 0000000000000..e62bdafaa2643 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_value_no_generic.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr b/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr new file mode 100644 index 0000000000000..63262690d915e --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr @@ -0,0 +1,5 @@ +error: pallet::storage unexpected number of generic argument, expect at least 2 args, found none + --> $DIR/storage_value_no_generic.rs:19:16 + | +19 | type Foo = StorageValue; + | ^^^^^^^^^^^^ diff --git a/frame/support/test/tests/pallet_ui/storage_wrong_item.rs b/frame/support/test/tests/pallet_ui/storage_wrong_item.rs new file mode 100644 index 0000000000000..56c4b86f2b35a --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_wrong_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + impl Foo {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr b/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr new file mode 100644 index 0000000000000..3219665249405 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::storage, expect item type + --> $DIR/storage_wrong_item.rs:19:2 + | +19 | impl Foo {} + | ^^^^ diff --git a/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs b/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs new file mode 100644 index 0000000000000..3ebd1cb9fa608 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/store_trait_leak_private.rs @@ -0,0 +1,25 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + use frame_support::pallet_prelude::StorageValue; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + #[pallet::generate_store(pub trait Store)] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::storage] + type Foo = StorageValue<_, u8>; +} + +fn main() { +} 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 new file mode 100644 index 0000000000000..d3ae7eb88ce3d --- /dev/null +++ b/frame/support/test/tests/pallet_ui/store_trait_leak_private.stderr @@ -0,0 +1,8 @@ +error[E0446]: private type `pallet::_GeneratedPrefixForStorageFoo` in public interface + --> $DIR/store_trait_leak_private.rs:11:37 + | +11 | #[pallet::generate_store(pub trait Store)] + | ^^^^^ can't leak private type +... +21 | type Foo = StorageValue<_, u8>; + | - `pallet::_GeneratedPrefixForStorageFoo` declared as private diff --git a/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs new file mode 100644 index 0000000000000..ce599d5a31e71 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + #[pallet::constant] + type U; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr new file mode 100644 index 0000000000000..16c3531140eaa --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_constant_invalid_bound.stderr @@ -0,0 +1,11 @@ +error: Invalid usage of `#[pallet::constant]`, syntax must be `type $SomeIdent: Get<$SomeType>;` + --> $DIR/trait_constant_invalid_bound.rs:9:3 + | +9 | type U; + | ^^^^ + +error: expected `:` + --> $DIR/trait_constant_invalid_bound.rs:9:9 + | +9 | type U; + | ^ diff --git a/frame/support/test/tests/pallet_ui/trait_invalid_item.rs b/frame/support/test/tests/pallet_ui/trait_invalid_item.rs new file mode 100644 index 0000000000000..8537659dcd037 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_invalid_item.rs @@ -0,0 +1,23 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config { + #[pallet::constant] + const U: u8 = 3; + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr b/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr new file mode 100644 index 0000000000000..3a2f2a4a19cda --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::constant in pallet::config, expect type trait item + --> $DIR/trait_invalid_item.rs:9:3 + | +9 | const U: u8 = 3; + | ^^^^^ diff --git a/frame/support/test/tests/pallet_ui/trait_no_supertrait.rs b/frame/support/test/tests/pallet_ui/trait_no_supertrait.rs new file mode 100644 index 0000000000000..0fc987f7bbdd7 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_no_supertrait.rs @@ -0,0 +1,21 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::Hooks; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config { + } + + #[pallet::pallet] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr b/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr new file mode 100644 index 0000000000000..ddf35a802e516 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::trait, expect explicit `frame_system::Config` as supertrait, found none. (try `pub trait Config: frame_system::Config { ...` or `pub trait Config: frame_system::Config { ...`). To disable this check, use `#[pallet::disable_frame_system_supertrait_check]` + --> $DIR/trait_no_supertrait.rs:7:2 + | +7 | pub trait Config { + | ^^^ diff --git a/frame/support/test/tests/pallet_ui/type_value_error_in_block.rs b/frame/support/test/tests/pallet_ui/type_value_error_in_block.rs new file mode 100644 index 0000000000000..1a1c451ac39fc --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_error_in_block.rs @@ -0,0 +1,25 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::type_value] fn Foo() -> u32 { + // Just wrong code to see span + u32::new() + } +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr b/frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr new file mode 100644 index 0000000000000..f46b89a067b06 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_error_in_block.stderr @@ -0,0 +1,5 @@ +error[E0599]: no function or associated item named `new` found for type `u32` in the current scope + --> $DIR/type_value_error_in_block.rs:20:8 + | +20 | u32::new() + | ^^^ function or associated item not found in `u32` diff --git a/frame/support/test/tests/pallet_ui/type_value_invalid_item.rs b/frame/support/test/tests/pallet_ui/type_value_invalid_item.rs new file mode 100644 index 0000000000000..476a4a8e1e783 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_invalid_item.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::type_value] struct Foo; +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr b/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr new file mode 100644 index 0000000000000..8f2eef7af1ddf --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::type_value, expect item fn + --> $DIR/type_value_invalid_item.rs:18:24 + | +18 | #[pallet::type_value] struct Foo; + | ^^^^^^ diff --git a/frame/support/test/tests/pallet_ui/type_value_no_return.rs b/frame/support/test/tests/pallet_ui/type_value_no_return.rs new file mode 100644 index 0000000000000..eb13436cac7cc --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_no_return.rs @@ -0,0 +1,22 @@ +#[frame_support::pallet] +mod pallet { + use frame_support::pallet_prelude::{Hooks, PhantomData}; + use frame_system::pallet_prelude::BlockNumberFor; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet {} + + #[pallet::call] + impl Pallet {} + + #[pallet::type_value] fn Foo() {} +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/type_value_no_return.stderr b/frame/support/test/tests/pallet_ui/type_value_no_return.stderr new file mode 100644 index 0000000000000..2410e6a7b7d85 --- /dev/null +++ b/frame/support/test/tests/pallet_ui/type_value_no_return.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet::type_value, expect return type + --> $DIR/type_value_no_return.rs:18:24 + | +18 | #[pallet::type_value] fn Foo() {} + | ^^ diff --git a/frame/support/test/tests/pallet_version.rs b/frame/support/test/tests/pallet_version.rs index 7adeec30cd695..f8423c55f1a02 100644 --- a/frame/support/test/tests/pallet_version.rs +++ b/frame/support/test/tests/pallet_version.rs @@ -27,22 +27,17 @@ use frame_support::{ }; use sp_core::{H256, sr25519}; -mod system; - /// A version that we will check for in the tests const SOME_TEST_VERSION: PalletVersion = PalletVersion { major: 3000, minor: 30, patch: 13 }; /// Checks that `on_runtime_upgrade` sets the latest pallet version when being called without /// being provided by the user. mod module1 { - use super::*; - - pub trait Trait: system::Trait {} + pub trait Trait: frame_system::Trait {} frame_support::decl_module! { pub struct Module for enum Call where - origin: ::Origin, - system = system, + origin: ::Origin, {} } } @@ -52,12 +47,11 @@ mod module1 { mod module2 { use super::*; - pub trait Trait: system::Trait {} + pub trait Trait: frame_system::Trait {} frame_support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where - origin: ::Origin, - system = system + origin: ::Origin, { fn on_runtime_upgrade() -> Weight { assert_eq!(crate_to_pallet_version!(), Self::current_version()); @@ -82,26 +76,102 @@ mod module2 { } } +#[frame_support::pallet] +mod pallet3 { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + } + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + return 3; + } + } + + #[pallet::call] + impl Pallet { + } +} + +#[frame_support::pallet] +mod pallet4 { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + } + + #[pallet::pallet] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + return 3; + } + } + + #[pallet::call] + impl, I: 'static> Pallet { + } +} + impl module1::Trait for Runtime {} impl module2::Trait for Runtime {} impl module2::Trait for Runtime {} impl module2::Trait for Runtime {} +impl pallet3::Config for Runtime {} +impl pallet4::Config for Runtime {} +impl pallet4::Config for Runtime {} +impl pallet4::Config for Runtime {} + pub type Signature = sr25519::Signature; pub type AccountId = ::Signer; pub type BlockNumber = u64; pub type Index = u64; -impl system::Config for Runtime { - type BaseCallFilter= (); - type Hash = H256; +frame_support::parameter_types!( + pub const BlockHashCount: u32 = 250; + pub const MaximumBlockWeight: frame_support::weights::Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: sp_runtime::Perbill = sp_runtime::Perbill::one(); +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = (); type Origin = Origin; + type Index = u64; type BlockNumber = BlockNumber; + type Call = Call; + type Hash = H256; + type Hashing = sp_runtime::traits::BlakeTwo256; type AccountId = AccountId; + type Lookup = sp_runtime::traits::IdentityLookup; + type Header = Header; type Event = Event; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = frame_support::weights::constants::RocksDbWeight; + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = (); type PalletInfo = PalletInfo; - type Call = Call; - type DbWeight = (); + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); } frame_support::construct_runtime!( @@ -110,11 +180,15 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: frame_system::{Module, Call, Event}, Module1: module1::{Module, Call}, Module2: module2::{Module, Call}, Module2_1: module2::::{Module, Call}, Module2_2: module2::::{Module, Call}, + Pallet3: pallet3::{Pallet, Call}, + Pallet4: pallet4::{Pallet, Call}, + Pallet4_1: pallet4::::{Pallet, Call}, + Pallet4_2: pallet4::::{Pallet, Call}, } ); @@ -156,6 +230,10 @@ fn on_runtime_upgrade_sets_the_pallet_versions_in_storage() { check_pallet_version("Module2"); check_pallet_version("Module2_1"); check_pallet_version("Module2_2"); + check_pallet_version("Pallet3"); + check_pallet_version("Pallet4"); + check_pallet_version("Pallet4_1"); + check_pallet_version("Pallet4_2"); }); } @@ -171,6 +249,10 @@ fn on_runtime_upgrade_overwrites_old_version() { check_pallet_version("Module2"); check_pallet_version("Module2_1"); check_pallet_version("Module2_2"); + check_pallet_version("Pallet3"); + check_pallet_version("Pallet4"); + check_pallet_version("Pallet4_1"); + check_pallet_version("Pallet4_2"); }); } @@ -183,6 +265,10 @@ fn genesis_init_puts_pallet_version_into_storage() { check_pallet_version("Module2"); check_pallet_version("Module2_1"); check_pallet_version("Module2_2"); + check_pallet_version("Pallet3"); + check_pallet_version("Pallet4"); + check_pallet_version("Pallet4_1"); + check_pallet_version("Pallet4_2"); let system_version = System::storage_version().expect("System version should be set"); assert_eq!(System::current_version(), system_version); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index da374b9cd473e..9351e8d340606 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -517,6 +517,11 @@ decl_error! { } } +/// 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; @@ -1371,3 +1376,11 @@ impl Lookup for ChainContext { ::lookup(s) } } + +pub mod pallet_prelude { + pub use crate::ensure_signed; + pub use crate::ensure_none; + pub use crate::ensure_root; + pub type OriginFor = ::Origin; + pub type BlockNumberFor = ::BlockNumber; +} From 1e1e8a3b1290ad01559c3fb2ce8e86afbf54a447 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 29 Oct 2020 17:44:17 +0100 Subject: [PATCH 04/36] allow to print some upgrade helper from decl_storage --- .../src/storage/genesis_config/mod.rs | 4 +- frame/support/procedural/src/storage/mod.rs | 3 + .../src/storage/print_pallet_upgrade.rs | 387 ++++++++++++++++++ frame/support/src/lib.rs | 33 +- 4 files changed, 413 insertions(+), 14 deletions(-) create mode 100644 frame/support/procedural/src/storage/print_pallet_upgrade.rs diff --git a/frame/support/procedural/src/storage/genesis_config/mod.rs b/frame/support/procedural/src/storage/genesis_config/mod.rs index 27fbdd2cd38b5..ebc4c7a7f79db 100644 --- a/frame/support/procedural/src/storage/genesis_config/mod.rs +++ b/frame/support/procedural/src/storage/genesis_config/mod.rs @@ -21,8 +21,8 @@ use proc_macro2::{TokenStream, Span}; use quote::quote; use super::DeclStorageDefExt; -use genesis_config_def::GenesisConfigDef; -use builder_def::BuilderDef; +pub use genesis_config_def::GenesisConfigDef; +pub use builder_def::BuilderDef; mod genesis_config_def; mod builder_def; diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index cfb3369fa9a8a..6193cbbd46e1f 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -24,6 +24,7 @@ mod getters; mod metadata; mod instance_trait; mod genesis_config; +mod print_pallet_upgrade; pub(crate) use instance_trait::INHERENT_INSTANCE_NAME; @@ -399,6 +400,8 @@ pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStr let def = syn::parse_macro_input!(input as DeclStorageDef); let def_ext = DeclStorageDefExt::from(def); + print_pallet_upgrade::maybe_print_pallet_upgrade(&def_ext); + let hidden_crate_name = def_ext.hidden_crate.as_ref().map(|i| i.to_string()) .unwrap_or_else(|| "decl_storage".to_string()); diff --git a/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/frame/support/procedural/src/storage/print_pallet_upgrade.rs new file mode 100644 index 0000000000000..b303fcf9552fe --- /dev/null +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -0,0 +1,387 @@ +use super::StorageLineTypeDef; +use quote::ToTokens; +use frame_support_procedural_tools::clean_type_string; + +/// Environment variable that tells us to print pallet upgrade helper. +const PRINT_PALLET_UPGRADE: &str = "PRINT_PALLET_UPGRADE"; + +fn check_print_pallet_upgrade() -> bool { + std::env::var(PRINT_PALLET_UPGRADE).is_ok() +} + +/// Convert visibilty as now objects are defined in a module. +fn convert_vis(vis: &syn::Visibility) -> &'static str{ + match vis { + syn::Visibility::Inherited => "pub(super)", + syn::Visibility::Public(_) => "pub", + _ => "/* TODO_VISIBILITY */", + } +} + +/// fn to convert to token stream then string using display and then call clean_type_string on it. +fn to_cleaned_string(t: impl quote::ToTokens) -> String { + clean_type_string(&format!("{}", t.into_token_stream())) +} + +/// Print an incomplete upgrade from decl_storage macro to new pallet attribute. +pub fn maybe_print_pallet_upgrade(def: &super::DeclStorageDefExt) { + if !check_print_pallet_upgrade() { + return + } + + let scrate = "e::quote!(frame_support); + + let config_gen = if def.optional_instance.is_some() { + "" + } else { + Default::default() + }; + + let impl_gen = if def.optional_instance.is_some() { + ", I: 'static>" + } else { + "" + }; + + let decl_gen = if def.optional_instance.is_some() { + "" + } else { + "" + }; + + let full_decl_gen = if def.optional_instance.is_some() { + ", I: 'static = ()>" + } else { + "" + }; + + let use_gen = if def.optional_instance.is_some() { + "" + } else { + "" + }; + + let use_gen_tuple = if def.optional_instance.is_some() { + "<(T, I)>" + } else { + "" + }; + + let mut genesis_config = String::new(); + let mut genesis_build = String::new(); + + let genesis_config_builder_def = super::genesis_config::BuilderDef::from_def(scrate, def); + if !genesis_config_builder_def.blocks.is_empty() { + let genesis_config_def = match super::genesis_config::GenesisConfigDef::from_def(def) { + Ok(g) => g, + Err(err) => { + println!("Could not print upgrade due compile error: {:?}", err); + return + }, + }; + + let genesis_config_impl_gen = if genesis_config_def.is_generic { + impl_gen.clone() + } else { + Default::default() + }; + + let genesis_config_use_gen = if genesis_config_def.is_generic { + use_gen.clone() + } else { + Default::default() + }; + + let genesis_config_decl_gen = if genesis_config_def.is_generic { + if def.optional_instance.is_some() { + ", I: 'static = ()>" + } else { + "" + } + } else { + Default::default() + }; + + let mut genesis_config_decl_fields = String::new(); + let mut genesis_config_default_fields = String::new(); + for field in &genesis_config_def.fields { + genesis_config_decl_fields.push_str(&format!(" + {attrs}pub {name}: {typ},", + attrs = field.attrs.iter() + .fold(String::new(), |res, attr| { + format!("{}#[{}] + ", + res, attr.to_token_stream()) + }), + name = field.name, + typ = to_cleaned_string(&field.typ), + )); + + genesis_config_default_fields.push_str(&format!(" + {name}: {default},", + name = field.name, + default = to_cleaned_string(&field.default), + )); + } + + genesis_config = format!(" + #[pallet::genesis_config] + pub struct GenesisConfig{genesis_config_decl_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{{genesis_config_decl_fields} + }} + + #[cfg(feature = \"std\")] + impl{genesis_config_impl_gen} Default for GenesisConfig{genesis_config_use_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{ + fn default() -> Self {{ + Self {{{genesis_config_default_fields} + }} + }} + }}", + genesis_config_decl_gen = genesis_config_decl_gen, + genesis_config_decl_fields = genesis_config_decl_fields, + genesis_config_impl_gen = genesis_config_impl_gen, + genesis_config_default_fields = genesis_config_default_fields, + genesis_config_use_gen = genesis_config_use_gen, + ); + + let genesis_config_build = genesis_config_builder_def.blocks.iter() + .fold(String::new(), |res, block| { + format!("{} + {}", + res, + to_cleaned_string(block), + ) + }); + + genesis_build = format!(" + #[pallet::genesis_build] + impl{impl_gen} GenesisBuild{use_gen} for GenesisConfig{genesis_config_use_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{ + fn build(&self) {{{genesis_config_build} + }} + }}", + impl_gen = impl_gen, + use_gen = use_gen, + genesis_config_use_gen = genesis_config_use_gen, + genesis_config_build = genesis_config_build, + ); + } + + let mut storages = String::new(); + for line in &def.storage_lines { + let storage_vis = convert_vis(&line.visibility); + + let getter = if let Some(getter) = &line.getter { + format!(" + #[pallet::getter(fn {getter})]", + getter = getter + ) + } else { + Default::default() + }; + + let value_type = &line.value_type; + + let default_value_type_value = line.default_value.as_ref() + .map(|default_expr| { + format!(" + #[pallet::type_value] + {storage_vis} fn DefaultFor{name} /* TODO_MAYBE_GENERICS */ () -> {value_type} {{ + {default_expr} + }} +", + name = line.name, + storage_vis = storage_vis, + value_type = to_cleaned_string(&line.value_type), + default_expr = to_cleaned_string(&default_expr), + ) + }) + .unwrap_or_else(|| String::new()); + + let comma_query_kind = if line.is_option { + if line.default_value.is_some() { + ", OptionQuery" + } else { + Default::default() + } + } else { + ", ValueQuery" + }; + + let comma_default_value_getter_name = line.default_value.as_ref() + .map(|_| format!(", DefaultFor{}", line.name)) + .unwrap_or_else(|| String::new()); + + let typ = match &line.storage_type { + StorageLineTypeDef::Map(map) => { + format!("StorageMap<_, {hasher}, {key}, {value_type}{comma_query_kind}\ + {comma_default_value_getter_name}>", + hasher = &map.hasher.to_storage_hasher_struct(), + key = to_cleaned_string(&map.key), + value_type = to_cleaned_string(&value_type), + comma_query_kind = comma_query_kind, + comma_default_value_getter_name = comma_default_value_getter_name, + ) + }, + StorageLineTypeDef::DoubleMap(double_map) => { + format!("StorageDoubleMap<_, {hasher1}, {key1}, {hasher2}, {key2}, {value_type}\ + {comma_query_kind}{comma_default_value_getter_name}>", + hasher1 = double_map.hasher1.to_storage_hasher_struct(), + key1 = to_cleaned_string(&double_map.key1), + hasher2 = double_map.hasher2.to_storage_hasher_struct(), + key2 = to_cleaned_string(&double_map.key2), + value_type = to_cleaned_string(&value_type), + comma_query_kind = comma_query_kind, + comma_default_value_getter_name = comma_default_value_getter_name, + ) + }, + StorageLineTypeDef::Simple(_) => { + format!("StorageValue<_, {value_type}{comma_query_kind}\ + {comma_default_value_getter_name}>", + value_type = to_cleaned_string(&value_type), + comma_query_kind = comma_query_kind, + comma_default_value_getter_name = comma_default_value_getter_name, + ) + }, + }; + + let additional_comment = if line.is_option && line.default_value.is_some() { + " // TODO: This type of storage is no longer supported: `OptionQuery` cannot be used \ + alongside a not-none value on empty storage. Please use `ValueQuery` instead." + } else { + "" + }; + + storages.push_str(&format!(" +{default_value_type_value}{doc} + #[pallet::storage]{getter} + {storage_vis} type {name}{full_decl_gen} = {typ};{additional_comment}", + default_value_type_value = default_value_type_value, + getter = getter, + storage_vis = storage_vis, + name = line.name, + full_decl_gen = full_decl_gen, + typ = typ, + additional_comment = additional_comment, + doc = line.doc_attrs.iter() + .fold(String::new(), |mut res, attr| { + if let syn::Meta::NameValue(name_value) = attr { + if name_value.path.is_ident("doc") { + if let syn::Lit::Str(string) = &name_value.lit { + res = format!("{} + ///{}", + res, + string.value(), + ); + } + } + } + res + }), + )); + } + + let deprecated_instance_stuff = if def.optional_instance.is_some() { + " + /// Old name for default instance generated by decl_storage. + #[deprecated(note=\"use `()` instead\")] + pub type DefaultInstance = (); + + /// Old name for instance trait used by old macros. + #[deprecated(note=\"use `'static` instead\")] + pub trait Instance: 'static {} + impl Instance for I {}" + } else { + "" + }; + + println!(" +// Template for pallet upgrade for {pallet_name} + +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet {{ + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; + + #[pallet::config] + pub trait Config{config_gen}: frame_system::Config + // TODO_MAYBE_ADDITIONAL_BOUNDS_AND_WHERE_CLAUSE + {{ + // TODO_ASSOCIATED_TYPE_AND_CONSTANTS + }} + + {deprecated_instance_stuff} + + #[pallet::pallet] + #[pallet::generate_store({store_vis} trait Store)] + pub struct Pallet{decl_gen}(PhantomData{use_gen_tuple}); + + /// Old name for pallet. + #[deprecated(note=\"use `Pallet` instead\")] + pub type Module{decl_gen} = Pallet{use_gen}; + + #[pallet::interface] + impl{impl_gen} Interface> for Pallet{use_gen} + // TODO_MAYBE_WHERE_CLAUSE + {{ + // TODO_ON_FINALIZE + // TODO_ON_INITIALIZE + // TODO_ON_RUNTIME_UPGRADE + // TODO_INTEGRITY_TEST + // TODO_OFFCHAIN_WORKER + }} + + #[pallet::call] + impl{impl_gen} Pallet{use_gen} + // 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 /* TODO_PUT_EVENT_GENERICS */ = Event /* TODO_PUT_EVENT_GENERICS */; + + #[pallet::error] + // TODO_ERROR + + #[pallet::origin] + // TODO_ORIGIN + + #[pallet::validate_unsigned] + // TODO_VALIDATE_UNSIGNED + + {storages} + + {genesis_config} + + {genesis_build} +}}", + config_gen = config_gen, + store_vis = convert_vis(&def.visibility), + impl_gen = impl_gen, + use_gen = use_gen, + use_gen_tuple = use_gen_tuple, + decl_gen = decl_gen, + storages = storages, + genesis_config = genesis_config, + genesis_build = genesis_build, + pallet_name = def.crate_name, + deprecated_instance_stuff = deprecated_instance_stuff, + ); +} diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 7bd2e00698930..015c2fd1197ed 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1788,7 +1788,11 @@ pub mod pallet_prelude { /// /// 1. make crate compiling: rename usage of frame_system::Trait to frame_system::Config. /// 2. export metadata of the pallet for later checks -/// 3. reorganize pallet to have trait Trait, decl_* macros, ValidateUnsigned, ProvideInherent, +/// 3. generate the template upgrade for the pallet provided by decl_storage with environment +/// variable `PRINT_PALLET_UPGRADE`: `PRINT_PALLET_UPGRADE=1 cargo check -p my_pallet` +/// This template can be used as information it contains all information for storages, genesis +/// config and genesis build. +/// 4. reorganize pallet to have trait Trait, decl_* macros, ValidateUnsigned, ProvideInherent, /// Origin all together in one file. suggested order: /// * trait, /// * decl_module, @@ -1799,7 +1803,7 @@ pub mod pallet_prelude { /// * validate_unsigned, /// * provide_inherent, /// so far it should compile and all be correct. -/// 4. start writing new pallet module +/// 5. start writing new pallet module /// ```ignore /// pub use pallet::*; /// #[frame_support::pallet] @@ -1816,10 +1820,10 @@ pub mod pallet_prelude { /// // pub struct Pallet(PhantomData); // for instantiable pallet /// } /// ``` -/// 5. **migrate trait**: move trait into the module with +/// 6. **migrate trait**: move trait into the module with /// * rename `Trait` to `Config` /// * all const in decl_module to `#[pallet::constant]` -/// 6. **migrate decl_module**: write: +/// 7. **migrate decl_module**: write: /// ```ignore /// #[pallet::hooks] /// impl Hooks for Pallet { @@ -1840,12 +1844,17 @@ pub mod pallet_prelude { /// - `#[compact]` must now be written `#[pallet::compact]` /// - `#[weight = ..]` must now be written `#[pallet::weight(..)]` /// -/// 7. **migrate event**: +/// 8. **migrate event**: /// rewrite as a simple enum under with the attribute `#[pallet::event]`, /// use `#[pallet::generate_deposit($vis fn deposit_event)]` to generate deposit_event, /// use `#[pallet::metadata(...)]` to configure the metadata for types in order not to break them. -/// 8. **migrate error**: just rewrite it with attribute `#[pallet::error]`. -/// 9. **migrate storage**: +/// 9. **migrate error**: just rewrite it with attribute `#[pallet::error]`. +/// 10. **migrate storage**: +/// decl_storage provide an upgrade template (see 3.). All storages, genesis config, genesis +/// build and default implementation of genesis config can be taken from it directly. +/// +/// Otherwise here is the manual process: +/// /// first migrate the genesis logic. write: /// ```ignore /// #[pallet::genesis_config] @@ -1891,13 +1900,13 @@ pub mod pallet_prelude { /// can be implemented manually, just implement those functions by calling `GenesisBuild` /// implementation. /// -/// 10. **migrate origin**: just move the origin to the pallet module under `#[pallet::origin]` -/// 11. **migrate validate_unsigned**: just move the ValidateUnsigned implementation to the pallet +/// 11. **migrate origin**: just move the origin to the pallet module under `#[pallet::origin]` +/// 12. **migrate validate_unsigned**: just move the ValidateUnsigned implementation to the pallet /// module under `#[pallet::validate_unsigned]` -/// 12. **migrate provide_inherent**: just move the ValidateUnsigned implementation to the pallet +/// 13. **migrate provide_inherent**: just move the ValidateUnsigned implementation to the pallet /// module under `#[pallet::provide_inherent]` -/// 13. rename the usage of Module to Pallet and the usage of Config to Trait inside the crate. -/// 14. migration is done, now double check migration with the checking migration guidelines. +/// 14. rename the usage of Module to Pallet and the usage of Config to Trait inside the crate. +/// 15. migration is done, now double check migration with the checking migration guidelines. /// /// ## Checking upgrade guidelines: /// From 0d9bb3e9abd04fc2e594b8a5db23c4e60679c093 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 19 Nov 2020 11:31:13 +0100 Subject: [PATCH 05/36] Improved error msg, typo. Co-authored-by: Shawn Tabrizi --- frame/support/procedural/src/construct_runtime/mod.rs | 3 +-- frame/support/procedural/src/lib.rs | 4 ++-- frame/support/procedural/src/pallet/parse/call.rs | 4 ++-- frame/support/procedural/src/pallet/parse/config.rs | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 614c69acabcbb..a93761dd599be 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -335,8 +335,7 @@ fn decl_runtime_metadata<'a>( let index = module_declaration.index; quote!( - // Note: we can keep the parts Pallet or Module or ValidateUnsigned because they - // are not used by impl_runtime_metadata anyway. + // Note: impl_runtime_metadata can be given all parts, no need to filter out any part #module::#pallet_or_module #instance as #name { index #index } with #(#parts)*, ) }); diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 26bb99c892853..f0b27de8d5273 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -276,8 +276,8 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// /// We provide support for the following module parts in a pallet: /// -/// - `Pallet` or `Module`, mandatory. (one or the other must be provided depending if pallet use -/// pallet attribute macro or old decl_module macro +/// - `Pallet` or `Module`, mandatory. (one or the other must be provided depending if the pallet +/// uses the pallet attribute macro or old `decl_module` macro. /// - `Call` /// - `Storage` /// - `Event` or `Event` (if the event is generic) diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index c77667913e3db..faf5736262e5a 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -115,7 +115,7 @@ pub fn check_dispatchable_first_arg_type(ty: &syn::Type) -> syn::Result<()> { syn::parse2::(ty.to_token_stream()) .map_err(|e| { - let msg = format!("Invalid ty: {}", expected); + let msg = format!("Invalid type: {}", expected); let mut err = syn::Error::new(ty.span(), msg); err.combine(e); err @@ -180,7 +180,7 @@ impl CallDef { let msg = if call_var_attrs.len() == 0 { "Invalid pallet::call, require weight attribute i.e. `#[pallet::weight = $expr]`" } else { - "Invalid pallet::call, to many weight attribute given" + "Invalid pallet::call, too many weight attributes given" }; return Err(syn::Error::new(method.sig.span(), msg)); } diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs index a243920ee0b24..08eacb8f003d5 100644 --- a/frame/support/procedural/src/pallet/parse/config.rs +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -268,7 +268,7 @@ impl ConfigDef { let item = if let syn::Item::Trait(item) = item { item } else { - let msg = "Invalid pallet::config, expect trait definition"; + let msg = "Invalid pallet::config, expected trait definition"; return Err(syn::Error::new(item.span(), msg)); }; @@ -288,7 +288,7 @@ impl ConfigDef { }; if item.generics.params.len() > 1 { - let msg = "Invalid pallet::config, expect no more than one generics"; + let msg = "Invalid pallet::config, expected no more than one generic"; return Err(syn::Error::new(item.generics.params[2].span(), msg)); } From b48cfc62eae7e29460af61424c607d9d3efbd265 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Thu, 19 Nov 2020 11:31:56 +0100 Subject: [PATCH 06/36] Improved error msg, typo. Co-authored-by: Shawn Tabrizi --- frame/support/procedural/src/pallet/parse/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs index 08eacb8f003d5..f9ad4bd062e77 100644 --- a/frame/support/procedural/src/pallet/parse/config.rs +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -330,7 +330,7 @@ impl ConfigDef { consts_metadata.push(constant); }, _ => { - let msg = "Invalid pallet::constant in pallet::config, expect type trait \ + let msg = "Invalid pallet::constant in pallet::config, expected type trait \ item"; return Err(syn::Error::new(trait_item.span(), msg)); }, From cc165a36aa85006f6089cc44ac70135948e69b2b Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 19 Nov 2020 12:04:52 +0100 Subject: [PATCH 07/36] Improved error message on unexpected attributes + ui test --- frame/support/procedural/src/pallet/mod.rs | 3 ++- frame/support/test/tests/pallet_ui/attr_non_empty.rs | 6 ++++++ frame/support/test/tests/pallet_ui/attr_non_empty.stderr | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 frame/support/test/tests/pallet_ui/attr_non_empty.rs create mode 100644 frame/support/test/tests/pallet_ui/attr_non_empty.stderr diff --git a/frame/support/procedural/src/pallet/mod.rs b/frame/support/procedural/src/pallet/mod.rs index 8b9a814b33909..7ae5a573d0103 100644 --- a/frame/support/procedural/src/pallet/mod.rs +++ b/frame/support/procedural/src/pallet/mod.rs @@ -36,7 +36,8 @@ pub fn pallet( item: proc_macro::TokenStream ) -> proc_macro::TokenStream { if !attr.is_empty() { - let msg = "Invalid pallet macro call: expect `#[frame_support::pallet]`"; + let msg = "Invalid pallet macro call: expected no attributes, e.g. macro call must be just \ + `#[frame_support::pallet]` or `#[pallet]`"; let span = proc_macro2::TokenStream::from(attr).span(); return syn::Error::new(span, msg).to_compile_error().into(); } diff --git a/frame/support/test/tests/pallet_ui/attr_non_empty.rs b/frame/support/test/tests/pallet_ui/attr_non_empty.rs new file mode 100644 index 0000000000000..5173d983bbd8e --- /dev/null +++ b/frame/support/test/tests/pallet_ui/attr_non_empty.rs @@ -0,0 +1,6 @@ +#[frame_support::pallet [foo]] +mod foo { +} + +fn main() { +} diff --git a/frame/support/test/tests/pallet_ui/attr_non_empty.stderr b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr new file mode 100644 index 0000000000000..144af5a17ea5c --- /dev/null +++ b/frame/support/test/tests/pallet_ui/attr_non_empty.stderr @@ -0,0 +1,5 @@ +error: Invalid pallet macro call: expected no attributes, e.g. macro call must be just `#[frame_support::pallet]` or `#[pallet]` + --> $DIR/attr_non_empty.rs:1:26 + | +1 | #[frame_support::pallet [foo]] + | ^^^ From 460ccf90509734cba055f21a5638d63810b16af5 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 19 Nov 2020 12:25:01 +0100 Subject: [PATCH 08/36] add test for transactional --- frame/support/test/tests/pallet.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 143f32802bf9c..8ea7084dd9c19 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -144,8 +144,13 @@ pub mod pallet { /// Doc comment put in metadata #[pallet::weight(1)] #[frame_support::transactional] - fn foo_transactional(_origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { - Ok(().into()) + fn foo_transactional(_origin: OriginFor, #[pallet::compact] foo: u32) -> DispatchResultWithPostInfo { + Self::deposit_event(Event::Something(0)); + if foo != 0 { + Ok(().into()) + } else { + Err(Error::::InsufficientProposersBalance.into()) + } } } @@ -318,6 +323,23 @@ frame_support::construct_runtime!( } ); +#[test] +fn transactional_works() { + TestExternalities::default().execute_with(|| { + frame_system::Pallet::::set_block_number(1); + + pallet::Call::::foo_transactional(0).dispatch_bypass_filter(None.into()) + .err().unwrap(); + assert!(frame_system::Pallet::::events().is_empty()); + + pallet::Call::::foo_transactional(1).dispatch_bypass_filter(None.into()).unwrap(); + assert_eq!( + frame_system::Pallet::::events().iter().map(|e| &e.event).collect::>(), + vec![&Event::pallet(pallet::Event::Something(0))], + ); + }) +} + #[test] fn call_expand() { let call_foo = pallet::Call::::foo(3, 0); @@ -571,7 +593,7 @@ fn metadata() { name: DecodeDifferent::Decoded("foo_transactional".to_string()), arguments: DecodeDifferent::Decoded(vec![ FunctionArgumentMetadata { - name: DecodeDifferent::Decoded("_foo".to_string()), + name: DecodeDifferent::Decoded("foo".to_string()), ty: DecodeDifferent::Decoded("Compact".to_string()), } ]), From 5ced0a8173dd9430c21e8c7e6bbea81220a1c643 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 19 Nov 2020 13:54:32 +0100 Subject: [PATCH 09/36] various typo --- frame/support/procedural/src/pallet/expand/storage.rs | 2 +- frame/support/procedural/src/pallet/parse/config.rs | 4 ++-- frame/support/procedural/src/pallet/parse/event.rs | 4 ++-- .../procedural/src/pallet/parse/genesis_config.rs | 4 ++-- frame/support/procedural/src/pallet/parse/helper.rs | 2 +- .../procedural/src/pallet/parse/pallet_struct.rs | 2 +- frame/support/src/lib.rs | 10 +++++----- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/frame/support/procedural/src/pallet/expand/storage.rs b/frame/support/procedural/src/pallet/expand/storage.rs index 7f6e6cac5f16b..2d8956324f467 100644 --- a/frame/support/procedural/src/pallet/expand/storage.rs +++ b/frame/support/procedural/src/pallet/expand/storage.rs @@ -27,7 +27,7 @@ fn prefix_ident(storage_ident: &syn::Ident) -> syn::Ident { /// * generate StoragePrefix structs (e.g. for a storage `MyStorage` a struct with the name /// `_GeneratedPrefixForStorage$NameOfStorage` is generated) and implements StorageInstance trait. -/// * replace the first generic `_` by the genereted prefix structure +/// * replace the first generic `_` by the generated prefix structure /// * generate metadatas pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream { let frame_support = &def.frame_support; diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs index f9ad4bd062e77..5cd58460fc022 100644 --- a/frame/support/procedural/src/pallet/parse/config.rs +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -38,11 +38,11 @@ mod keyword { pub struct ConfigDef { /// The index of item in pallet module. pub index: usize, - /// Wheither the trait has instance (i.e. define with `Config`) + /// Whether the trait has instance (i.e. define with `Config`) pub has_instance: bool, /// Const associated type. pub consts_metadata: Vec, - /// Wether the trait has the associated type `Event`, note that those bounds are checked: + /// Whether the trait has the associated type `Event`, note that those bounds are checked: /// * `IsType::Event` /// * `From` or `From>` or `From>` pub has_event_type: bool, diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs index 49911832e20d2..e0e04428f6686 100644 --- a/frame/support/procedural/src/pallet/parse/event.rs +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -40,9 +40,9 @@ pub struct EventDef { pub instances: Vec, /// If event is declared with instance. pub has_instance: bool, - /// If event is declared with genericity. + /// If event is declared with generics. pub is_generic: bool, - /// Weither the function `deposit_event` must be generated. + /// Whether the function `deposit_event` must be generated. pub deposit_event: Option<(syn::Visibility, proc_macro2::Span)>, /// Where clause used in event definition. pub where_clause: Option, diff --git a/frame/support/procedural/src/pallet/parse/genesis_config.rs b/frame/support/procedural/src/pallet/parse/genesis_config.rs index beecd3ef39243..60a979ecfc937 100644 --- a/frame/support/procedural/src/pallet/parse/genesis_config.rs +++ b/frame/support/procedural/src/pallet/parse/genesis_config.rs @@ -27,9 +27,9 @@ use super::helper; pub struct GenesisConfigDef { /// The index of item in pallet module. pub index: usize, - /// Weither type has instance generic. + /// Whether type has instance generic. pub has_instance: bool, - /// Weither type has trait generic. + /// Whether type has trait generic. pub has_trait: bool, /// A set of usage of instance, must be check for consistency with trait. pub instances: Vec, diff --git a/frame/support/procedural/src/pallet/parse/helper.rs b/frame/support/procedural/src/pallet/parse/helper.rs index 1d797a0cc72ca..c5d8301fe23a4 100644 --- a/frame/support/procedural/src/pallet/parse/helper.rs +++ b/frame/support/procedural/src/pallet/parse/helper.rs @@ -380,7 +380,7 @@ pub fn check_pallet_struct_usage(type_: &Box) -> syn::Result, /// The keyword Pallet used (contains span). pub pallet: keyword::Pallet, - /// Weither the trait `Store` must be generated. + /// Whether the trait `Store` must be generated. pub store: Option<(syn::Visibility, keyword::Store)> } diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 015c2fd1197ed..87b8dfc333db2 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -96,7 +96,7 @@ pub enum Never {} /// load the value from the storage under a fixed key. If the value could not be found in the /// storage, the given default value will be returned. It is required that the value implements /// [`Encode`](codec::Encode) and [`Decode`](codec::Decode). The key for looking up the value -/// in the storage is built using the following formular: +/// in the storage is built using the following formula: /// /// `twox_128(":" ++ NAME ++ ":")` where `NAME` is the name that is passed as type name. /// @@ -1229,7 +1229,7 @@ pub mod pallet_prelude { /// Variant documentations and field types are put into metadata. /// The attribute `#[pallet::metadata(..)]` allows to specify the metadata to put for some types. /// -/// The metadat of a type is defined by: +/// The metadata of a type is defined by: /// * if matching a type in `#[pallet::metadata(..)]`, then the corresponding metadata. /// * otherwise the last segment of the type. /// @@ -1405,7 +1405,7 @@ pub mod pallet_prelude { /// /// ### Macro expansion /// -/// Macro make currenlty no use of this information, but it might use this information in the +/// Macro make currently no use of this information, but it might use this information in the /// future to give information directly to construct_runtime. /// /// # Validate unsigned: `#[pallet::validate_unsigned]` optional @@ -1427,7 +1427,7 @@ pub mod pallet_prelude { /// /// ### Macro expansion /// -/// Macro make currenlty no use of this information, but it might use this information in the +/// Macro make currently no use of this information, but it might use this information in the /// future to give information directly to construct_runtime. /// /// # Origin: `#[pallet::origin]` optional @@ -1838,7 +1838,7 @@ pub mod pallet_prelude { /// } /// ``` /// and write inside all the call in decl_module with a few changes in the signature: -/// - origin must now be written completly, e.g. `origin: OriginFor` +/// - origin must now be written completely, e.g. `origin: OriginFor` /// - result type must be `DispatchResultWithPostInfo`, you need to write it and also you might /// need to put `Ok(().into())` at the end or the function. /// - `#[compact]` must now be written `#[pallet::compact]` From 688f0449f1df314227be9e6a7ab4136a23dfbd55 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 23 Nov 2020 11:39:12 +0100 Subject: [PATCH 10/36] some tips when spans are lost --- frame/support/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 87b8dfc333db2..b76208b87d4dc 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1932,4 +1932,17 @@ pub mod pallet_prelude { /// Thus any use of this pallet in `construct_runtime!` should be careful to update name in /// order not to break storage or to upgrade storage (moreover for instantiable pallet). /// If pallet is published, make sure to warn about this breaking change. +/// +/// # Notes when macro fails to show proper error message spans: +/// +/// Rustc loses span for some macro input. Some tips to fix it: +/// * do not use inner attribute: +/// ``` +/// #[pallet] +/// pub mod pallet { +/// //! This inner attribute will make span fail +/// .. +/// } +/// ``` +/// * use the newest nightly possible. pub use frame_support_procedural::pallet; From c5ef21f4ed7290c45d974ddbb3376e07bec27491 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 23 Nov 2020 12:13:56 +0100 Subject: [PATCH 11/36] allow pallet to depend on other pallet instances --- .../procedural/src/pallet/expand/instances.rs | 6 +- frame/support/src/instances.rs | 90 +++++++++++++++++++ frame/support/src/lib.rs | 1 + 3 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 frame/support/src/instances.rs diff --git a/frame/support/procedural/src/pallet/expand/instances.rs b/frame/support/procedural/src/pallet/expand/instances.rs index 46783d71079c5..1b05be4f61f91 100644 --- a/frame/support/procedural/src/pallet/expand/instances.rs +++ b/frame/support/procedural/src/pallet/expand/instances.rs @@ -35,10 +35,6 @@ pub fn expand_instances(def: &mut Def) -> proc_macro2::TokenStream { #[doc(hidden)] pub type #inherent_ident = (); - #( - /// Generated module instance - #[derive(Clone, Copy, PartialEq, Eq, #frame_support::RuntimeDebugNoBound)] - pub struct #instances; - )* + #( pub use #frame_support::instances::#instances; )* ) } diff --git a/frame/support/src/instances.rs b/frame/support/src/instances.rs new file mode 100644 index 0000000000000..fd619103765c3 --- /dev/null +++ b/frame/support/src/instances.rs @@ -0,0 +1,90 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 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. + +//! Some instance placeholder to be used in `pallet` attribute macro. +//! +//! `pallet` attribute macro do not make use of `I` instance generic for anything, thus the +//! placeholder can reexported from frame-support. +//! This can allow some instantiable pallet to depend on specific instance of another: +//! ``` +//! # mod another_pallet { pub trait Config {} } +//! pub trait Config: another_pallet::Config {} +//! ``` + +/// Instance0 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance0; + +/// Instance1 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance1; + +/// Instance2 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance2; + +/// Instance3 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance3; + +/// Instance4 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance4; + +/// Instance5 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance5; + +/// Instance6 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance6; + +/// Instance7 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance7; + +/// Instance8 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance8; + +/// Instance9 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance9; + +/// Instance10 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance10; + +/// Instance11 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance11; + +/// Instance12 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance12; + +/// Instance13 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance13; + +/// Instance14 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance14; + +/// Instance15 to be used for instantiable pallet define with `pallet` macro. +#[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] +pub struct Instance15; diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index b76208b87d4dc..997e1ddf6e595 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -67,6 +67,7 @@ pub mod unsigned; pub mod error; pub mod traits; pub mod weights; +pub mod instances; pub use self::hash::{ Twox256, Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, Hashable, From 240a2a736ada38ad945f66df8a4a81f84b02ef6e Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 23 Nov 2020 12:14:16 +0100 Subject: [PATCH 12/36] make event type metadata consistent with call and constant --- .../procedural/src/pallet/parse/event.rs | 22 +++++-------------- frame/support/src/lib.rs | 6 ++--- frame/support/test/tests/pallet.rs | 15 +++++++++---- .../test/tests/pallet_compatibility.rs | 1 + .../tests/pallet_compatibility_instance.rs | 1 + frame/support/test/tests/pallet_instance.rs | 2 +- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs index e0e04428f6686..cb3d864e38f5f 100644 --- a/frame/support/procedural/src/pallet/parse/event.rs +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -18,6 +18,7 @@ use super::helper; use syn::spanned::Spanned; use quote::ToTokens; +use frame_support_procedural_tools::clean_type_string; /// List of additional token to be used for parsing. mod keyword { @@ -221,26 +222,15 @@ impl EventDef { .map(|field| { metadata.iter().find(|m| m.0 == field.ty) .map(|m| m.1.clone()) - .or_else(|| { - if let syn::Type::Path(p) = &field.ty { - p.path.segments.last().map(|s| format!("{}", s.ident)) - } else { - None - } - }) - .ok_or_else(|| { - let msg = "Invalid pallet::event, type can't be parsed for \ - metadata, must be either a path type (and thus last \ - segments ident is metadata) or match a type in the \ - metadata attributes"; - syn::Error::new(field.span(), msg) + .unwrap_or_else(|| { + clean_type_string(&field.ty.to_token_stream().to_string()) }) }) - .collect::>()?; + .collect(); - Ok((name, args, docs)) + (name, args, docs) }) - .collect::>()?; + .collect(); Ok(EventDef { index, diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 997e1ddf6e595..577846f91e89d 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1232,7 +1232,7 @@ pub mod pallet_prelude { /// /// The metadata of a type is defined by: /// * if matching a type in `#[pallet::metadata(..)]`, then the corresponding metadata. -/// * otherwise the last segment of the type. +/// * otherwise the type stringified. /// /// E.g.: /// ```ignore @@ -1242,7 +1242,7 @@ pub mod pallet_prelude { /// Proposed(u32, T::AccountId), /// } /// ``` -/// will write in event variant metadata `"SpecialU32"` and `"AccountId"`. +/// will write in event variant metadata `"SpecialU32"` and `"T::AccountId"`. /// /// The attribute `#[pallet::generate_deposit($visbility fn deposit_event)]` generate a helper /// function on `Pallet` to deposit event. @@ -1558,7 +1558,7 @@ pub mod pallet_prelude { /// pub enum Event { /// /// doc comment put in metadata /// // `::AccountId` is not defined in metadata list, the last -/// // segment is put into metadata, i.e. `AccountId` +/// // Thus the metadata is `::AccountId`. /// Proposed(::AccountId), /// /// doc /// // here metadata will be `Balance` as define in metadata list diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 8ea7084dd9c19..500b3ef0cba0b 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -133,7 +133,11 @@ pub mod pallet { { /// Doc comment put in metadata #[pallet::weight(Weight::from(*_foo))] - fn foo(origin: OriginFor, #[pallet::compact] _foo: u32, _bar: u32) -> DispatchResultWithPostInfo { + fn foo( + origin: OriginFor, + #[pallet::compact] _foo: u32, + _bar: u32, + ) -> DispatchResultWithPostInfo { T::AccountId::from(SomeType1); // Test for where clause T::AccountId::from(SomeType3); // Test for where clause let _ = origin; @@ -144,7 +148,10 @@ pub mod pallet { /// Doc comment put in metadata #[pallet::weight(1)] #[frame_support::transactional] - fn foo_transactional(_origin: OriginFor, #[pallet::compact] foo: u32) -> DispatchResultWithPostInfo { + fn foo_transactional( + _origin: OriginFor, + #[pallet::compact] foo: u32, + ) -> DispatchResultWithPostInfo { Self::deposit_event(Event::Something(0)); if foo != 0 { Ok(().into()) @@ -605,7 +612,7 @@ fn metadata() { event: Some(DecodeDifferent::Decoded(vec![ EventMetadata { name: DecodeDifferent::Decoded("Proposed".to_string()), - arguments: DecodeDifferent::Decoded(vec!["AccountId".to_string()]), + arguments: DecodeDifferent::Decoded(vec!["::AccountId".to_string()]), documentation: DecodeDifferent::Decoded(vec![ " doc comment put in metadata".to_string() ]), @@ -624,7 +631,7 @@ fn metadata() { }, EventMetadata { name: DecodeDifferent::Decoded("SomethingElse".to_string()), - arguments: DecodeDifferent::Decoded(vec!["_1".to_string()]), + arguments: DecodeDifferent::Decoded(vec!["::_1".to_string()]), documentation: DecodeDifferent::Decoded(vec![]), }, ])), diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs index 48418ae57611f..b2b5249729781 100644 --- a/frame/support/test/tests/pallet_compatibility.rs +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -146,6 +146,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(fn deposit_event)] + #[pallet::metadata(T::Balance = "Balance")] pub enum Event { /// Dummy event, just here so there's a generic type that's used. Dummy(T::Balance), diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs index 7da9d7ed83e20..6e9cb11da4d06 100644 --- a/frame/support/test/tests/pallet_compatibility_instance.rs +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -130,6 +130,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(fn deposit_event)] + #[pallet::metadata(T::Balance = "Balance")] pub enum Event, I: 'static = ()> { /// Dummy event, just here so there's a generic type that's used. Dummy(T::Balance), diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index f9e20324705e7..51fef63da2a0b 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -591,7 +591,7 @@ fn metadata() { event: Some(DecodeDifferent::Decoded(vec![ EventMetadata { name: DecodeDifferent::Decoded("Proposed".to_string()), - arguments: DecodeDifferent::Decoded(vec!["AccountId".to_string()]), + arguments: DecodeDifferent::Decoded(vec!["::AccountId".to_string()]), documentation: DecodeDifferent::Decoded(vec![ " doc comment put in metadata".to_string() ]), From 1229c33341d875a23fb094547724dd426b665e4a Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 23 Nov 2020 12:19:22 +0100 Subject: [PATCH 13/36] error messages --- .../procedural/src/pallet/parse/helper.rs | 20 +++++++++---------- .../pallet_ui/call_invalid_origin_type.stderr | 2 +- .../pallet_ui/genesis_invalid_generic.stderr | 2 +- .../tests/pallet_ui/trait_invalid_item.stderr | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frame/support/procedural/src/pallet/parse/helper.rs b/frame/support/procedural/src/pallet/parse/helper.rs index c5d8301fe23a4..eddb03fc33f9c 100644 --- a/frame/support/procedural/src/pallet/parse/helper.rs +++ b/frame/support/procedural/src/pallet/parse/helper.rs @@ -154,7 +154,7 @@ impl syn::parse::Parse for Unit { let content; syn::parenthesized!(content in input); if !content.is_empty() { - let msg = "unexpected tokens, expect nothing inside parenthesis as `()`"; + let msg = "unexpected tokens, expected nothing inside parenthesis as `()`"; return Err(syn::Error::new(content.span(), msg)); } Ok(Self) @@ -167,7 +167,7 @@ impl syn::parse::Parse for StaticLifetime { fn parse(input: syn::parse::ParseStream) -> syn::Result { let lifetime = input.parse::()?; if lifetime.ident != "static" { - let msg = "unexpected tokens, expect `static`"; + let msg = "unexpected tokens, expected `static`"; return Err(syn::Error::new(lifetime.ident.span(), msg)); } Ok(Self) @@ -183,7 +183,7 @@ pub fn check_config_def_gen( gen: &syn::Generics, span: proc_macro2::Span, ) -> syn::Result<()> { - let expected = "expect `I: 'static = ()`"; + let expected = "expected `I: 'static = ()`"; pub struct CheckTraitDefGenerics; impl syn::parse::Parse for CheckTraitDefGenerics { fn parse(input: syn::parse::ParseStream) -> syn::Result { @@ -219,7 +219,7 @@ pub fn check_type_def_gen_no_bounds( gen: &syn::Generics, span: proc_macro2::Span, ) -> syn::Result { - let expected = "expect `T` or `T, I = ()`"; + let expected = "expected `T` or `T, I = ()`"; pub struct Checker(InstanceUsage); impl syn::parse::Parse for Checker { fn parse(input: syn::parse::ParseStream) -> syn::Result { @@ -266,7 +266,7 @@ pub fn check_type_def_optional_gen( gen: &syn::Generics, span: proc_macro2::Span, ) -> syn::Result> { - let expected = "expect `` or `T` or `T: Config` or `T, I = ()` or \ + let expected = "expected `` or `T` or `T: Config` or `T, I = ()` or \ `T: Config, I: 'static = ()`"; pub struct Checker(Option); impl syn::parse::Parse for Checker { @@ -340,7 +340,7 @@ pub fn check_type_def_optional_gen( /// /// return the instance if found. pub fn check_pallet_struct_usage(type_: &Box) -> syn::Result { - let expected = "expect `Pallet` or `Pallet`"; + let expected = "expected `Pallet` or `Pallet`"; pub struct Checker(InstanceUsage); impl syn::parse::Parse for Checker { fn parse(input: syn::parse::ParseStream) -> syn::Result { @@ -385,7 +385,7 @@ pub fn check_impl_gen( gen: &syn::Generics, span: proc_macro2::Span ) -> syn::Result { - let expected = "expect `impl` or `impl, I: 'static>`"; + let expected = "expected `impl` or `impl, I: 'static>`"; pub struct Checker(InstanceUsage); impl syn::parse::Parse for Checker { fn parse(input: syn::parse::ParseStream) -> syn::Result { @@ -435,7 +435,7 @@ pub fn check_type_def_gen( gen: &syn::Generics, span: proc_macro2::Span, ) -> syn::Result { - let expected = "expect `T` or `T: Config` or `T, I = ()` or \ + let expected = "expected `T` or `T: Config` or `T, I = ()` or \ `T: Config, I: 'static = ()`"; pub struct Checker(InstanceUsage); impl syn::parse::Parse for Checker { @@ -506,7 +506,7 @@ pub fn check_type_def_gen( /// /// return the instance if found. pub fn check_genesis_builder_usage(type_: &syn::Path) -> syn::Result { - let expected = "expect `GenesisBuild` or `GenesisBuild`"; + let expected = "expected `GenesisBuild` or `GenesisBuild`"; pub struct Checker(InstanceUsage); impl syn::parse::Parse for Checker { fn parse(input: syn::parse::ParseStream) -> syn::Result { @@ -552,7 +552,7 @@ pub fn check_type_value_gen( gen: &syn::Generics, span: proc_macro2::Span, ) -> syn::Result> { - let expected = "expect `` or `T: Config` or `T: Config, I: 'static`"; + let expected = "expected `` or `T: Config` or `T: Config, I: 'static`"; pub struct Checker(Option); impl syn::parse::Parse for Checker { fn parse(input: syn::parse::ParseStream) -> syn::Result { diff --git a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr index 9cf933698ff32..13083a49be342 100644 --- a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr +++ b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr @@ -1,4 +1,4 @@ -error: Invalid ty: expect `OriginFor` +error: Invalid type: expect `OriginFor` --> $DIR/call_invalid_origin_type.rs:17:18 | 17 | fn foo(origin: u8) {} diff --git a/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr index 619b5ffe9db98..f451f7b16aee5 100644 --- a/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr +++ b/frame/support/test/tests/pallet_ui/genesis_invalid_generic.stderr @@ -1,4 +1,4 @@ -error: Invalid genesis builder: expect `GenesisBuild` or `GenesisBuild` +error: Invalid genesis builder: expected `GenesisBuild` or `GenesisBuild` --> $DIR/genesis_invalid_generic.rs:19:7 | 19 | impl GenesisBuild for GenesisConfig {} diff --git a/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr b/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr index 3a2f2a4a19cda..72495d94b3079 100644 --- a/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr +++ b/frame/support/test/tests/pallet_ui/trait_invalid_item.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::constant in pallet::config, expect type trait item +error: Invalid pallet::constant in pallet::config, expected type trait item --> $DIR/trait_invalid_item.rs:9:3 | 9 | const U: u8 = 3; From c2148b09e3f00183220a3a53c9c388dc9bf70da5 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 23 Nov 2020 13:22:41 +0100 Subject: [PATCH 14/36] ignore doc example --- frame/support/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 6b70a39b73f38..4737293e704f7 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -2010,7 +2010,7 @@ pub mod pallet_prelude { /// /// Rustc loses span for some macro input. Some tips to fix it: /// * do not use inner attribute: -/// ``` +/// ```ignore /// #[pallet] /// pub mod pallet { /// //! This inner attribute will make span fail From e5485c8e370c0005ba3d5c38669f804ef2354a3d Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 23 Nov 2020 13:23:25 +0100 Subject: [PATCH 15/36] fix pallet upgrade template --- 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 b303fcf9552fe..f8a70f244b1dc 100644 --- a/frame/support/procedural/src/storage/print_pallet_upgrade.rs +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -328,7 +328,7 @@ pub mod pallet {{ pub type Module{decl_gen} = Pallet{use_gen}; #[pallet::interface] - impl{impl_gen} Interface> for Pallet{use_gen} + impl{impl_gen} Hooks> for Pallet{use_gen} // TODO_MAYBE_WHERE_CLAUSE {{ // TODO_ON_FINALIZE From d5b745f4f032a92025719adaa452254c835467ea Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 25 Nov 2020 16:25:55 +0100 Subject: [PATCH 16/36] fixup --- frame/contracts/src/wasm/env_def/macros.rs | 8 ++++---- frame/contracts/src/wasm/mod.rs | 4 ++-- frame/contracts/src/wasm/runtime.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index 6741896102d40..cc61deb074b75 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -129,8 +129,8 @@ macro_rules! define_func { args: &[sp_sandbox::Value], ) -> Result where - ::AccountId: - sp_core::crypto::UncheckedFrom<::Hash> + + ::AccountId: + sp_core::crypto::UncheckedFrom<::Hash> + AsRef<[u8]> { #[allow(unused)] @@ -190,8 +190,8 @@ macro_rules! define_env { impl $crate::wasm::env_def::FunctionImplProvider for $init_name where - ::AccountId: - sp_core::crypto::UncheckedFrom<::Hash> + + ::AccountId: + sp_core::crypto::UncheckedFrom<::Hash> + AsRef<[u8]> { fn impls)>(f: &mut F) { diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index baa75ad49720c..e4b935310a9a6 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -462,8 +462,8 @@ mod tests { gas_meter: &mut GasMeter, ) -> ExecResult where - ::AccountId: - UncheckedFrom<::Hash> + AsRef<[u8]> + ::AccountId: + UncheckedFrom<::Hash> + AsRef<[u8]> { use crate::exec::Vm; diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index a594baaaf94ea..019e82fea9883 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -291,8 +291,8 @@ pub struct Runtime<'a, E: Ext + 'a> { impl<'a, E> Runtime<'a, E> where E: Ext + 'a, - ::AccountId: - UncheckedFrom<::Hash> + AsRef<[u8]> + ::AccountId: + UncheckedFrom<::Hash> + AsRef<[u8]> { pub fn new( ext: &'a mut E, From 8e8ee8ddc60c1c740a14118147598a3098fad30d Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 25 Nov 2020 16:24:06 +0100 Subject: [PATCH 17/36] fix doc --- frame/support/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 4737293e704f7..9a9663abf0fcc 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1058,7 +1058,7 @@ pub mod pallet_prelude { /// It is define by a module item: /// ```ignore /// #[pallet] -/// mod pallet { +/// pub mod pallet { /// ... /// } /// ``` @@ -1073,7 +1073,7 @@ pub mod pallet_prelude { /// frame_system: /// ```ignore /// #[pallet] -/// mod { +/// pub mod pallet { /// use frame_support::pallet_prelude::*; /// use frame_system::pallet_prelude::*; /// ... @@ -1880,7 +1880,7 @@ pub mod pallet_prelude { /// ```ignore /// pub use pallet::*; /// #[frame_support::pallet] -/// mod pallet { +/// pub mod pallet { /// pub use frame_support::pallet_prelude::*; /// pub use frame_system::pallet_prelude::*; /// use super::*; From 3ea926c444f85cb5197627eaecab7d8b792a3c13 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 25 Nov 2020 16:50:47 +0100 Subject: [PATCH 18/36] fix indentation --- frame/support/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 9a9663abf0fcc..6b0afaae2a9f7 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1879,7 +1879,8 @@ pub mod pallet_prelude { /// 5. start writing new pallet module /// ```ignore /// pub use pallet::*; -/// #[frame_support::pallet] +/// +/// #[frame_support::pallet] /// pub mod pallet { /// pub use frame_support::pallet_prelude::*; /// pub use frame_system::pallet_prelude::*; From bd99a8db8af4e62fd8dbd6e978638a8b6da21d05 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Mon, 30 Nov 2020 11:59:22 +0100 Subject: [PATCH 19/36] Apply suggestions code formatting Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- frame/support/procedural/src/pallet/parse/call.rs | 1 - frame/support/procedural/src/pallet/parse/config.rs | 7 +++---- frame/support/procedural/src/pallet/parse/mod.rs | 1 + 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index faf5736262e5a..c1fccf890739d 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -69,7 +69,6 @@ impl syn::parse::Parse for FunctionAttr { syn::bracketed!(content in input); content.parse::()?; content.parse::()?; - content.parse::()?; let weight_content; diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs index 5cd58460fc022..1c1e8e6e9436f 100644 --- a/frame/support/procedural/src/pallet/parse/config.rs +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -292,12 +292,11 @@ impl ConfigDef { return Err(syn::Error::new(item.generics.params[2].span(), msg)); } - let has_instance; - if let Some(_) = item.generics.params.first() { + let has_instance = if let Some(_) = item.generics.params.first() { helper::check_config_def_gen(&item.generics, item.ident.span())?; - has_instance = true; + true } else { - has_instance = false; + false } let mut has_event_type = false; diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index 36ba7e1847401..b9db722b67b77 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -197,6 +197,7 @@ impl Def { _ => Ok(()) } } + /// Check that usage of trait `Config` is consistent with the definition, i.e. it is used with /// instance iff it is defined with instance. fn check_instance_usage(&self) -> syn::Result<()> { From 0adbb30495970b7022c8dfa701c78080c7c1c875 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 30 Nov 2020 14:44:06 +0100 Subject: [PATCH 20/36] some renames + fix compilation --- .../procedural/src/pallet/expand/call.rs | 18 ++++++++++-------- .../procedural/src/pallet/parse/call.rs | 11 +++++------ .../procedural/src/pallet/parse/config.rs | 4 ++-- .../procedural/src/pallet/parse/error.rs | 2 +- .../procedural/src/pallet/parse/event.rs | 2 +- .../src/pallet/parse/extra_constants.rs | 4 ++-- .../src/pallet/parse/genesis_build.rs | 4 ++-- .../src/pallet/parse/genesis_config.rs | 2 +- .../procedural/src/pallet/parse/hooks.rs | 6 +++--- .../procedural/src/pallet/parse/inherent.rs | 9 +++++---- .../support/procedural/src/pallet/parse/mod.rs | 2 +- .../procedural/src/pallet/parse/origin.rs | 2 +- .../src/pallet/parse/pallet_struct.rs | 2 +- .../procedural/src/pallet/parse/storage.rs | 14 +++++++------- .../procedural/src/pallet/parse/type_value.rs | 5 +++-- .../src/pallet/parse/validate_unsigned.rs | 8 ++++---- 16 files changed, 49 insertions(+), 46 deletions(-) diff --git a/frame/support/procedural/src/pallet/expand/call.rs b/frame/support/procedural/src/pallet/expand/call.rs index a5ad68cd90640..56b8ecf994158 100644 --- a/frame/support/procedural/src/pallet/expand/call.rs +++ b/frame/support/procedural/src/pallet/expand/call.rs @@ -31,7 +31,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { let pallet_ident = &def.pallet_struct.pallet; let where_clause = &def.call.where_clause; - let fn_ = def.call.methods.iter().map(|method| &method.fn_).collect::>(); + let fn_name = def.call.methods.iter().map(|method| &method.name).collect::>(); let fn_weight = def.call.methods.iter().map(|method| &method.weight); @@ -87,7 +87,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { #frame_support::sp_std::marker::PhantomData<(#type_use_gen,)>, #frame_support::Never, ), - #( #fn_( #( #args_compact_attr #args_type ),* ), )* + #( #fn_name( #( #args_compact_attr #args_type ),* ), )* } impl<#type_impl_gen> #frame_support::dispatch::GetDispatchInfo @@ -97,7 +97,7 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { fn get_dispatch_info(&self) -> #frame_support::dispatch::DispatchInfo { match *self { #( - Self::#fn_ ( #( ref #args_name, )* ) => { + Self::#fn_name ( #( ref #args_name, )* ) => { let base_weight = #fn_weight; let weight = < @@ -131,13 +131,13 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { { fn get_call_name(&self) -> &'static str { match *self { - #( Self::#fn_(..) => stringify!(#fn_), )* + #( Self::#fn_name(..) => stringify!(#fn_name), )* Self::__Ignore(_, _) => unreachable!("__PhantomItem cannot be used."), } } fn get_call_names() -> &'static [&'static str] { - &[ #( stringify!(#fn_), )* ] + &[ #( stringify!(#fn_name), )* ] } } @@ -152,8 +152,8 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { ) -> #frame_support::dispatch::DispatchResultWithPostInfo { match self { #( - Self::#fn_( #( #args_name, )* ) => - <#pallet_ident<#type_use_gen>>::#fn_(origin, #( #args_name, )* ) + Self::#fn_name( #( #args_name, )* ) => + <#pallet_ident<#type_use_gen>>::#fn_name(origin, #( #args_name, )* ) .map(Into::into).map_err(Into::into), )* Self::__Ignore(_, _) => { @@ -175,7 +175,9 @@ pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream { pub fn call_functions() -> &'static [#frame_support::dispatch::FunctionMetadata] { &[ #( #frame_support::dispatch::FunctionMetadata { - name: #frame_support::dispatch::DecodeDifferent::Encode(stringify!(#fn_)), + name: #frame_support::dispatch::DecodeDifferent::Encode( + stringify!(#fn_name) + ), arguments: #frame_support::dispatch::DecodeDifferent::Encode( &[ #( #frame_support::dispatch::FunctionArgumentMetadata { diff --git a/frame/support/procedural/src/pallet/parse/call.rs b/frame/support/procedural/src/pallet/parse/call.rs index c1fccf890739d..239329639e5f1 100644 --- a/frame/support/procedural/src/pallet/parse/call.rs +++ b/frame/support/procedural/src/pallet/parse/call.rs @@ -47,7 +47,7 @@ pub struct CallDef { /// Definition of dispatchable typically: `#[weight...] fn foo(origin .., param1: ...) -> ..` pub struct CallVariantDef { /// Function name. - pub fn_: syn::Ident, + pub name: syn::Ident, /// Information on args: `(is_compact, name, type)` pub args: Vec<(bool, syn::Ident, Box)>, /// Weight formula. @@ -98,7 +98,6 @@ impl syn::parse::Parse for ArgAttrIsCompact { /// Check the syntax is `OriginFor` pub fn check_dispatchable_first_arg_type(ty: &syn::Type) -> syn::Result<()> { - let expected = "expect `OriginFor`"; pub struct CheckDispatchableFirstArg; impl syn::parse::Parse for CheckDispatchableFirstArg { @@ -114,7 +113,7 @@ pub fn check_dispatchable_first_arg_type(ty: &syn::Type) -> syn::Result<()> { syn::parse2::(ty.to_token_stream()) .map_err(|e| { - let msg = format!("Invalid type: {}", expected); + let msg = "Invalid type: expected `OriginFor`"; let mut err = syn::Error::new(ty.span(), msg); err.combine(e); err @@ -133,7 +132,7 @@ impl CallDef { let item = if let syn::Item::Impl(item) = item { item } else { - return Err(syn::Error::new(item.span(), "Invalid pallet::call, expect item impl")); + return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl")); }; let mut instances = vec![]; @@ -141,7 +140,7 @@ impl CallDef { instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); if let Some((_, _, for_)) = item.trait_ { - let msg = "Invalid pallet::call, expect no trait ident as in \ + let msg = "Invalid pallet::call, expected no trait ident as in \ `impl<..> Pallet<..> { .. }`"; return Err(syn::Error::new(for_.span(), msg)) } @@ -214,7 +213,7 @@ impl CallDef { let docs = helper::get_doc_literals(&method.attrs); methods.push(CallVariantDef { - fn_: method.sig.ident.clone(), + name: method.sig.ident.clone(), weight, args, docs, diff --git a/frame/support/procedural/src/pallet/parse/config.rs b/frame/support/procedural/src/pallet/parse/config.rs index 1c1e8e6e9436f..46355b0fdb158 100644 --- a/frame/support/procedural/src/pallet/parse/config.rs +++ b/frame/support/procedural/src/pallet/parse/config.rs @@ -297,7 +297,7 @@ impl ConfigDef { true } else { false - } + }; let mut has_event_type = false; let mut consts_metadata = vec![]; @@ -362,7 +362,7 @@ impl ConfigDef { }; let msg = format!( - "Invalid pallet::trait, expect explicit `{}::Config` as supertrait, \ + "Invalid pallet::trait, expected explicit `{}::Config` as supertrait, \ found {}. \ (try `pub trait Config: frame_system::Config {{ ...` or \ `pub trait Config: frame_system::Config {{ ...`). \ diff --git a/frame/support/procedural/src/pallet/parse/error.rs b/frame/support/procedural/src/pallet/parse/error.rs index 4fcde327cc0d1..0bdf8e73b3749 100644 --- a/frame/support/procedural/src/pallet/parse/error.rs +++ b/frame/support/procedural/src/pallet/parse/error.rs @@ -42,7 +42,7 @@ impl ErrorDef { let item = if let syn::Item::Enum(item) = item { item } else { - return Err(syn::Error::new(item.span(), "Invalid pallet::error, expect item enum")); + return Err(syn::Error::new(item.span(), "Invalid pallet::error, expected item enum")); }; if !matches!(item.vis, syn::Visibility::Public(_)) { let msg = "Invalid pallet::error, `Error` must be public"; diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs index cb3d864e38f5f..cf5fe8f9bcee3 100644 --- a/frame/support/procedural/src/pallet/parse/event.rs +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -184,7 +184,7 @@ impl EventDef { let item = if let syn::Item::Enum(item) = item { item } else { - return Err(syn::Error::new(item.span(), "Invalid pallet::event, expect item enum")) + return Err(syn::Error::new(item.span(), "Invalid pallet::event, expected item enum")) }; let event_attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; diff --git a/frame/support/procedural/src/pallet/parse/extra_constants.rs b/frame/support/procedural/src/pallet/parse/extra_constants.rs index fd44dacbcc1d0..f37c7135de8f1 100644 --- a/frame/support/procedural/src/pallet/parse/extra_constants.rs +++ b/frame/support/procedural/src/pallet/parse/extra_constants.rs @@ -59,7 +59,7 @@ impl ExtraConstantsDef { let item = if let syn::Item::Impl(item) = item { item } else { - return Err(syn::Error::new(item.span(), "Invalid pallet::call, expect item impl")); + return Err(syn::Error::new(item.span(), "Invalid pallet::call, expected item impl")); }; let mut instances = vec![]; @@ -67,7 +67,7 @@ impl ExtraConstantsDef { instances.push(helper::check_pallet_struct_usage(&item.self_ty)?); if let Some((_, _, for_)) = item.trait_ { - let msg = "Invalid pallet::call, expect no trait ident as in \ + let msg = "Invalid pallet::call, expected no trait ident as in \ `impl<..> Pallet<..> { .. }`"; return Err(syn::Error::new(for_.span(), msg)) } diff --git a/frame/support/procedural/src/pallet/parse/genesis_build.rs b/frame/support/procedural/src/pallet/parse/genesis_build.rs index c3f3c59bcabea..79c64b8a1a9c9 100644 --- a/frame/support/procedural/src/pallet/parse/genesis_build.rs +++ b/frame/support/procedural/src/pallet/parse/genesis_build.rs @@ -33,13 +33,13 @@ impl GenesisBuildDef { let item = if let syn::Item::Impl(item) = item { item } else { - let msg = "Invalid pallet::genesis_build, expect item impl"; + let msg = "Invalid pallet::genesis_build, expected item impl"; return Err(syn::Error::new(item.span(), msg)); }; let item_trait = &item.trait_.as_ref() .ok_or_else(|| { - let msg = "Invalid pallet::genesis_build, expect impl<..> GenesisBuild<..> \ + let msg = "Invalid pallet::genesis_build, expected impl<..> GenesisBuild<..> \ for GenesisConfig<..>"; syn::Error::new(item.span(), msg) })?.1; diff --git a/frame/support/procedural/src/pallet/parse/genesis_config.rs b/frame/support/procedural/src/pallet/parse/genesis_config.rs index 60a979ecfc937..ff42d5d437011 100644 --- a/frame/support/procedural/src/pallet/parse/genesis_config.rs +++ b/frame/support/procedural/src/pallet/parse/genesis_config.rs @@ -45,7 +45,7 @@ impl GenesisConfigDef { syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics), syn::Item::Type(item) => (&item.vis, &item.ident, &item.generics), _ => { - let msg = "Invalid pallet::genesis_config, expect enum or struct or type"; + let msg = "Invalid pallet::genesis_config, expected enum or struct or type"; return Err(syn::Error::new(item.span(), msg)); }, }; diff --git a/frame/support/procedural/src/pallet/parse/hooks.rs b/frame/support/procedural/src/pallet/parse/hooks.rs index ab3d31a327a49..93061069f8c30 100644 --- a/frame/support/procedural/src/pallet/parse/hooks.rs +++ b/frame/support/procedural/src/pallet/parse/hooks.rs @@ -33,7 +33,7 @@ impl HooksDef { let item = if let syn::Item::Impl(item) = item { item } else { - let msg = "Invalid pallet::hooks, expect item impl"; + let msg = "Invalid pallet::hooks, expected item impl"; return Err(syn::Error::new(item.span(), msg)); }; @@ -43,7 +43,7 @@ impl HooksDef { let item_trait = &item.trait_.as_ref() .ok_or_else(|| { - let msg = "Invalid pallet::hooks, expect impl<..> Hooks \ + let msg = "Invalid pallet::hooks, expected impl<..> Hooks \ for Pallet<..>"; syn::Error::new(item.span(), msg) })?.1; @@ -52,7 +52,7 @@ impl HooksDef { || item_trait.segments[0].ident != "Hooks" { let msg = format!( - "Invalid pallet::hooks, expect trait to be `Hooks` found `{}`\ + "Invalid pallet::hooks, expected trait to be `Hooks` found `{}`\ , you can import from `frame_support::pallet_prelude`", quote::quote!(#item_trait) ); diff --git a/frame/support/procedural/src/pallet/parse/inherent.rs b/frame/support/procedural/src/pallet/parse/inherent.rs index b97d0fd8f2f2b..b4dfd71d8a509 100644 --- a/frame/support/procedural/src/pallet/parse/inherent.rs +++ b/frame/support/procedural/src/pallet/parse/inherent.rs @@ -31,21 +31,22 @@ impl InherentDef { let item = if let syn::Item::Impl(item) = item { item } else { - return Err(syn::Error::new(item.span(), "Invalid pallet::inherent, expect item impl")); + let msg = "Invalid pallet::inherent, expected item impl"; + return Err(syn::Error::new(item.span(), msg)); }; if item.trait_.is_none() { - let msg = "Invalid pallet::inherent, expect impl<..> ProvideInherent for Pallet<..>"; + let msg = "Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..>"; return Err(syn::Error::new(item.span(), msg)); } if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() { if last.ident != "ProvideInherent" { - let msg = "Invalid pallet::inherent, expect trait ProvideInherent"; + let msg = "Invalid pallet::inherent, expected trait ProvideInherent"; return Err(syn::Error::new(last.span(), msg)); } } else { - let msg = "Invalid pallet::inherent, expect impl<..> ProvideInherent for Pallet<..>"; + let msg = "Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..>"; return Err(syn::Error::new(item.span(), msg)); } diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index b9db722b67b77..1872e30ffd87a 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -69,7 +69,7 @@ impl Def { let item_span = item.span().clone(); let items = &mut item.content.as_mut() .ok_or_else(|| { - let msg = "Invalid pallet definition, expect mod to be inlined."; + let msg = "Invalid pallet definition, expected mod to be inlined."; syn::Error::new(item_span, msg) })?.1; diff --git a/frame/support/procedural/src/pallet/parse/origin.rs b/frame/support/procedural/src/pallet/parse/origin.rs index 1f5d535060e73..00b64c20bc451 100644 --- a/frame/support/procedural/src/pallet/parse/origin.rs +++ b/frame/support/procedural/src/pallet/parse/origin.rs @@ -41,7 +41,7 @@ impl OriginDef { syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics), syn::Item::Type(item) => (&item.vis, &item.ident, &item.generics), _ => { - let msg = "Invalid pallet::origin, expect enum or struct or type"; + let msg = "Invalid pallet::origin, expected enum or struct or type"; return Err(syn::Error::new(item.span(), msg)); }, }; diff --git a/frame/support/procedural/src/pallet/parse/pallet_struct.rs b/frame/support/procedural/src/pallet/parse/pallet_struct.rs index e2fe3b6e69d4e..140355070df8c 100644 --- a/frame/support/procedural/src/pallet/parse/pallet_struct.rs +++ b/frame/support/procedural/src/pallet/parse/pallet_struct.rs @@ -68,7 +68,7 @@ impl PalletStructDef { let item = if let syn::Item::Struct(item) = item { item } else { - let msg = "Invalid pallet::pallet, expect struct definition"; + let msg = "Invalid pallet::pallet, expected struct definition"; return Err(syn::Error::new(item.span(), msg)); }; diff --git a/frame/support/procedural/src/pallet/parse/storage.rs b/frame/support/procedural/src/pallet/parse/storage.rs index ba1b24e76362a..b7ffe3da751fb 100644 --- a/frame/support/procedural/src/pallet/parse/storage.rs +++ b/frame/support/procedural/src/pallet/parse/storage.rs @@ -100,13 +100,13 @@ fn retrieve_arg( if arg_pos < args.args.len() { Ok(args.args[arg_pos].clone()) } else { - let msg = format!("pallet::storage unexpected number of generic argument, expect at \ + let msg = format!("pallet::storage unexpected number of generic argument, expected at \ least {} args, found {}", arg_pos + 1, args.args.len()); Err(syn::Error::new(args.span(), msg)) } } else { - let msg = format!("pallet::storage unexpected number of generic argument, expect at least \ - {} args, found none", arg_pos + 1); + let msg = format!("pallet::storage unexpected number of generic argument, expected at \ + least {} args, found none", arg_pos + 1); Err(syn::Error::new(segment.span(), msg)) } } @@ -116,7 +116,7 @@ impl StorageDef { let item = if let syn::Item::Type(item) = item { item } else { - return Err(syn::Error::new(item.span(), "Invalid pallet::storage, expect item type")); + return Err(syn::Error::new(item.span(), "Invalid pallet::storage, expected item type")); }; let mut attrs: Vec = helper::take_item_attrs(&mut item.attrs)?; @@ -135,12 +135,12 @@ impl StorageDef { let typ = if let syn::Type::Path(typ) = &*item.ty { typ } else { - let msg = "Invalid pallet::storage, expect type path"; + let msg = "Invalid pallet::storage, expected type path"; return Err(syn::Error::new(item.ty.span(), msg)); }; if typ.path.segments.len() != 1 { - let msg = "Invalid pallet::storage, expect type path with one segment"; + let msg = "Invalid pallet::storage, expected type path with one segment"; return Err(syn::Error::new(item.ty.span(), msg)); } @@ -169,7 +169,7 @@ impl StorageDef { } found @ _ => { let msg = format!( - "Invalid pallet::storage, expect ident: `StorageValue` or \ + "Invalid pallet::storage, expected ident: `StorageValue` or \ `StorageMap` or `StorageDoubleMap` in order to expand metadata, found \ `{}`", found, diff --git a/frame/support/procedural/src/pallet/parse/type_value.rs b/frame/support/procedural/src/pallet/parse/type_value.rs index fd9ef197ac5a3..0313c76c3ec8e 100644 --- a/frame/support/procedural/src/pallet/parse/type_value.rs +++ b/frame/support/procedural/src/pallet/parse/type_value.rs @@ -43,7 +43,8 @@ impl TypeValueDef { let item = if let syn::Item::Fn(item) = item { item } else { - return Err(syn::Error::new(item.span(), "Invalid pallet::type_value, expect item fn")); + let msg = "Invalid pallet::type_value, expected item fn"; + return Err(syn::Error::new(item.span(), msg)); }; @@ -73,7 +74,7 @@ impl TypeValueDef { let type_ = match item.sig.output.clone() { syn::ReturnType::Type(_, type_) => type_, syn::ReturnType::Default => { - let msg = "Invalid pallet::type_value, expect return type"; + let msg = "Invalid pallet::type_value, expected return type"; return Err(syn::Error::new(item.sig.span(), msg)); }, }; diff --git a/frame/support/procedural/src/pallet/parse/validate_unsigned.rs b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs index a94c9b5fdd920..3c460249811f9 100644 --- a/frame/support/procedural/src/pallet/parse/validate_unsigned.rs +++ b/frame/support/procedural/src/pallet/parse/validate_unsigned.rs @@ -31,23 +31,23 @@ impl ValidateUnsignedDef { let item = if let syn::Item::Impl(item) = item { item } else { - let msg = "Invalid pallet::validate_unsigned, expect item impl"; + let msg = "Invalid pallet::validate_unsigned, expected item impl"; return Err(syn::Error::new(item.span(), msg)); }; if item.trait_.is_none() { - let msg = "Invalid pallet::validate_unsigned, expect impl<..> ValidateUnsigned for \ + let msg = "Invalid pallet::validate_unsigned, expected impl<..> ValidateUnsigned for \ Pallet<..>"; return Err(syn::Error::new(item.span(), msg)); } if let Some(last) = item.trait_.as_ref().unwrap().1.segments.last() { if last.ident != "ValidateUnsigned" { - let msg = "Invalid pallet::validate_unsigned, expect trait ValidateUnsigned"; + let msg = "Invalid pallet::validate_unsigned, expected trait ValidateUnsigned"; return Err(syn::Error::new(last.span(), msg)); } } else { - let msg = "Invalid pallet::validate_unsigned, expect impl<..> ValidateUnsigned for \ + let msg = "Invalid pallet::validate_unsigned, expected impl<..> ValidateUnsigned for \ Pallet<..>"; return Err(syn::Error::new(item.span(), msg)); } From c96e1cfe4b63fd8b3fbf5c4ee83758abef43e403 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 30 Nov 2020 14:47:25 +0100 Subject: [PATCH 21/36] remove unsupported genesis config type alias --- frame/support/procedural/src/pallet/parse/genesis_config.rs | 4 +--- frame/support/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frame/support/procedural/src/pallet/parse/genesis_config.rs b/frame/support/procedural/src/pallet/parse/genesis_config.rs index ff42d5d437011..21832d8feb33b 100644 --- a/frame/support/procedural/src/pallet/parse/genesis_config.rs +++ b/frame/support/procedural/src/pallet/parse/genesis_config.rs @@ -21,7 +21,6 @@ use super::helper; /// Definition for pallet genesis config type. /// /// Either: -/// * `type GenesisConfig` /// * `struct GenesisConfig` /// * `enum GenesisConfig` pub struct GenesisConfigDef { @@ -43,9 +42,8 @@ impl GenesisConfigDef { let (vis, ident, generics) = match &item { syn::Item::Enum(item) => (&item.vis, &item.ident, &item.generics), syn::Item::Struct(item) => (&item.vis, &item.ident, &item.generics), - syn::Item::Type(item) => (&item.vis, &item.ident, &item.generics), _ => { - let msg = "Invalid pallet::genesis_config, expected enum or struct or type"; + let msg = "Invalid pallet::genesis_config, expected enum or struct"; return Err(syn::Error::new(item.span(), msg)); }, }; diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 6b0afaae2a9f7..f041a7c732688 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1410,7 +1410,7 @@ pub mod pallet_prelude { /// /// Allow to define the genesis configuration of the pallet. /// -/// Item is defined as either a type alias or an enum or a struct. +/// Item is defined as either an enum or a struct. /// It needs to be public and implement trait GenesisBuild with `#[pallet::genesis_build]`. /// The type generics is constrained to be either none, or `T` or `T: Config`. /// From 78789d696f123fb719b568d8d17c07e95952b431 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 30 Nov 2020 17:53:15 +0100 Subject: [PATCH 22/36] merge fixup --- frame/support/procedural/src/pallet/expand/type_value.rs | 2 +- frame/support/procedural/src/pallet/parse/mod.rs | 2 +- frame/support/procedural/src/storage/print_pallet_upgrade.rs | 2 +- frame/support/test/Cargo.toml | 2 +- frame/support/test/src/lib.rs | 4 ---- frame/system/src/extensions/check_weight.rs | 2 +- 6 files changed, 5 insertions(+), 9 deletions(-) diff --git a/frame/support/procedural/src/pallet/expand/type_value.rs b/frame/support/procedural/src/pallet/expand/type_value.rs index 9b3e9e351c4bf..3de3be8fcf272 100644 --- a/frame/support/procedural/src/pallet/expand/type_value.rs +++ b/frame/support/procedural/src/pallet/expand/type_value.rs @@ -29,7 +29,7 @@ pub fn expand_type_values(def: &mut Def) -> proc_macro2::TokenStream { let item = &mut def.item.content.as_mut().expect("Checked by def").1[type_value.index]; let span = item.span(); *item = syn::Item::Verbatim(Default::default()); - + let vis = &type_value.vis; let ident = &type_value.ident; let block = &type_value.block; diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index 1872e30ffd87a..f97138e62c7d0 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -197,7 +197,7 @@ impl Def { _ => Ok(()) } } - + /// Check that usage of trait `Config` is consistent with the definition, i.e. it is used with /// instance iff it is defined with instance. fn check_instance_usage(&self) -> syn::Result<()> { diff --git a/frame/support/procedural/src/storage/print_pallet_upgrade.rs b/frame/support/procedural/src/storage/print_pallet_upgrade.rs index f8a70f244b1dc..66da5fd01b578 100644 --- a/frame/support/procedural/src/storage/print_pallet_upgrade.rs +++ b/frame/support/procedural/src/storage/print_pallet_upgrade.rs @@ -309,7 +309,7 @@ pub mod pallet {{ use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; use super::*; - + #[pallet::config] pub trait Config{config_gen}: frame_system::Config // TODO_MAYBE_ADDITIONAL_BOUNDS_AND_WHERE_CLAUSE diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index d067b41828031..6d8064102c4dd 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -24,8 +24,8 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../../primiti trybuild = "1.0.33" pretty_assertions = "0.6.1" rustversion = "1.0.0" -frame-system = { version = "2.0.0", default-features = false, path = "../../system" } frame-metadata = { version = "12.0.0", default-features = false, path = "../../metadata" } +frame-system = { version = "2.0.0", default-features = false, path = "../../system" } [features] default = ["std"] diff --git a/frame/support/test/src/lib.rs b/frame/support/test/src/lib.rs index 8d26970bcabab..2baf698f1e529 100644 --- a/frame/support/test/src/lib.rs +++ b/frame/support/test/src/lib.rs @@ -25,10 +25,6 @@ #[cfg(test)] mod pallet_version; -/// Kind of alias for `Config` trait. Deprecated as `Trait` is renamed `Config`. -pub trait Trait: Config {} -impl Trait for T {} - /// The configuration trait pub trait Config: 'static { /// The runtime origin type. diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs index 8e749fda394ce..6dfff865d45bb 100644 --- a/frame/system/src/extensions/check_weight.rs +++ b/frame/system/src/extensions/check_weight.rs @@ -309,7 +309,7 @@ impl sp_std::fmt::Debug for CheckWeight { #[cfg(test)] mod tests { use super::*; - use crate::{BlockWeight, AllExtrinsicsLen, Config}; + use crate::{BlockWeight, AllExtrinsicsLen}; use crate::mock::{Test, CALL, new_test_ext, System}; use sp_std::marker::PhantomData; use frame_support::{assert_ok, assert_noop}; From 96845d8b56a5625d3329d2d655e55f8e020d59d1 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 2 Dec 2020 17:47:08 +0100 Subject: [PATCH 23/36] fix ui tests --- .../test/tests/pallet_ui/call_invalid_origin_type.stderr | 2 +- frame/support/test/tests/pallet_ui/error_wrong_item.stderr | 2 +- frame/support/test/tests/pallet_ui/event_wrong_item.stderr | 2 +- frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr | 2 +- frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr | 2 +- frame/support/test/tests/pallet_ui/mod_not_inlined.stderr | 2 +- .../test/tests/pallet_ui/storage_not_storage_type.stderr | 2 +- .../test/tests/pallet_ui/storage_value_no_generic.stderr | 2 +- frame/support/test/tests/pallet_ui/storage_wrong_item.stderr | 2 +- frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr | 2 +- .../support/test/tests/pallet_ui/type_value_invalid_item.stderr | 2 +- frame/support/test/tests/pallet_ui/type_value_no_return.stderr | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr index 13083a49be342..855c59fd8d57d 100644 --- a/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr +++ b/frame/support/test/tests/pallet_ui/call_invalid_origin_type.stderr @@ -1,4 +1,4 @@ -error: Invalid type: expect `OriginFor` +error: Invalid type: expected `OriginFor` --> $DIR/call_invalid_origin_type.rs:17:18 | 17 | fn foo(origin: u8) {} diff --git a/frame/support/test/tests/pallet_ui/error_wrong_item.stderr b/frame/support/test/tests/pallet_ui/error_wrong_item.stderr index e028616acc95f..8c0496782fb16 100644 --- a/frame/support/test/tests/pallet_ui/error_wrong_item.stderr +++ b/frame/support/test/tests/pallet_ui/error_wrong_item.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::error, expect item enum +error: Invalid pallet::error, expected item enum --> $DIR/error_wrong_item.rs:19:2 | 19 | pub struct Foo; diff --git a/frame/support/test/tests/pallet_ui/event_wrong_item.stderr b/frame/support/test/tests/pallet_ui/event_wrong_item.stderr index d3ddb6cb0fd4d..21eb0ed35e936 100644 --- a/frame/support/test/tests/pallet_ui/event_wrong_item.stderr +++ b/frame/support/test/tests/pallet_ui/event_wrong_item.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::event, expect item enum +error: Invalid pallet::event, expected item enum --> $DIR/event_wrong_item.rs:19:2 | 19 | pub struct Foo; diff --git a/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr b/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr index 82c030ac64417..dd2e65588f56b 100644 --- a/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr +++ b/frame/support/test/tests/pallet_ui/genesis_wrong_name.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::genesis_build, expect impl<..> GenesisBuild<..> for GenesisConfig<..> +error: Invalid pallet::genesis_build, expected impl<..> GenesisBuild<..> for GenesisConfig<..> --> $DIR/genesis_wrong_name.rs:19:2 | 19 | impl Foo {} diff --git a/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr b/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr index 4dc1193b74fe7..b62b1234bdeb0 100644 --- a/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr +++ b/frame/support/test/tests/pallet_ui/inherent_invalid_item.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::inherent, expect impl<..> ProvideInherent for Pallet<..> +error: Invalid pallet::inherent, expected impl<..> ProvideInherent for Pallet<..> --> $DIR/inherent_invalid_item.rs:19:2 | 19 | impl Foo {} diff --git a/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr b/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr index 1acff2e678ece..9ad93939d8c00 100644 --- a/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr +++ b/frame/support/test/tests/pallet_ui/mod_not_inlined.stderr @@ -6,7 +6,7 @@ error[E0658]: non-inline modules in proc macro input are unstable | = note: see issue #54727 for more information -error: Invalid pallet definition, expect mod to be inlined. +error: Invalid pallet definition, expected mod to be inlined. --> $DIR/mod_not_inlined.rs:2:1 | 2 | mod foo; diff --git a/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr b/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr index 9f190ae1dbfaa..ec4bde22ac7a8 100644 --- a/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr +++ b/frame/support/test/tests/pallet_ui/storage_not_storage_type.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::storage, expect ident: `StorageValue` or `StorageMap` or `StorageDoubleMap` in order to expand metadata, found `u8` +error: Invalid pallet::storage, expected ident: `StorageValue` or `StorageMap` or `StorageDoubleMap` in order to expand metadata, found `u8` --> $DIR/storage_not_storage_type.rs:19:16 | 19 | type Foo = u8; diff --git a/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr b/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr index 63262690d915e..894f7095b2b5a 100644 --- a/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr +++ b/frame/support/test/tests/pallet_ui/storage_value_no_generic.stderr @@ -1,4 +1,4 @@ -error: pallet::storage unexpected number of generic argument, expect at least 2 args, found none +error: pallet::storage unexpected number of generic argument, expected at least 2 args, found none --> $DIR/storage_value_no_generic.rs:19:16 | 19 | type Foo = StorageValue; diff --git a/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr b/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr index 3219665249405..8cc180b5bfe49 100644 --- a/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr +++ b/frame/support/test/tests/pallet_ui/storage_wrong_item.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::storage, expect item type +error: Invalid pallet::storage, expected item type --> $DIR/storage_wrong_item.rs:19:2 | 19 | impl Foo {} diff --git a/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr b/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr index ddf35a802e516..c38f43d28eb33 100644 --- a/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr +++ b/frame/support/test/tests/pallet_ui/trait_no_supertrait.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::trait, expect explicit `frame_system::Config` as supertrait, found none. (try `pub trait Config: frame_system::Config { ...` or `pub trait Config: frame_system::Config { ...`). To disable this check, use `#[pallet::disable_frame_system_supertrait_check]` +error: Invalid pallet::trait, expected explicit `frame_system::Config` as supertrait, found none. (try `pub trait Config: frame_system::Config { ...` or `pub trait Config: frame_system::Config { ...`). To disable this check, use `#[pallet::disable_frame_system_supertrait_check]` --> $DIR/trait_no_supertrait.rs:7:2 | 7 | pub trait Config { diff --git a/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr b/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr index 8f2eef7af1ddf..5ae618df8837c 100644 --- a/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr +++ b/frame/support/test/tests/pallet_ui/type_value_invalid_item.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::type_value, expect item fn +error: Invalid pallet::type_value, expected item fn --> $DIR/type_value_invalid_item.rs:18:24 | 18 | #[pallet::type_value] struct Foo; diff --git a/frame/support/test/tests/pallet_ui/type_value_no_return.stderr b/frame/support/test/tests/pallet_ui/type_value_no_return.stderr index 2410e6a7b7d85..65ac0243f9f64 100644 --- a/frame/support/test/tests/pallet_ui/type_value_no_return.stderr +++ b/frame/support/test/tests/pallet_ui/type_value_no_return.stderr @@ -1,4 +1,4 @@ -error: Invalid pallet::type_value, expect return type +error: Invalid pallet::type_value, expected return type --> $DIR/type_value_no_return.rs:18:24 | 18 | #[pallet::type_value] fn Foo() {} From 1762c4783271e35faf88633c9be2c3e2ea9fc30f Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 2 Dec 2020 17:50:00 +0100 Subject: [PATCH 24/36] additional doc --- frame/support/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index b0659b8ab0221..1ebf81a59c3a3 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1132,6 +1132,9 @@ pub mod pallet_prelude { /// More precisely the store trait contains an associated type for each storage. It is implemented /// for `Pallet` allowing to access the storage from pallet struct. /// +/// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using +/// `::Foo`. +/// /// ### Macro expansion: /// /// The macro add this attribute to the struct definition: From cf7ae7d0c28e561b0ba3e4a36fd2b518e0d7adbc Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 3 Dec 2020 12:46:55 +0100 Subject: [PATCH 25/36] implement StorageInstance with new syntax --- .../support/procedural/src/pallet/expand/storage.rs | 9 +++++++-- frame/support/src/lib.rs | 13 +++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/frame/support/procedural/src/pallet/expand/storage.rs b/frame/support/procedural/src/pallet/expand/storage.rs index 2d8956324f467..a8b6b2f0d7baf 100644 --- a/frame/support/procedural/src/pallet/expand/storage.rs +++ b/frame/support/procedural/src/pallet/expand/storage.rs @@ -224,8 +224,13 @@ pub fn expand_storages(def: &mut Def) -> proc_macro2::TokenStream { for #prefix_struct_ident<#type_use_gen> #config_where_clause { - type PalletInfo = ::PalletInfo; - type Pallet = Pallet<#type_use_gen>; + fn pallet_prefix() -> &'static str { + < + ::PalletInfo + as #frame_support::traits::PalletInfo + >::name::>() + .expect("Every active pallet has a name in the runtime; qed") + } const STORAGE_PREFIX: &'static str = #prefix_struct_const; } ) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 1ebf81a59c3a3..108264762f89c 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1346,10 +1346,10 @@ pub mod pallet_prelude { /// of `StorageValue`, `StorageMap` or `StorageDoubleMap` (defined in frame_support). /// Their first generic must be `_` as it is written by the macro itself. /// -/// The Prefix generic written by the macro is generated using PalletInfo::name and the name of the -/// storage type. -/// E.g. if runtime name the pallet MyExample the storage `type Foo = ...` use -/// prefixes: `Twox128(b"MyExample") ++ Twox128(b"Foo")`. +/// The Prefix generic written by the macro is generated using `PalletInfo::name::>()` +/// and the name of the storage type. +/// E.g. if runtime names the pallet "MyExample" then the storage `type Foo = ...` use the +/// prefix: `Twox128(b"MyExample") ++ Twox128(b"Foo")`. /// /// The optional attribute `#[pallet::getter(fn $my_getter_fn_name)]` allow to define a /// getter function on `Pallet`. @@ -1368,8 +1368,9 @@ pub mod pallet_prelude { /// ### Macro expansion /// /// For each storage the macro generate a struct named -/// `_GeneratedPrefixForStorage$NameOfStorage`, implements StorageInstance on it using pallet -/// names and storage name. and use it as first generic of the aliased type. +/// `_GeneratedPrefixForStorage$NameOfStorage`, implements `StorageInstance` on it using pallet +/// name and storage name. And use it as first generic of the aliased type. +/// /// /// The macro implement the function `storage_metadata` on `Pallet` implementing the metadata for /// storages. From 88e699580ae1b1b0a665d9624af9f227f6bb8425 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 3 Dec 2020 12:52:38 +0100 Subject: [PATCH 26/36] fix line width --- .../procedural/src/pallet/parse/event.rs | 4 +++- frame/support/src/lib.rs | 3 ++- frame/support/test/tests/pallet.rs | 4 +++- .../test/tests/pallet_compatibility.rs | 8 ++++++-- .../tests/pallet_compatibility_instance.rs | 20 ++++++++++++++----- frame/support/test/tests/pallet_instance.rs | 9 +++++++-- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs index cf5fe8f9bcee3..3ffa747183a1c 100644 --- a/frame/support/procedural/src/pallet/parse/event.rs +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -109,7 +109,9 @@ impl PalletEventAttr { } /// Parse for syntax `$Type = "$SomeString"`. -fn parse_event_metadata_element(input: syn::parse::ParseStream) -> syn::Result<(syn::Type, String)> { +fn parse_event_metadata_element( + input: syn::parse::ParseStream +) -> syn::Result<(syn::Type, String)> { let typ = input.parse::()?; input.parse::()?; let ident = input.parse::()?; diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 108264762f89c..a8f2260caa127 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1340,7 +1340,8 @@ pub mod pallet_prelude { /// ```ignore /// #[pallet::storage] /// #[pallet::getter(fn $getter_name)] // optional -/// $vis type $StorageName<$some_generic> $optional_where_clause = $StorageType<_, $some_generics, ...>; +/// $vis type $StorageName<$some_generic> $optional_where_clause +/// = $StorageType<_, $some_generics, ...>; /// ``` /// I.e. it must be a type alias, with generics: `T` or `T: Config`, aliased type must be one /// of `StorageValue`, `StorageMap` or `StorageDoubleMap` (defined in frame_support). diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 500b3ef0cba0b..a0f151a005045 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -187,7 +187,9 @@ pub mod pallet { pub type Value = StorageValue<_, u32>; #[pallet::type_value] - pub fn MyDefault() -> u16 where T::AccountId: From + From + SomeAssociation1 { + pub fn MyDefault() -> u16 + where T::AccountId: From + From + SomeAssociation1 + { T::AccountId::from(SomeType7); // Test where clause works 4u16 } diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs index fe4d04a7d42d8..a4df0f6262093 100644 --- a/frame/support/test/tests/pallet_compatibility.rs +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -289,12 +289,16 @@ mod test { #[test] fn types() { assert_eq!( - pallet_old::Event::::decode(&mut &pallet::Event::::Dummy(10).encode()[..]).unwrap(), + pallet_old::Event::::decode( + &mut &pallet::Event::::Dummy(10).encode()[..] + ).unwrap(), pallet_old::Event::::Dummy(10), ); assert_eq!( - pallet_old::Call::::decode(&mut &pallet::Call::::set_dummy(10).encode()[..]).unwrap(), + pallet_old::Call::::decode( + &mut &pallet::Call::::set_dummy(10).encode()[..] + ).unwrap(), pallet_old::Call::::set_dummy(10), ); } diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs index 5c51d5ed66c78..68bdfa3cfc39a 100644 --- a/frame/support/test/tests/pallet_compatibility_instance.rs +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -35,7 +35,8 @@ mod pallet_old { Dummy get(fn dummy) config(): Option; Bar get(fn bar) config(): map hasher(blake2_128_concat) T::AccountId => T::Balance; Foo get(fn foo) config(): T::Balance = 3.into(); - Double get(fn double): double_map hasher(blake2_128_concat) u32, hasher(twox_64_concat) u64 => u16; + Double get(fn double): + double_map hasher(blake2_128_concat) u32, hasher(twox_64_concat) u64 => u16; } } @@ -47,7 +48,9 @@ mod pallet_old { ); decl_module! { - pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin { + pub struct Module, I: Instance = DefaultInstance> for enum Call + where origin: T::Origin + { type Error = Error; fn deposit_event() = default; const SomeConst: T::Balance = T::SomeConst::get(); @@ -112,7 +115,10 @@ pub mod pallet { #[pallet::call] impl, I: 'static> Pallet { #[pallet::weight(>::into(new_value.clone()))] - fn set_dummy(origin: OriginFor, #[pallet::compact] new_value: T::Balance) -> DispatchResultWithPostInfo { + fn set_dummy( + origin: OriginFor, + #[pallet::compact] new_value: T::Balance + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; >::put(&new_value); @@ -300,12 +306,16 @@ mod test { #[test] fn types() { assert_eq!( - pallet_old::Event::::decode(&mut &pallet::Event::::Dummy(10).encode()[..]).unwrap(), + pallet_old::Event::::decode( + &mut &pallet::Event::::Dummy(10).encode()[..] + ).unwrap(), pallet_old::Event::::Dummy(10), ); assert_eq!( - pallet_old::Call::::decode(&mut &pallet::Call::::set_dummy(10).encode()[..]).unwrap(), + pallet_old::Call::::decode( + &mut &pallet::Call::::set_dummy(10).encode()[..] + ).unwrap(), pallet_old::Call::::set_dummy(10), ); } diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index 51fef63da2a0b..3943acd294e9d 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -88,7 +88,10 @@ pub mod pallet { /// Doc comment put in metadata #[pallet::weight(1)] #[frame_support::transactional] - fn foo_transactional(origin: OriginFor, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo { + fn foo_transactional( + origin: OriginFor, + #[pallet::compact] _foo: u32 + ) -> DispatchResultWithPostInfo { let _ = origin; Ok(().into()) } @@ -239,7 +242,9 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Event}, Example: pallet::{Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, - Instance1Example: pallet::::{Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + Instance1Example: pallet::::{ + Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned + }, } ); From 3a296837d479f4eed27789531bf64512392db626 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Fri, 4 Dec 2020 14:01:49 +0100 Subject: [PATCH 27/36] fix doc: because pallet doc goes below reexport doc --- frame/support/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index a8f2260caa127..145fd8d78cd35 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -2015,4 +2015,5 @@ pub mod pallet_prelude { /// } /// ``` /// * use the newest nightly possible. +/// pub use frame_support_procedural::pallet; From 888d121383bc7cd6524f71ea0dd49c13b5f4925e Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Wed, 9 Dec 2020 15:42:22 +0100 Subject: [PATCH 28/36] Update frame/support/procedural/src/pallet/parse/event.rs Co-authored-by: Andrew Jones --- frame/support/procedural/src/pallet/parse/event.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs index 3ffa747183a1c..e45549bda72cb 100644 --- a/frame/support/procedural/src/pallet/parse/event.rs +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -69,7 +69,7 @@ impl EventDef { pub fn event_impl_gen(&self) -> proc_macro2::TokenStream { if self.is_generic { if self.has_instance { - quote::quote!(T: Config, I) + quote::quote!(T: Config, I: 'static) } else { quote::quote!(T: Config) } From 52a654ffc80ae271625a537b6b3c8afd40f461c1 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Wed, 23 Dec 2020 10:53:26 +0100 Subject: [PATCH 29/36] Update frame/system/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- 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 f04c20c5b6492..248589fc19d98 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1362,9 +1362,7 @@ impl Lookup for ChainContext { } pub mod pallet_prelude { - pub use crate::ensure_signed; - pub use crate::ensure_none; - pub use crate::ensure_root; + pub use crate::{ensure_signed, ensure_none, ensure_root}; pub type OriginFor = ::Origin; pub type BlockNumberFor = ::BlockNumber; } From 03c7fbffbc64fd28409905b8731c61155b8663f1 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Wed, 23 Dec 2020 10:58:22 +0100 Subject: [PATCH 30/36] Update frame/support/test/tests/pallet_ui.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/support/test/tests/pallet_ui.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/support/test/tests/pallet_ui.rs b/frame/support/test/tests/pallet_ui.rs index 80a28ee826940..d323526622a4f 100644 --- a/frame/support/test/tests/pallet_ui.rs +++ b/frame/support/test/tests/pallet_ui.rs @@ -19,7 +19,7 @@ #[test] fn pallet_ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. - std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + std::env::set_var("SKIP_WASM_BUILD", "1"); let t = trybuild::TestCases::new(); t.compile_fail("tests/pallet_ui/*.rs"); From 3f23d3ca35235888d065255d02d3cfbbc8c980c6 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 23 Dec 2020 14:18:40 +0100 Subject: [PATCH 31/36] improve doc as suggested --- frame/support/src/instances.rs | 14 ++++++++++---- frame/support/src/lib.rs | 20 ++++++++------------ frame/system/src/lib.rs | 5 +++++ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/frame/support/src/instances.rs b/frame/support/src/instances.rs index fd619103765c3..ee38a6a403e15 100644 --- a/frame/support/src/instances.rs +++ b/frame/support/src/instances.rs @@ -15,15 +15,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Some instance placeholder to be used in `pallet` attribute macro. +//! Some instance placeholder to be used in [`frame_support::pallet`] attribute macro. //! -//! `pallet` attribute macro do not make use of `I` instance generic for anything, thus the -//! placeholder can reexported from frame-support. -//! This can allow some instantiable pallet to depend on specific instance of another: +//! [`frame_support::pallet`] attribute macro does only requires the instance generic `I` to be +//! static (contrary to `decl_*` macro which requires instance generic to implement +//! [`frame_support::traits::Instance`]). +//! +//! Thus support provides some instance types to be used, This allow some instantiable pallet to +//! depend on specific instance of another: //! ``` //! # mod another_pallet { pub trait Config {} } //! pub trait Config: another_pallet::Config {} //! ``` +//! +//! NOTE: [`frame_support::pallet`] will reexport them inside the module, in order to make them +//! accessible to [`frame_support::construct_runtime`]. /// Instance0 to be used for instantiable pallet define with `pallet` macro. #[derive(Clone, Copy, PartialEq, Eq, crate::RuntimeDebugNoBound)] diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 145fd8d78cd35..ac122f936f937 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1014,26 +1014,22 @@ mod tests { } } -/// prelude to be used alongside pallet macro, for ease of use. +/// Prelude to be used alongside pallet macro, for ease of use. pub mod pallet_prelude { pub use sp_std::marker::PhantomData; - pub use frame_support::traits::{Get, Hooks, IsType, GetPalletVersion, EnsureOrigin}; #[cfg(feature = "std")] pub use frame_support::traits::GenesisBuild; - pub use frame_support::dispatch::{DispatchResultWithPostInfo, Parameter, DispatchError}; - pub use frame_support::storage::types::{ - StorageValue, StorageMap, StorageDoubleMap, ValueQuery, OptionQuery, - }; pub use frame_support::{ - EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, DebugNoBound, CloneNoBound + EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, DebugNoBound, CloneNoBound, Twox256, + Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, debug, ensure, + RuntimeDebug, storage, + traits::{Get, Hooks, IsType, GetPalletVersion, EnsureOrigin}, + dispatch::{DispatchResultWithPostInfo, Parameter, DispatchError}, + weights::{DispatchClass, Pays, Weight}, + storage::types::{StorageValue, StorageMap, StorageDoubleMap, ValueQuery, OptionQuery}, }; pub use codec::{Encode, Decode}; pub use sp_inherents::{InherentData, InherentIdentifier, ProvideInherent}; - pub use crate::weights::{DispatchClass, Pays, Weight}; - pub use crate::{ - Twox256, Twox128, Blake2_256, Blake2_128, Identity, Twox64Concat, Blake2_128Concat, - debug, ensure, RuntimeDebug, storage - }; pub use sp_runtime::{ traits::{MaybeSerializeDeserialize, Member, ValidateUnsigned}, transaction_validity::{ diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 248589fc19d98..23e53a853deaa 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1361,8 +1361,13 @@ impl Lookup for ChainContext { } } +/// 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 d9d48c705a4f6557057c00699aada002e27c1b07 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 23 Dec 2020 14:43:12 +0100 Subject: [PATCH 32/36] revert construct_runtime Pallet part. This revert the changes on construct_runtime. Now construct_runtime is unchanged and instead pallet macro create a type alias `type Module<..> = Pallet<..>` to be used by construct_runtime --- .../procedural/src/construct_runtime/mod.rs | 59 ++++++------------- .../procedural/src/construct_runtime/parse.rs | 6 -- frame/support/procedural/src/lib.rs | 3 +- .../src/pallet/expand/pallet_struct.rs | 7 +++ .../procedural/src/pallet/parse/mod.rs | 4 +- frame/support/src/lib.rs | 8 ++- frame/support/test/tests/construct_runtime.rs | 22 +++---- .../construct_runtime_ui/conflicting_index.rs | 4 +- .../conflicting_index.stderr | 4 +- .../conflicting_index_2.rs | 8 +-- .../conflicting_index_2.stderr | 4 +- .../conflicting_module_pallet_parts.rs | 13 ---- .../conflicting_module_pallet_parts.stderr | 11 ---- .../invalid_module_details_keyword.stderr | 2 +- .../invalid_module_entry.stderr | 2 +- ...g_event_generic_on_module_with_instance.rs | 2 +- ...ent_generic_on_module_with_instance.stderr | 2 +- ..._origin_generic_on_module_with_instance.rs | 2 +- ...gin_generic_on_module_with_instance.stderr | 2 +- .../more_than_256_modules.rs | 4 +- .../more_than_256_modules.stderr | 2 +- .../tests/construct_runtime_ui/no_part.rs | 13 ---- .../tests/construct_runtime_ui/no_part.stderr | 5 -- frame/support/test/tests/pallet.rs | 4 +- .../test/tests/pallet_compatibility.rs | 2 +- .../tests/pallet_compatibility_instance.rs | 8 +-- frame/support/test/tests/pallet_instance.rs | 6 +- frame/support/test/tests/pallet_version.rs | 8 +-- 28 files changed, 75 insertions(+), 142 deletions(-) delete mode 100644 frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs delete mode 100644 frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr delete mode 100644 frame/support/test/tests/construct_runtime_ui/no_part.rs delete mode 100644 frame/support/test/tests/construct_runtime_ui/no_part.stderr diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index a93761dd599be..15f0935f38233 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -25,7 +25,6 @@ use proc_macro2::{TokenStream as TokenStream2}; use quote::quote; use syn::{Ident, Result, TypePath}; use std::collections::HashMap; -use syn::spanned::Spanned; /// The fixed name of the system module. const SYSTEM_MODULE_NAME: &str = "System"; @@ -33,9 +32,6 @@ const SYSTEM_MODULE_NAME: &str = "System"; /// The complete definition of a module with the resulting fixed index. #[derive(Debug, Clone)] pub struct Module { - /// A Pallet use either Module (if defined with old macros) or Pallet. - /// This contains the struct to access Pallet information. - pub pallet_or_module: syn::Ident, pub name: Ident, pub index: u8, pub module: Ident, @@ -92,29 +88,7 @@ fn complete_modules(decl: impl Iterator) -> syn::Resul return Err(err); } - // Get if pallet use struct Module or Pallet. - let module_part = module.module_parts.iter().find(|part| part.name() == "Module"); - let pallet_part = module.module_parts.iter().find(|part| part.name() == "Pallet"); - let pallet_or_module = match (module_part, pallet_part) { - (Some(module_part), None) => syn::Ident::new("Module", module_part.keyword.span()), - (None, Some(pallet_part)) => syn::Ident::new("Pallet", pallet_part.keyword.span()), - (None, None) => { - let msg = "Cannot find part `Module` nor `Pallet`, one must be defined"; - return Err(syn::Error::new(module.name.span(), msg)); - }, - (Some(module_part), Some(pallet_part)) => { - let msg = "`Module` cannot be defined when `Pallet` is defined"; - let mut err = syn::Error::new(module_part.keyword.span(), msg); - let msg1 = "`Module` cannot be defined when `Pallet` is defined"; - let err1 = syn::Error::new(pallet_part.keyword.span(), msg1); - err.combine(err1); - return Err(err); - }, - }; - - Ok(Module { - pallet_or_module, name: module.name, index: final_index, module: module.module, @@ -321,22 +295,30 @@ fn decl_runtime_metadata<'a>( extrinsic: &TypePath, ) -> TokenStream2 { let modules_tokens = module_declarations - .map(|module_declaration| { - let parts = module_declaration.module_parts().into_iter() - .map(|part| part.ident()); - + .filter_map(|module_declaration| { + module_declaration.find_part("Module").map(|_| { + let filtered_names: Vec<_> = module_declaration + .module_parts() + .into_iter() + .filter(|part| part.name() != "Module") + .map(|part| part.ident()) + .collect(); + (module_declaration, filtered_names) + }) + }) + .map(|(module_declaration, filtered_names)| { let module = &module_declaration.module; let name = &module_declaration.name; - let instance = module_declaration.instance.as_ref() - .map(|name| quote!(<#name>)); - - let pallet_or_module = &module_declaration.pallet_or_module; + let instance = module_declaration + .instance + .as_ref() + .map(|name| quote!(<#name>)) + .into_iter(); let index = module_declaration.index; quote!( - // Note: impl_runtime_metadata can be given all parts, no need to filter out any part - #module::#pallet_or_module #instance as #name { index #index } with #(#parts)*, + #module::Module #(#instance)* as #name { index #index } with #(#filtered_names)*, ) }); quote!( @@ -468,11 +450,8 @@ fn decl_all_modules<'a>( .iter() .map(|name| quote!(#module::#name)), ); - - let pallet_or_module = &module_declaration.pallet_or_module; - let type_decl = quote!( - pub type #type_name = #module::#pallet_or_module <#(#generics),*>; + pub type #type_name = #module::Module <#(#generics),*>; ); types.extend(type_decl); names.push(&module_declaration.name); diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index 0f39db5081436..4a45044d67f25 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -29,7 +29,6 @@ mod keyword { syn::custom_keyword!(NodeBlock); syn::custom_keyword!(UncheckedExtrinsic); syn::custom_keyword!(Module); - syn::custom_keyword!(Pallet); syn::custom_keyword!(Call); syn::custom_keyword!(Storage); syn::custom_keyword!(Event); @@ -222,7 +221,6 @@ fn parse_module_parts(input: ParseStream) -> Result> { #[derive(Debug, Clone)] pub enum ModulePartKeyword { Module(keyword::Module), - Pallet(keyword::Pallet), Call(keyword::Call), Storage(keyword::Storage), Event(keyword::Event), @@ -238,8 +236,6 @@ impl Parse for ModulePartKeyword { if lookahead.peek(keyword::Module) { Ok(Self::Module(input.parse()?)) - } else if lookahead.peek(keyword::Pallet) { - Ok(Self::Pallet(input.parse()?)) } else if lookahead.peek(keyword::Call) { Ok(Self::Call(input.parse()?)) } else if lookahead.peek(keyword::Storage) { @@ -265,7 +261,6 @@ impl ModulePartKeyword { fn name(&self) -> &'static str { match self { Self::Module(_) => "Module", - Self::Pallet(_) => "Pallet", Self::Call(_) => "Call", Self::Storage(_) => "Storage", Self::Event(_) => "Event", @@ -296,7 +291,6 @@ impl Spanned for ModulePartKeyword { fn span(&self) -> Span { match self { Self::Module(inner) => inner.span(), - Self::Pallet(inner) => inner.span(), Self::Call(inner) => inner.span(), Self::Storage(inner) => inner.span(), Self::Event(inner) => inner.span(), diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 04e87d6eb933d..7adc646c339fe 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -276,8 +276,7 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// /// We provide support for the following module parts in a pallet: /// -/// - `Pallet` or `Module`, mandatory. (one or the other must be provided depending if the pallet -/// uses the pallet attribute macro or old `decl_module` macro. +/// - `Module` /// - `Call` /// - `Storage` /// - `Event` or `Event` (if the event is generic) diff --git a/frame/support/procedural/src/pallet/expand/pallet_struct.rs b/frame/support/procedural/src/pallet/expand/pallet_struct.rs index 53e102013a335..133e49a85d8ed 100644 --- a/frame/support/procedural/src/pallet/expand/pallet_struct.rs +++ b/frame/support/procedural/src/pallet/expand/pallet_struct.rs @@ -21,11 +21,13 @@ use crate::pallet::Def; /// * Implement GetPalletVersion on Pallet /// * Implement OnGenesis on Pallet /// * Implement ModuleErrorMetadata on Pallet +/// * declare Module type alias for construct_runtime pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { let frame_support = &def.frame_support; let frame_system = &def.frame_system; let type_impl_gen = &def.type_impl_generics(); let type_use_gen = &def.type_use_generics(); + let type_decl_gen = &def.type_decl_generics(); let pallet_ident = &def.pallet_struct.pallet; let config_where_clause = &def.config.where_clause; @@ -78,6 +80,11 @@ pub fn expand_pallet_struct(def: &mut Def) -> proc_macro2::TokenStream { quote::quote!( #module_error_metadata + /// Type alias to `Pallet`, to be used by `construct_runtime`. + /// + /// Generated by `pallet` attribute macro. + pub type Module<#type_decl_gen> = #pallet_ident<#type_use_gen>; + // Implement `GetPalletVersion` for `Pallet` impl<#type_impl_gen> #frame_support::traits::GetPalletVersion for #pallet_ident<#type_use_gen> diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index f97138e62c7d0..a07d5fb6324ab 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -276,10 +276,10 @@ impl Def { /// Depending on if pallet is instantiable: /// * either `T` - /// * or `T, I` + /// * or `T, I = ()` pub fn type_decl_generics(&self) -> proc_macro2::TokenStream { if self.config.has_instance { - quote::quote!(T, I) + quote::quote!(T, I = ()) } else { quote::quote!(T) } diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index ac122f936f937..c8279dff9eecb 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1144,9 +1144,11 @@ pub mod pallet_prelude { /// ``` /// /// It implements on pallet: -/// * [`GetPalletVersion`] -/// * [`OnGenesis`]: contains some logic to write pallet version into storage. -/// * [`ModuleErrorMetadata`]: using error declared or no metadata. +/// * [`traits::GetPalletVersion`] +/// * [`traits::OnGenesis`]: contains some logic to write pallet version into storage. +/// * `ModuleErrorMetadata`: using error declared or no metadata. +/// +/// It declare `type Module` type alias for `Pallet`, used by [`construct_runtime`]. /// /// If attribute generate_store then macro create the trait `Store` and implement it on `Pallet`. /// diff --git a/frame/support/test/tests/construct_runtime.rs b/frame/support/test/tests/construct_runtime.rs index 678342533e32c..33bb4a9cc877b 100644 --- a/frame/support/test/tests/construct_runtime.rs +++ b/frame/support/test/tests/construct_runtime.rs @@ -39,9 +39,6 @@ mod module1 { pub trait Config: system::Config {} - // Test that pallet can be used instead of module. - pub type Pallet = Module; - frame_support::decl_module! { pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: ::Origin, system=system @@ -80,9 +77,6 @@ mod module2 { pub trait Config: system::Config {} - // Test that pallet can be used instead of module. - pub type Pallet = Module; - frame_support::decl_module! { pub struct Module for enum Call where origin: ::Origin, system=system @@ -146,15 +140,15 @@ frame_support::construct_runtime!( { System: system::{Module, Call, Event, Origin} = 30, Module1_1: module1::::{Module, Call, Storage, Event, Origin}, - Module2: module2::{Pallet, Call, Storage, Event, Origin}, + Module2: module2::{Module, Call, Storage, Event, Origin}, Module1_2: module1::::{Module, Call, Storage, Event, Origin}, - Module1_3: module1::::{Pallet, Storage} = 6, - Module1_4: module1::::{Pallet, Call} = 3, - Module1_5: module1::::{Pallet, Event}, - Module1_6: module1::::{Pallet, Call, Storage, Event, Origin} = 1, - Module1_7: module1::::{Pallet, Call, Storage, Event, Origin}, - Module1_8: module1::::{Pallet, Call, Storage, Event, Origin} = 12, - Module1_9: module1::::{Pallet, Call, Storage, Event, Origin}, + Module1_3: module1::::{Module, Storage} = 6, + Module1_4: module1::::{Module, Call} = 3, + Module1_5: module1::::{Module, Event}, + Module1_6: module1::::{Module, Call, Storage, Event, Origin} = 1, + Module1_7: module1::::{Module, Call, Storage, Event, Origin}, + Module1_8: module1::::{Module, Call, Storage, Event, Origin} = 12, + Module1_9: module1::::{Module, Call, Storage, Event, Origin}, } ); diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs b/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs index a361c5fc15afe..a48b4bd097039 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index.rs @@ -6,8 +6,8 @@ construct_runtime! { Block = Block, NodeBlock = Block, { - System: system::{Pallet}, - Pallet1: pallet1::{Pallet} = 0, + System: system::{}, + Pallet1: pallet1::{} = 0, } } diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr b/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr index f8fef492b16de..65368666c88fe 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index.stderr @@ -1,11 +1,11 @@ error: Module indices are conflicting: Both modules System and Pallet1 are at index 0 --> $DIR/conflicting_index.rs:9:3 | -9 | System: system::{Pallet}, +9 | System: system::{}, | ^^^^^^ error: Module indices are conflicting: Both modules System and Pallet1 are at index 0 --> $DIR/conflicting_index.rs:10:3 | -10 | Pallet1: pallet1::{Pallet} = 0, +10 | Pallet1: pallet1::{} = 0, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs index a93876d6e98df..c949cb41a23fa 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.rs @@ -6,10 +6,10 @@ construct_runtime! { Block = Block, NodeBlock = Block, { - System: system::{Pallet} = 5, - Pallet1: pallet1::{Pallet} = 3, - Pallet2: pallet2::{Pallet}, - Pallet3: pallet3::{Pallet}, + System: system::{} = 5, + Pallet1: pallet1::{} = 3, + Pallet2: pallet2::{}, + Pallet3: pallet3::{}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr index 2594fdcf52512..b792ff5d2a541 100644 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr +++ b/frame/support/test/tests/construct_runtime_ui/conflicting_index_2.stderr @@ -1,11 +1,11 @@ error: Module indices are conflicting: Both modules System and Pallet3 are at index 5 --> $DIR/conflicting_index_2.rs:9:3 | -9 | System: system::{Pallet} = 5, +9 | System: system::{} = 5, | ^^^^^^ error: Module indices are conflicting: Both modules System and Pallet3 are at index 5 --> $DIR/conflicting_index_2.rs:12:3 | -12 | Pallet3: pallet3::{Pallet}, +12 | Pallet3: pallet3::{}, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs b/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs deleted file mode 100644 index ed1efc5e1afa7..0000000000000 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.rs +++ /dev/null @@ -1,13 +0,0 @@ -use frame_support::construct_runtime; - -construct_runtime! { - pub enum Runtime where - UncheckedExtrinsic = UncheckedExtrinsic, - Block = Block, - NodeBlock = Block, - { - System: system::{Pallet, Module}, - } -} - -fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr b/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr deleted file mode 100644 index 4e99c0f751390..0000000000000 --- a/frame/support/test/tests/construct_runtime_ui/conflicting_module_pallet_parts.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: `Module` cannot be defined when `Pallet` is defined - --> $DIR/conflicting_module_pallet_parts.rs:9:28 - | -9 | System: system::{Pallet, Module}, - | ^^^^^^ - -error: `Module` cannot be defined when `Pallet` is defined - --> $DIR/conflicting_module_pallet_parts.rs:9:20 - | -9 | System: system::{Pallet, Module}, - | ^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr index 0e4f0e0bfeaa7..66c9fc95cb546 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_details_keyword.stderr @@ -1,4 +1,4 @@ -error: expected one of: `Module`, `Pallet`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` +error: expected one of: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` --> $DIR/invalid_module_details_keyword.rs:9:20 | 9 | system: System::{enum}, diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr index 53ecdc2bafbb6..7442c6be3a9a3 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr @@ -1,4 +1,4 @@ -error: expected one of: `Module`, `Pallet`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` +error: expected one of: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` --> $DIR/invalid_module_entry.rs:10:23 | 10 | Balance: balances::{Error}, diff --git a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs index b4c5742c03345..5eb7df5d18c20 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs +++ b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.rs @@ -7,7 +7,7 @@ construct_runtime! { UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module}, - Balance: balances::::{Pallet, Event}, + Balance: balances::::{Event}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr index f4f0dd9a362e3..f80b4bd66abdd 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr +++ b/frame/support/test/tests/construct_runtime_ui/missing_event_generic_on_module_with_instance.stderr @@ -1,5 +1,5 @@ error: Instantiable module with no generic `Event` cannot be constructed: module `Balance` must have generic `Event` --> $DIR/missing_event_generic_on_module_with_instance.rs:10:3 | -10 | Balance: balances::::{Pallet, Event}, +10 | Balance: balances::::{Event}, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs index 0dcac4a2ded11..5e44ae84d87c6 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs +++ b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.rs @@ -7,7 +7,7 @@ construct_runtime! { UncheckedExtrinsic = UncheckedExtrinsic { System: system::{Module}, - Balance: balances::::{Pallet, Origin}, + Balance: balances::::{Origin}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr index da24e6c34a58b..0f7d36aafb863 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr +++ b/frame/support/test/tests/construct_runtime_ui/missing_origin_generic_on_module_with_instance.stderr @@ -1,5 +1,5 @@ error: Instantiable module with no generic `Origin` cannot be constructed: module `Balance` must have generic `Origin` --> $DIR/missing_origin_generic_on_module_with_instance.rs:10:3 | -10 | Balance: balances::::{Pallet, Origin}, +10 | Balance: balances::::{Origin}, | ^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs index 547b35b186da4..4c8331ae442c8 100644 --- a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs +++ b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.rs @@ -6,8 +6,8 @@ construct_runtime! { Block = Block, NodeBlock = Block, { - System: system::{Pallet} = 255, - Pallet256: pallet256::{Pallet}, + System: system::{} = 255, + Pallet256: pallet256::{}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr index 453396c3ef747..c0ef5c8e60b9e 100644 --- a/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr +++ b/frame/support/test/tests/construct_runtime_ui/more_than_256_modules.stderr @@ -1,5 +1,5 @@ error: Module index doesn't fit into u8, index is 256 --> $DIR/more_than_256_modules.rs:10:3 | -10 | Pallet256: pallet256::{Pallet}, +10 | Pallet256: pallet256::{}, | ^^^^^^^^^ diff --git a/frame/support/test/tests/construct_runtime_ui/no_part.rs b/frame/support/test/tests/construct_runtime_ui/no_part.rs deleted file mode 100644 index 6d74014e04f09..0000000000000 --- a/frame/support/test/tests/construct_runtime_ui/no_part.rs +++ /dev/null @@ -1,13 +0,0 @@ -use frame_support::construct_runtime; - -construct_runtime! { - pub enum Runtime where - UncheckedExtrinsic = UncheckedExtrinsic, - Block = Block, - NodeBlock = Block, - { - System: system::{}, - } -} - -fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/no_part.stderr b/frame/support/test/tests/construct_runtime_ui/no_part.stderr deleted file mode 100644 index 647eeca4f81b9..0000000000000 --- a/frame/support/test/tests/construct_runtime_ui/no_part.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Cannot find part `Module` nor `Pallet`, one must be defined - --> $DIR/no_part.rs:9:3 - | -9 | System: system::{}, - | ^^^^^^ diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 8a56f9006cd6b..b1734f23ad7b3 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -322,8 +322,8 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: frame_system::{Pallet, Call, Event}, - Example: pallet::{Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + System: frame_system::{Module, Call, Event}, + Example: pallet::{Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, } ); diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs index 8c703acacb42f..912d68baed167 100644 --- a/frame/support/test/tests/pallet_compatibility.rs +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -250,7 +250,7 @@ frame_support::construct_runtime!( { System: frame_system::{Module, Call, Event}, // NOTE: name Example here is needed in order to have same module prefix - Example: pallet::{Pallet, Call, Event, Config, Storage}, + Example: pallet::{Module, Call, Event, Config, Storage}, PalletOld: pallet_old::{Module, Call, Event, Config, Storage}, } ); diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs index aca7c12268575..d2f7a6668ca6f 100644 --- a/frame/support/test/tests/pallet_compatibility_instance.rs +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -260,12 +260,12 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: frame_system::{Pallet, Call, Event}, - Example: pallet::{Pallet, Call, Event, Config, Storage}, + System: frame_system::{Module, Call, Event}, + Example: pallet::{Module, Call, Event, Config, Storage}, PalletOld: pallet_old::{Module, Call, Event, Config, Storage}, - Instance2Example: pallet::::{Pallet, Call, Event, Config, Storage}, + Instance2Example: pallet::::{Module, Call, Event, Config, Storage}, PalletOld2: pallet_old::::{Module, Call, Event, Config, Storage}, - Instance3Example: pallet::::{Pallet, Call, Event, Config, Storage}, + Instance3Example: pallet::::{Module, Call, Event, Config, Storage}, PalletOld3: pallet_old::::{Module, Call, Event, Config, Storage}, } ); diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index 89b1a14084fa4..f7e6c20ee8827 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -235,10 +235,10 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: frame_system::{Pallet, Call, Event}, - Example: pallet::{Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + System: frame_system::{Module, Call, Event}, + Example: pallet::{Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, Instance1Example: pallet::::{ - Pallet, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned + Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned }, } ); diff --git a/frame/support/test/tests/pallet_version.rs b/frame/support/test/tests/pallet_version.rs index dd79e0cdf2865..25320597ba49e 100644 --- a/frame/support/test/tests/pallet_version.rs +++ b/frame/support/test/tests/pallet_version.rs @@ -178,10 +178,10 @@ frame_support::construct_runtime!( Module2: module2::{Module, Call}, Module2_1: module2::::{Module, Call}, Module2_2: module2::::{Module, Call}, - Pallet3: pallet3::{Pallet, Call}, - Pallet4: pallet4::{Pallet, Call}, - Pallet4_1: pallet4::::{Pallet, Call}, - Pallet4_2: pallet4::::{Pallet, Call}, + Pallet3: pallet3::{Module, Call}, + Pallet4: pallet4::{Module, Call}, + Pallet4_1: pallet4::::{Module, Call}, + Pallet4_2: pallet4::::{Module, Call}, } ); From 0d56f2b5f0fe83bafdfa7bfc8223d66cfd339d93 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 23 Dec 2020 15:59:54 +0100 Subject: [PATCH 33/36] refactor with less intricated code --- .../procedural/src/pallet/expand/event.rs | 8 +-- .../src/pallet/expand/genesis_build.rs | 7 +-- .../procedural/src/pallet/parse/event.rs | 50 ++++--------------- .../src/pallet/parse/genesis_config.rs | 17 +++---- .../procedural/src/pallet/parse/helper.rs | 2 +- .../procedural/src/pallet/parse/mod.rs | 48 ++++++++++++++++++ 6 files changed, 73 insertions(+), 59 deletions(-) diff --git a/frame/support/procedural/src/pallet/expand/event.rs b/frame/support/procedural/src/pallet/expand/event.rs index 33e4224cd36a1..1dc3431f9bac5 100644 --- a/frame/support/procedural/src/pallet/expand/event.rs +++ b/frame/support/procedural/src/pallet/expand/event.rs @@ -40,8 +40,8 @@ pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream { let event_ident = &event.event; let frame_system = &def.frame_system; let frame_support = &def.frame_support; - let event_use_gen = &event.event_use_gen(); - let event_impl_gen= &event.event_impl_gen(); + let event_use_gen = &event.gen_kind.type_use_gen(); + let event_impl_gen= &event.gen_kind.type_impl_gen(); let metadata = event.metadata.iter() .map(|(ident, args, docs)| { let name = format!("{}", ident); @@ -71,7 +71,7 @@ pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream { }; // Phantom data is added for generic event. - if event.is_generic { + if event.gen_kind.is_generic() { let variant = syn::parse_quote!( #[doc(hidden)] #[codec(skip)] @@ -99,7 +99,7 @@ pub fn expand_event(def: &mut Def) -> proc_macro2::TokenStream { let deposit_event = if let Some((fn_vis, fn_span)) = &event.deposit_event { - let event_use_gen = &event.event_use_gen(); + let event_use_gen = &event.gen_kind.type_use_gen(); let trait_use_gen = &def.trait_use_generics(); let type_impl_gen = &def.type_impl_generics(); let type_use_gen = &def.type_use_generics(); diff --git a/frame/support/procedural/src/pallet/expand/genesis_build.rs b/frame/support/procedural/src/pallet/expand/genesis_build.rs index 71eebd25e349d..678e89eddf24a 100644 --- a/frame/support/procedural/src/pallet/expand/genesis_build.rs +++ b/frame/support/procedural/src/pallet/expand/genesis_build.rs @@ -38,12 +38,7 @@ pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream { }; let gen_cfg_ident = &genesis_config.genesis_config; - let gen_cfg_use_gen = match (genesis_config.has_trait, genesis_config.has_instance) { - (false, false) => (quote::quote!()), - (true, false) => (quote::quote!(T)), - (true, true) => (quote::quote!(T, I)), - (false, true) => unreachable!("Checked by def parser"), - }; + let gen_cfg_use_gen = genesis_config.gen_kind.type_use_gen(); let genesis_build = def.genesis_build.as_ref().expect("Checked by def parser"); let genesis_build_item = &mut def.item.content.as_mut() diff --git a/frame/support/procedural/src/pallet/parse/event.rs b/frame/support/procedural/src/pallet/parse/event.rs index e45549bda72cb..6b83ca4bf044a 100644 --- a/frame/support/procedural/src/pallet/parse/event.rs +++ b/frame/support/procedural/src/pallet/parse/event.rs @@ -39,46 +39,14 @@ pub struct EventDef { pub metadata: Vec<(syn::Ident, Vec, Vec)>, /// A set of usage of instance, must be check for consistency with trait. pub instances: Vec, - /// If event is declared with instance. - pub has_instance: bool, - /// If event is declared with generics. - pub is_generic: bool, + /// The kind of generic the type `Event` has. + pub gen_kind: super::GenericKind, /// Whether the function `deposit_event` must be generated. pub deposit_event: Option<(syn::Visibility, proc_macro2::Span)>, /// Where clause used in event definition. pub where_clause: Option, } -impl EventDef { - /// Return the generic to be used when using Event type - /// - /// Depending on its definition it can be: ``, `T` or `T, I` - pub fn event_use_gen(&self) -> proc_macro2::TokenStream { - if self.is_generic { - if self.has_instance { - quote::quote!(T, I) - } else { - quote::quote!(T) - } - } else { - quote::quote!() - } - } - - /// Return the generic to be used in `impl<..>` when implementing on Event type. - pub fn event_impl_gen(&self) -> proc_macro2::TokenStream { - if self.is_generic { - if self.has_instance { - quote::quote!(T: Config, I: 'static) - } else { - quote::quote!(T: Config) - } - } else { - quote::quote!() - } - } -} - /// Attribute for Event: defines metadata name to use. /// /// Syntax is: @@ -200,20 +168,25 @@ impl EventDef { } let where_clause = item.generics.where_clause.clone(); - let has_instance = item.generics.params.len() == 2; - let is_generic = item.generics.params.len() > 0; let mut instances = vec![]; + // NOTE: Event is not allowed to be only generic on I because it is not supported + // by construct_runtime. if let Some(u) = helper::check_type_def_optional_gen(&item.generics, item.ident.span())? { instances.push(u); } else { - // construct_runtime only allow generic event for instantiable pallet. + // construct_runtime only allow non generic event for non instantiable pallet. instances.push(helper::InstanceUsage { has_instance: false, span: item.ident.span(), }) } + let has_instance = item.generics.type_params().any(|t| t.ident == "I"); + let has_config = item.generics.type_params().any(|t| t.ident == "T"); + let gen_kind = super::GenericKind::from_gens(has_config, has_instance) + .expect("Checked by `helper::check_type_def_optional_gen` above"); + let event = syn::parse2::(item.ident.to_token_stream())?; let metadata = item.variants.iter() @@ -238,10 +211,9 @@ impl EventDef { index, metadata, instances, - has_instance, deposit_event, event, - is_generic, + gen_kind, where_clause, }) } diff --git a/frame/support/procedural/src/pallet/parse/genesis_config.rs b/frame/support/procedural/src/pallet/parse/genesis_config.rs index 21832d8feb33b..f42fcc6dac3d4 100644 --- a/frame/support/procedural/src/pallet/parse/genesis_config.rs +++ b/frame/support/procedural/src/pallet/parse/genesis_config.rs @@ -26,10 +26,8 @@ use super::helper; pub struct GenesisConfigDef { /// The index of item in pallet module. pub index: usize, - /// Whether type has instance generic. - pub has_instance: bool, - /// Whether type has trait generic. - pub has_trait: bool, + /// The kind of generic the type `GenesisConfig` has. + pub gen_kind: super::GenericKind, /// A set of usage of instance, must be check for consistency with trait. pub instances: Vec, /// The ident of genesis_config, can be used for span. @@ -48,9 +46,6 @@ impl GenesisConfigDef { }, }; - let has_instance = generics.type_params().any(|t| t.ident == "I"); - let has_trait = generics.type_params().any(|t| t.ident == "T"); - let mut instances = vec![]; // NOTE: GenesisConfig is not allowed to be only generic on I because it is not supported // by construct_runtime. @@ -58,6 +53,11 @@ impl GenesisConfigDef { instances.push(u); } + let has_instance = generics.type_params().any(|t| t.ident == "I"); + let has_config = generics.type_params().any(|t| t.ident == "T"); + let gen_kind = super::GenericKind::from_gens(has_config, has_instance) + .expect("Checked by `helper::check_type_def_optional_gen` above"); + if !matches!(vis, syn::Visibility::Public(_)) { let msg = "Invalid pallet::genesis_config, GenesisConfig must be public"; return Err(syn::Error::new(item_span, msg)); @@ -71,9 +71,8 @@ impl GenesisConfigDef { Ok(GenesisConfigDef { index, genesis_config: ident.clone(), - has_instance, - has_trait, instances, + gen_kind, }) } } diff --git a/frame/support/procedural/src/pallet/parse/helper.rs b/frame/support/procedural/src/pallet/parse/helper.rs index eddb03fc33f9c..cbf09ee231757 100644 --- a/frame/support/procedural/src/pallet/parse/helper.rs +++ b/frame/support/procedural/src/pallet/parse/helper.rs @@ -261,7 +261,7 @@ pub fn check_type_def_gen_no_bounds( /// /// `span` is used in case generics is empty (empty generics has span == call_site). /// -/// return the instance if found. +/// return some instance usage if there is some generic, or none otherwise. pub fn check_type_def_optional_gen( gen: &syn::Generics, span: proc_macro2::Span, diff --git a/frame/support/procedural/src/pallet/parse/mod.rs b/frame/support/procedural/src/pallet/parse/mod.rs index a07d5fb6324ab..085467bdaa2e5 100644 --- a/frame/support/procedural/src/pallet/parse/mod.rs +++ b/frame/support/procedural/src/pallet/parse/mod.rs @@ -309,6 +309,54 @@ impl Def { } } +/// Some generic kind for type which can be not generic, or generic over config, +/// or generic over config and instance, but not generic only over instance. +pub enum GenericKind { + None, + Config, + ConfigAndInstance, +} + +impl GenericKind { + /// Return Err if it is only generics over instance but not over config. + pub fn from_gens(has_config: bool, has_instance: bool) -> Result { + match (has_config, has_instance) { + (false, false) => Ok(GenericKind::None), + (true, false) => Ok(GenericKind::Config), + (true, true) => Ok(GenericKind::ConfigAndInstance), + (false, true) => Err(()), + } + } + + /// Return the generic to be used when using the type. + /// + /// Depending on its definition it can be: ``, `T` or `T, I` + pub fn type_use_gen(&self) -> proc_macro2::TokenStream { + match self { + GenericKind::None => quote::quote!(), + GenericKind::Config => quote::quote!(T), + GenericKind::ConfigAndInstance => quote::quote!(T, I), + } + } + + /// Return the generic to be used in `impl<..>` when implementing on the type. + pub fn type_impl_gen(&self) -> proc_macro2::TokenStream { + match self { + GenericKind::None => quote::quote!(), + GenericKind::Config => quote::quote!(T: Config), + GenericKind::ConfigAndInstance => quote::quote!(T: Config, I: 'static), + } + } + + /// Return whereas the type has some generic. + pub fn is_generic(&self) -> bool { + match self { + GenericKind::None => false, + GenericKind::Config | GenericKind::ConfigAndInstance => true, + } + } +} + /// List of additional token to be used for parsing. mod keyword { syn::custom_keyword!(origin); From 98cdc0ee6607088b6e135808c8a22bb6bc29b79d Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 23 Dec 2020 16:31:48 +0100 Subject: [PATCH 34/36] fix ui test with new image --- .../call_argument_invalid_bound.stderr | 8 +++----- .../call_argument_invalid_bound_2.stderr | 5 ++--- .../call_argument_invalid_bound_3.stderr | 20 +++++++++---------- .../pallet_ui/event_field_not_member.stderr | 8 +++----- .../genesis_default_not_satisfied.stderr | 2 +- .../inherent_check_inner_span.stderr | 2 +- .../pallet_ui/storage_incomplete_item.stderr | 5 ++--- .../pallet_ui/store_trait_leak_private.stderr | 4 ++-- 8 files changed, 23 insertions(+), 31 deletions(-) diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr index e9e35d50ad4cc..3f1f5382d757b 100644 --- a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr @@ -8,15 +8,13 @@ help: consider further restricting this bound | 1 | #[frame_support::pallet] + std::cmp::PartialEq | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `::Bar: std::clone::Clone` is not satisfied +error[E0277]: the trait bound `::Bar: Clone` is not satisfied --> $DIR/call_argument_invalid_bound.rs:20:37 | 20 | fn foo(origin: OriginFor, bar: T::Bar) -> DispatchResultWithPostInfo { - | ^ the trait `std::clone::Clone` is not implemented for `::Bar` + | ^ the trait `Clone` is not implemented for `::Bar` | - = note: required by `std::clone::Clone::clone` - + = note: required by `clone` error[E0277]: `::Bar` doesn't implement `std::fmt::Debug` --> $DIR/call_argument_invalid_bound.rs:20:37 | 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 1fc092423629b..2b55eca69c1bb 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 @@ -1,9 +1,8 @@ -error[E0277]: the trait bound `pallet::Call: pallet::_::_parity_scale_codec::Decode` is not satisfied +error[E0277]: the trait bound `pallet::Call: Decode` is not satisfied --> $DIR/call_argument_invalid_bound_2.rs:17:12 | 17 | #[pallet::call] - | ^^^^ the trait `pallet::_::_parity_scale_codec::Decode` is not implemented for `pallet::Call` - + | ^^^^ the trait `Decode` is not implemented for `pallet::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 | diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr index cf327754abfb9..217cb16b83488 100644 --- a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr @@ -1,26 +1,24 @@ -error[E0369]: binary operation `==` cannot be applied to type `&pallet::Bar` +error[E0369]: binary operation `==` cannot be applied to type `&Bar` --> $DIR/call_argument_invalid_bound_3.rs:22:37 | 22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { | ^^^ | - = note: an implementation of `std::cmp::PartialEq` might be missing for `&pallet::Bar` - -error[E0277]: the trait bound `pallet::Bar: std::clone::Clone` is not satisfied + = note: an implementation of `std::cmp::PartialEq` might be missing for `&Bar` +error[E0277]: the trait bound `Bar: Clone` is not satisfied --> $DIR/call_argument_invalid_bound_3.rs:22:37 | 22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { - | ^^^ the trait `std::clone::Clone` is not implemented for `pallet::Bar` + | ^^^ the trait `Clone` is not implemented for `Bar` | - = note: required by `std::clone::Clone::clone` - -error[E0277]: `pallet::Bar` doesn't implement `std::fmt::Debug` + = note: required by `clone` +error[E0277]: `Bar` doesn't implement `std::fmt::Debug` --> $DIR/call_argument_invalid_bound_3.rs:22:37 | 22 | fn foo(origin: OriginFor, bar: Bar) -> DispatchResultWithPostInfo { - | ^^^ `pallet::Bar` cannot be formatted using `{:?}` + | ^^^ `Bar` cannot be formatted using `{:?}` | - = help: the trait `std::fmt::Debug` is not implemented for `pallet::Bar` + = help: the trait `std::fmt::Debug` is not implemented for `Bar` = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` - = note: required because of the requirements on the impl of `std::fmt::Debug` for `&pallet::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/event_field_not_member.stderr b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr index 7275476936235..f0a8a3258342f 100644 --- a/frame/support/test/tests/pallet_ui/event_field_not_member.stderr +++ b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr @@ -7,7 +7,6 @@ error[E0277]: `::Bar` 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` - error[E0369]: binary operation `==` cannot be applied to type `&::Bar` --> $DIR/event_field_not_member.rs:23:7 | @@ -18,11 +17,10 @@ help: consider further restricting this bound | 22 | pub enum Event { | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `::Bar: std::clone::Clone` is not satisfied +error[E0277]: the trait bound `::Bar: Clone` is not satisfied --> $DIR/event_field_not_member.rs:23:7 | 23 | B { b: T::Bar }, - | ^ the trait `std::clone::Clone` is not implemented for `::Bar` + | ^ the trait `Clone` is not implemented for `::Bar` | - = note: required by `std::clone::Clone::clone` + = note: required by `clone` diff --git a/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr index b699288db0d7f..a2998788736ac 100644 --- a/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr +++ b/frame/support/test/tests/pallet_ui/genesis_default_not_satisfied.stderr @@ -7,4 +7,4 @@ error[E0277]: the trait bound `pallet::GenesisConfig: std::default::Default` is ::: $WORKSPACE/frame/support/src/traits.rs | | pub trait GenesisBuild: Default + MaybeSerializeDeserialize { - | ------- required by this bound in `frame_support::traits::GenesisBuild` + | ------- required by this bound in `GenesisBuild` diff --git a/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr index f44b6da415344..75a522889ebd9 100644 --- a/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr +++ b/frame/support/test/tests/pallet_ui/inherent_check_inner_span.stderr @@ -7,4 +7,4 @@ error[E0046]: not all trait items implemented, missing: `Call`, `Error`, `INHERE = help: implement the missing item: `type Call = Type;` = help: implement the missing item: `type Error = Type;` = help: implement the missing item: `const INHERENT_IDENTIFIER: [u8; 8] = value;` - = help: implement the missing item: `fn create_inherent(_: &frame_support::inherent::InherentData) -> std::option::Option<::Call> { todo!() }` + = help: implement the missing item: `fn create_inherent(_: &InherentData) -> std::option::Option<::Call> { todo!() }` diff --git a/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr index 571caa0bf40ed..bb377c94c257c 100644 --- a/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr +++ b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr @@ -5,9 +5,8 @@ error: free type alias without body | ^^^^^^^^- | | | help: provide a definition for the type: `= ;` - -error[E0433]: failed to resolve: use of undeclared type or module `pallet` +error[E0433]: failed to resolve: use of undeclared crate or module `pallet` --> $DIR/storage_incomplete_item.rs:18:4 | 18 | #[pallet::storage] - | ^^^^^^ use of undeclared type or module `pallet` + | ^^^^^^ use of undeclared crate or module `pallet` 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 d3ae7eb88ce3d..f0f41a75deb46 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 @@ -1,8 +1,8 @@ -error[E0446]: private type `pallet::_GeneratedPrefixForStorageFoo` in public interface +error[E0446]: private type `_GeneratedPrefixForStorageFoo` in public interface --> $DIR/store_trait_leak_private.rs:11:37 | 11 | #[pallet::generate_store(pub trait Store)] | ^^^^^ can't leak private type ... 21 | type Foo = StorageValue<_, u8>; - | - `pallet::_GeneratedPrefixForStorageFoo` declared as private + | - `_GeneratedPrefixForStorageFoo` declared as private From ae38859a5a8f583ba2c5abe755af03eb9bc331ef Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 23 Dec 2020 17:25:49 +0100 Subject: [PATCH 35/36] fix ui tests --- .../test/tests/pallet_ui/call_argument_invalid_bound.stderr | 2 ++ .../test/tests/pallet_ui/call_argument_invalid_bound_2.stderr | 1 + .../test/tests/pallet_ui/call_argument_invalid_bound_3.stderr | 2 ++ .../support/test/tests/pallet_ui/event_field_not_member.stderr | 2 ++ .../support/test/tests/pallet_ui/storage_incomplete_item.stderr | 1 + 5 files changed, 8 insertions(+) diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr index 3f1f5382d757b..64f93cd574ed0 100644 --- a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound.stderr @@ -8,6 +8,7 @@ help: consider further restricting this bound | 1 | #[frame_support::pallet] + std::cmp::PartialEq | ^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: the trait bound `::Bar: Clone` is not satisfied --> $DIR/call_argument_invalid_bound.rs:20:37 | @@ -15,6 +16,7 @@ error[E0277]: the trait bound `::Bar: Clone` is not satisfi | ^ 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.rs:20:37 | 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 2b55eca69c1bb..e366061b1c25e 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,6 +3,7 @@ error[E0277]: the trait bound `pallet::Call: Decode` is not satisfied | 17 | #[pallet::call] | ^^^^ the trait `Decode` is not implemented for `pallet::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 | diff --git a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr index 217cb16b83488..89cee573a2757 100644 --- a/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr +++ b/frame/support/test/tests/pallet_ui/call_argument_invalid_bound_3.stderr @@ -5,6 +5,7 @@ error[E0369]: binary operation `==` cannot be applied to type `&Bar` | ^^^ | = note: an implementation of `std::cmp::PartialEq` might be missing for `&Bar` + error[E0277]: the trait bound `Bar: Clone` is not satisfied --> $DIR/call_argument_invalid_bound_3.rs:22:37 | @@ -12,6 +13,7 @@ error[E0277]: the trait bound `Bar: Clone` is not satisfied | ^^^ 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_3.rs:22:37 | diff --git a/frame/support/test/tests/pallet_ui/event_field_not_member.stderr b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr index f0a8a3258342f..97d4db798e611 100644 --- a/frame/support/test/tests/pallet_ui/event_field_not_member.stderr +++ b/frame/support/test/tests/pallet_ui/event_field_not_member.stderr @@ -7,6 +7,7 @@ error[E0277]: `::Bar` 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` + error[E0369]: binary operation `==` cannot be applied to type `&::Bar` --> $DIR/event_field_not_member.rs:23:7 | @@ -17,6 +18,7 @@ help: consider further restricting this bound | 22 | pub enum Event { | ^^^^^^^^^^^^^^^^^^^^^ + error[E0277]: the trait bound `::Bar: Clone` is not satisfied --> $DIR/event_field_not_member.rs:23:7 | diff --git a/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr index bb377c94c257c..57f3ab78a5382 100644 --- a/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr +++ b/frame/support/test/tests/pallet_ui/storage_incomplete_item.stderr @@ -5,6 +5,7 @@ error: free type alias without body | ^^^^^^^^- | | | help: provide a definition for the type: `= ;` + error[E0433]: failed to resolve: use of undeclared crate or module `pallet` --> $DIR/storage_incomplete_item.rs:18:4 | From c158e5fbf9fd80e64c0faf80459dc5ef3b032a85 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Thu, 24 Dec 2020 12:01:30 +0100 Subject: [PATCH 36/36] add minor tests --- frame/support/test/tests/pallet.rs | 66 +++++++++++++++++++++ frame/support/test/tests/pallet_instance.rs | 54 +++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index b1734f23ad7b3..5d2785ebf2609 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -274,6 +274,67 @@ pub mod pallet { pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; } +// Test that a pallet with non generic event and generic genesis_config is correctly handled +#[frame_support::pallet] +pub mod pallet2 { + use super::{SomeType1, SomeAssociation1}; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config + where ::AccountId: From + SomeAssociation1, + { + type Event: From + IsType<::Event>; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks> for Pallet + where T::AccountId: From + SomeAssociation1, + { + } + + #[pallet::call] + impl Pallet + where T::AccountId: From + SomeAssociation1, + { + } + + #[pallet::event] + pub enum Event { + /// Something + Something(u32), + } + + #[pallet::genesis_config] + pub struct GenesisConfig + where T::AccountId: From + SomeAssociation1, + { + phantom: PhantomData, + } + + impl Default for GenesisConfig + where T::AccountId: From + SomeAssociation1, + { + fn default() -> Self { + GenesisConfig { + phantom: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig + where T::AccountId: From + SomeAssociation1, + { + fn build(&self) {} + } +} + frame_support::parameter_types!( pub const MyGetParam: u32= 10; pub const MyGetParam2: u32= 11; @@ -312,6 +373,10 @@ impl pallet::Config for Runtime { type Balance = u64; } +impl pallet2::Config for Runtime { + type Event = Event; +} + pub type Header = sp_runtime::generic::Header; pub type Block = sp_runtime::generic::Block; pub type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic; @@ -324,6 +389,7 @@ frame_support::construct_runtime!( { System: frame_system::{Module, Call, Event}, Example: pallet::{Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned}, + Example2: pallet2::{Module, Call, Event, Config, Storage}, } ); diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index f7e6c20ee8827..82b058b7bdddd 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -186,6 +186,52 @@ pub mod pallet { pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall"; } +// Test that a instantiable pallet with a generic genesis_config is correctly handled +#[frame_support::pallet] +pub mod pallet2 { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(crate) trait Store)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet {} + + #[pallet::call] + impl, I: 'static> Pallet {} + + #[pallet::event] + pub enum Event, I: 'static = ()> { + /// Something + Something(u32), + } + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + phantom: PhantomData<(T, I)>, + } + + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + phantom: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) {} + } +} + frame_support::parameter_types!( pub const MyGetParam: u32= 10; pub const BlockHashCount: u32 = 250; @@ -224,6 +270,12 @@ impl pallet::Config for Runtime { type MyGetParam= MyGetParam; type Balance = u64; } +impl pallet2::Config for Runtime { + type Event = Event; +} +impl pallet2::Config for Runtime { + type Event = Event; +} pub type Header = sp_runtime::generic::Header; pub type Block = sp_runtime::generic::Block; @@ -240,6 +292,8 @@ frame_support::construct_runtime!( Instance1Example: pallet::::{ Module, Call, Event, Config, Storage, Inherent, Origin, ValidateUnsigned }, + Example2: pallet2::{Module, Call, Event, Config, Storage}, + Instance1Example2: pallet2::::{Module, Call, Event, Config, Storage}, } );