-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[FRAME Core] Default Pallet Config Trait / derive_impl #13454
Changes from 121 commits
83ebbbe
8597691
8090642
6294102
a0a6423
749df49
0777136
7d5d50f
6c6f8c5
9abec0a
930cc25
01c88ad
4b481be
4ff18f4
cd0753c
07d80f5
7dc8022
c8924cc
b409576
d72da33
d27b824
3e4c923
d178975
046b0b8
e3566dd
bd68211
dce288d
e061bbb
8b8a11e
271186a
48506f7
d5bda5f
7fc7665
04fd313
9e31858
5b8019b
b7a5a3f
ef9d107
bc3237c
d17c807
4d089e5
879de64
d697ee1
f6c232e
727a4e7
df3b5ce
4a33e99
a9413d3
ec34f58
52152a5
e191aa9
cc9ee82
5119cf5
2fd5cc5
814176e
d4cf31e
53bfe6d
d80bbdd
9bf5328
97de112
194da7f
4dd4440
e32e8a1
f90f13d
edfc83b
efd9222
78ac0d5
1dae299
faa8dce
8374ed8
8b22ea6
d7f3f6a
5b90575
afae21c
f784efc
763a93a
16b4d5a
bc688f9
8077b7b
a399ecd
c825367
b373b52
af16dac
ce06d17
e7c9056
655657e
9bcf5e8
4449600
238dc9c
7a7f74e
07a0555
a99aca0
cc7bd84
b4b7de8
13d5ab4
b9113c4
9d4cce6
167cbbd
c8640d4
bb4f8fd
1029ff6
86b649c
fc7b8aa
09c30c1
0b21ac1
144c09d
d86021e
db8587f
4ffda9b
0decc58
2f8f4a5
ba426b2
7356072
85f20d0
19540f6
b36a086
68b76d2
298352b
e141483
4b6fe4a
d3d7d93
9ee1b09
41da6cd
638c1fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| [package] | ||
| name = "pallet-default-config-example" | ||
| version = "4.0.0-dev" | ||
| authors = ["Parity Technologies <[email protected]>"] | ||
| edition = "2021" | ||
| license = "MIT-0" | ||
| homepage = "https://substrate.io" | ||
| repository = "https://github.com/paritytech/substrate/" | ||
| description = "FRAME example pallet demonstrating derive_impl / default_config in action" | ||
| readme = "README.md" | ||
|
|
||
| [package.metadata.docs.rs] | ||
| targets = ["x86_64-unknown-linux-gnu"] | ||
|
|
||
| [dependencies] | ||
| codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false } | ||
| log = { version = "0.4.17", default-features = false } | ||
| scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } | ||
| frame-support = { version = "4.0.0-dev", default-features = false, path = "../../support" } | ||
| frame-system = { version = "4.0.0-dev", default-features = false, path = "../../system" } | ||
|
|
||
| sp-io = { version = "7.0.0", default-features = false, path = "../../../primitives/io" } | ||
| sp-runtime = { version = "7.0.0", default-features = false, path = "../../../primitives/runtime" } | ||
| sp-std = { version = "5.0.0", default-features = false, path = "../../../primitives/std" } | ||
|
|
||
| [dev-dependencies] | ||
| sp-core = { version = "7.0.0", default-features = false, path = "../../../primitives/core" } | ||
|
|
||
| [features] | ||
| default = ["std"] | ||
| std = [ | ||
| "codec/std", | ||
| "frame-support/std", | ||
| "frame-system/std", | ||
| "log/std", | ||
| "scale-info/std", | ||
| "sp-io/std", | ||
| "sp-runtime/std", | ||
| "sp-std/std", | ||
| ] | ||
| try-runtime = ["frame-support/try-runtime"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # Default Config Example Pallet | ||
|
|
||
| An example pallet demonstrating the ability to derive default testing configs via | ||
| `#[derive_impl]` and `#[pallet::config(with_default)]`. | ||
|
|
||
| Run `cargo doc --package pallet-default-config-example --open` to view this pallet's documentation. | ||
|
|
||
| License: MIT-0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,210 @@ | ||
| // This file is part of Substrate. | ||
|
|
||
| // Copyright (C) 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. | ||
|
|
||
| //! # Default Config Pallet Example | ||
| //! | ||
| //! A simple example of a FRAME pallet that utilizes [`frame_support::derive_impl`] to demonstrate | ||
| //! the simpler way to implement `Config` trait of pallets. This example only showcases this in a | ||
| //! `mock.rs` environment, but the same applies to a real runtime as well. | ||
| //! | ||
| //! See the source code of [`tests`] for a real examples. | ||
| //! | ||
| //! Study the following types: | ||
| //! | ||
| //! - [`pallet::DefaultConfig`], and how it differs from [`pallet::Config`]. | ||
| //! - [`pallet::config_preludes::TestDefaultConfig`] and how it implements | ||
| //! [`pallet::DefaultConfig`]. | ||
| //! - Notice how [`pallet::DefaultConfig`] is independent of [`frame_system::Config`]. | ||
|
|
||
| #![cfg_attr(not(feature = "std"), no_std)] | ||
|
|
||
| #[frame_support::pallet] | ||
| pub mod pallet { | ||
| use frame_support::pallet_prelude::*; | ||
|
|
||
| /// This pallet is annotated to have a default config. This will auto-generate | ||
| /// [`DefaultConfig`]. | ||
| /// | ||
| /// It will be an identical, but won't have anything that is `#[pallet::no_default]`. | ||
| #[pallet::config(with_default)] | ||
| pub trait Config: frame_system::Config { | ||
| /// The overarching event type. This is coming from the runtime, and cannot have a default. | ||
| /// In general, `Runtime*`-oriented types cannot have a sensible default. | ||
| #[pallet::no_default] // optional. `RuntimeEvent` is automatically excluded as well. | ||
| type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>; | ||
sam0x17 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /// An input parameter to this pallet. This value can have a default, because it is not | ||
| /// reliant on `frame_system::Config` or the overarching runtime in any way. | ||
| type WithDefaultValue: Get<u32>; | ||
|
|
||
| /// Same as [`Config::WithDefaultValue`], but we don't intend to define a default for this | ||
| /// in our tests below. | ||
| type OverwrittenDefaultValue: Get<u32>; | ||
|
|
||
| /// An input parameter that relies on `<Self as frame_system::Config>::AccountId`. As of | ||
| /// now, such types cannot have defaults and need to be annotated as such, iff | ||
| /// `#[pallet::config(with_default)]` is enabled: | ||
| #[pallet::no_default] | ||
| type CannotHaveDefault: Get<Self::AccountId>; | ||
|
|
||
| /// Something that is a normal type, with default. | ||
| type WithDefaultType; | ||
|
|
||
| /// Same as [`Config::WithDefaultType`], but we don't intend to define a default for this | ||
| /// in our tests below. | ||
| type OverwrittenDefaultType; | ||
| } | ||
|
|
||
| /// Container for different types that implement [`DefaultConfig`]` of this pallet. | ||
| pub mod config_preludes { | ||
| // This will help use not need to disambiguate anything when using `derive_impl`. | ||
| use super::*; | ||
|
|
||
| /// A type providing default configurations for this pallet in testing environment. | ||
| pub struct TestDefaultConfig; | ||
| #[frame_support::register_default_impl(TestDefaultConfig)] | ||
| impl DefaultConfig for TestDefaultConfig { | ||
| type WithDefaultValue = frame_support::traits::ConstU32<42>; | ||
| type OverwrittenDefaultValue = frame_support::traits::ConstU32<42>; | ||
|
|
||
| type WithDefaultType = u32; | ||
| type OverwrittenDefaultType = u32; | ||
| } | ||
|
|
||
| /// A type providing default configurations for this pallet in a parachain environment. | ||
| pub struct ParachainDefaultConfig; | ||
| #[frame_support::register_default_impl(ParachainDefaultConfig)] | ||
| impl DefaultConfig for ParachainDefaultConfig { | ||
| type WithDefaultValue = frame_support::traits::ConstU32<66>; | ||
| type OverwrittenDefaultValue = frame_support::traits::ConstU32<66>; | ||
| type WithDefaultType = u32; | ||
| type OverwrittenDefaultType = u32; | ||
| } | ||
| } | ||
|
|
||
| #[pallet::pallet] | ||
| pub struct Pallet<T>(_); | ||
|
|
||
| #[pallet::event] | ||
| pub enum Event<T: Config> {} | ||
| } | ||
|
|
||
| #[cfg(any(test, doc))] | ||
| pub mod tests { | ||
| use super::*; | ||
|
|
||
| use frame_support::macro_magic::use_attr; | ||
| // Because `derive_impl` is a [macro_magic](https://crates.io/crates/macro_magic) attribute | ||
| // macro, [`#[use_attr]`](`frame_support::macro_magic::use_attr`) must be attached to any use | ||
| // statement that brings it into scope. | ||
| #[use_attr] | ||
| use frame_support::derive_impl; | ||
|
|
||
| use super::pallet as pallet_default_config_example; | ||
|
|
||
| type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>; | ||
| type Block = frame_system::mocking::MockBlock<Test>; | ||
|
|
||
| frame_support::construct_runtime!( | ||
| pub enum Test where | ||
| Block = Block, | ||
| NodeBlock = Block, | ||
| UncheckedExtrinsic = UncheckedExtrinsic, | ||
| { | ||
| System: frame_system, | ||
| DefaultPallet: pallet_default_config_example, | ||
| } | ||
| ); | ||
|
|
||
| #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can omit it in certain situations indeed. It is documented here https://github.com/paritytech/substrate/pull/13454/files#diff-55fa2bbcb98405e03a4311fca1d14b211001133cffa61fb0d4837be69c9e7bebR804 |
||
| impl frame_system::Config for Test { | ||
| // these items are defined by frame-system as `no_default`, so we must specify them here. | ||
| // Note that these are types that actually rely on the outer runtime, and can't sensibly | ||
| // have an _independent_ default. | ||
| type BaseCallFilter = frame_support::traits::Everything; | ||
| type RuntimeOrigin = RuntimeOrigin; | ||
| type RuntimeCall = RuntimeCall; | ||
| type RuntimeEvent = RuntimeEvent; | ||
| type PalletInfo = PalletInfo; | ||
| type OnSetCode = (); | ||
|
|
||
| // all of this is coming from `frame_system::config_preludes::TestDefaultConfig`. | ||
|
|
||
| // type Index = u32; | ||
| // type BlockNumber = u32; | ||
| // type Header = sp_runtime::generic::Header<Self::BlockNumber, Self::Hashing>; | ||
| // type Hash = sp_core::hash::H256; | ||
| // type Hashing = sp_runtime::traits::BlakeTwo256; | ||
| // type AccountId = u64; | ||
| // type Lookup = sp_runtime::traits::IdentityLookup<u64>; | ||
| // type BlockHashCount = frame_support::traits::ConstU32<10>; | ||
| // type MaxConsumers = frame_support::traits::ConstU32<16>; | ||
| // type AccountData = (); | ||
| // type OnNewAccount = (); | ||
| // type OnKilledAccount = (); | ||
| // type SystemWeightInfo = (); | ||
| // type SS58Prefix = (); | ||
| // type Version = (); | ||
| // type BlockWeights = (); | ||
| // type BlockLength = (); | ||
| // type DbWeight = (); | ||
|
|
||
| // you could still overwrite any of them if desired. | ||
| type SS58Prefix = frame_support::traits::ConstU16<456>; | ||
| } | ||
|
|
||
| // Similarly, we use the defaults provided by own crate as well. | ||
| use pallet::config_preludes::TestDefaultConfig; | ||
| #[derive_impl(TestDefaultConfig as pallet::DefaultConfig)] | ||
| impl crate::pallet::Config for Test { | ||
| // These two both cannot have defaults. | ||
| type RuntimeEvent = RuntimeEvent; | ||
| // Note that the default account-id type in | ||
| // `frame_system::config_preludes::TestDefaultConfig` is `u64`. | ||
| type CannotHaveDefault = frame_support::traits::ConstU64<1>; | ||
|
|
||
| type OverwrittenDefaultValue = frame_support::traits::ConstU32<678>; | ||
| type OverwrittenDefaultType = u128; | ||
| } | ||
|
|
||
| #[test] | ||
| fn it_works() { | ||
| use frame_support::traits::Get; | ||
| use pallet::{Config, DefaultConfig}; | ||
|
|
||
| // assert one of the value types that is not overwritten. | ||
| assert_eq!( | ||
| <<Test as Config>::WithDefaultValue as Get<u32>>::get(), | ||
| <<TestDefaultConfig as DefaultConfig>::WithDefaultValue as Get<u32>>::get() | ||
| ); | ||
|
|
||
| // assert one of the value types that is overwritten. | ||
| assert_eq!(<<Test as Config>::OverwrittenDefaultValue as Get<u32>>::get(), 678u32); | ||
|
|
||
| // assert one of the types that is not overwritten. | ||
| assert_eq!( | ||
| std::any::TypeId::of::<<Test as Config>::WithDefaultType>(), | ||
| std::any::TypeId::of::<<TestDefaultConfig as DefaultConfig>::WithDefaultType>() | ||
| ); | ||
|
|
||
| // assert one of the types that is overwritten. | ||
| assert_eq!( | ||
| std::any::TypeId::of::<<Test as Config>::OverwrittenDefaultType>(), | ||
| std::any::TypeId::of::<u128>() | ||
| ) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.