diff --git a/Cargo.lock b/Cargo.lock index a4215b7dbc77a..bd6ed4ed8fa7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6493,6 +6493,23 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-example-kitchensink" +version = "4.0.0-dev" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-example-offchain-worker" version = "4.0.0-dev" @@ -6510,6 +6527,17 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-examples" +version = "4.0.0-dev" +dependencies = [ + "pallet-default-config-example", + "pallet-dev-mode", + "pallet-example-basic", + "pallet-example-kitchensink", + "pallet-example-offchain-worker", +] + [[package]] name = "pallet-fast-unstake" version = "4.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index eed878428d387..cb0417de788c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,8 +106,10 @@ members = [ "frame/election-provider-support/benchmarking", "frame/election-provider-support/solution-type", "frame/election-provider-support/solution-type/fuzzer", + "frame/examples", "frame/examples/basic", "frame/examples/offchain-worker", + "frame/examples/kitchensink", "frame/examples/dev-mode", "frame/examples/default-config", "frame/executive", diff --git a/frame/examples/Cargo.toml b/frame/examples/Cargo.toml new file mode 100644 index 0000000000000..57def091b1f63 --- /dev/null +++ b/frame/examples/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "pallet-examples" +version = "4.0.0-dev" +authors = ["Parity Technologies "] +edition = "2021" +license = "Apache-2.0" +homepage = "https://substrate.io" +repository = "https://github.com/paritytech/substrate/" +description = "The single package with various examples for frame pallets" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +pallet-example-basic = { default-features = false, path = "./basic" } +pallet-default-config-example = { default-features = false, path = "./default-config" } +pallet-example-offchain-worker = { default-features = false, path = "./offchain-worker" } +pallet-example-kitchensink = { default-features = false, path = "./kitchensink" } +pallet-dev-mode = { default-features = false, path = "./dev-mode" } + +[features] +default = [ "std" ] +std = [ + "pallet-example-basic/std", + "pallet-default-config-example/std", + "pallet-example-offchain-worker/std", + "pallet-example-kitchensink/std", + "pallet-dev-mode/std", +] +try-runtime = [ + "pallet-example-basic/try-runtime", + "pallet-default-config-example/try-runtime", + "pallet-example-offchain-worker/try-runtime", + "pallet-example-kitchensink/try-runtime", + "pallet-dev-mode/try-runtime", +] \ No newline at end of file diff --git a/frame/examples/kitchensink/Cargo.toml b/frame/examples/kitchensink/Cargo.toml new file mode 100644 index 0000000000000..783a5276e43eb --- /dev/null +++ b/frame/examples/kitchensink/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "pallet-example-kitchensink" +version = "4.0.0-dev" +authors = ["Parity Technologies "] +edition = "2021" +license = "MIT-0" +homepage = "https://substrate.io" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME example kitchensink pallet" +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 = "23.0.0", default-features = false, path = "../../../primitives/io" } +sp-runtime = { version = "24.0.0", default-features = false, path = "../../../primitives/runtime" } +sp-std = { version = "8.0.0", default-features = false, path = "../../../primitives/std" } + +frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../../benchmarking" } + +pallet-balances = { version = "4.0.0-dev", default-features = false, path = "../../balances" } + +[dev-dependencies] +sp-core = { version = "21.0.0", default-features = false, path = "../../../primitives/core" } + +[features] +default = ["std"] +std = [ + "codec/std", + "log/std", + "scale-info/std", + + "frame-support/std", + "frame-system/std", + + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + + "frame-benchmarking?/std", + + "pallet-balances/std", +] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +try-runtime = ["frame-support/try-runtime"] diff --git a/frame/examples/kitchensink/src/benchmarking.rs b/frame/examples/kitchensink/src/benchmarking.rs new file mode 100644 index 0000000000000..24da581fc967b --- /dev/null +++ b/frame/examples/kitchensink/src/benchmarking.rs @@ -0,0 +1,66 @@ +// 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. + +//! Benchmarking for `pallet-example-kitchensink`. + +// Only enable this module for benchmarking. +#![cfg(feature = "runtime-benchmarks")] +use super::*; + +#[allow(unused)] +use crate::Pallet as Kitchensink; + +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; + +// To actually run this benchmark on pallet-example-kitchensink, we need to put this pallet into the +// runtime and compile it with `runtime-benchmarks` feature. The detail procedures are +// documented at: +// https://docs.substrate.io/reference/how-to-guides/weights/add-benchmarks/ +// +// The auto-generated weight estimate of this pallet is copied over to the `weights.rs` file. +// The exact command of how the estimate generated is printed at the top of the file. + +// Details on using the benchmarks macro can be seen at: +// https://paritytech.github.io/substrate/master/frame_benchmarking/trait.Benchmarking.html#tymethod.benchmarks +#[benchmarks] +mod benchmarks { + use super::*; + + // This will measure the execution time of `set_foo`. + #[benchmark] + fn set_foo_benchmark() { + // This is the benchmark setup phase. + // `set_foo` is a constant time function, hence we hard-code some random value here. + let value = 1000u32.into(); + #[extrinsic_call] + set_foo(RawOrigin::Root, value, 10u128); // The execution phase is just running `set_foo` extrinsic call + + // This is the optional benchmark verification phase, asserting certain states. + assert_eq!(Pallet::::foo(), Some(value)) + } + + // This line generates test cases for benchmarking, and could be run by: + // `cargo test -p pallet-example-kitchensink --all-features`, you will see one line per case: + // `test benchmarking::bench_sort_vector ... ok` + // `test benchmarking::bench_accumulate_dummy ... ok` + // `test benchmarking::bench_set_dummy_benchmark ... ok` in the result. + // + // The line generates three steps per benchmark, with repeat=1 and the three steps are + // [low, mid, high] of the range. + impl_benchmark_test_suite!(Kitchensink, crate::tests::new_test_ext(), crate::tests::Test); +} diff --git a/frame/examples/kitchensink/src/lib.rs b/frame/examples/kitchensink/src/lib.rs new file mode 100644 index 0000000000000..c60e126181a95 --- /dev/null +++ b/frame/examples/kitchensink/src/lib.rs @@ -0,0 +1,330 @@ +// 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. + +//! # Kitchensink Example Pallet +//! +//! **This pallet serves as an example and is not meant to be used in production.** +//! +//! The kitchen-sink catalog of the the FRAME macros and their various syntax options. +//! +//! This example does not focus on pallet instancing, `dev_mode`, and does nto include any 'where' +//! clauses on `T`. These will both incur additional complexity to the syntax, but are not discussed +//! here. + +#![cfg_attr(not(feature = "std"), no_std)] + +// Re-export pallet items so that they can be accessed from the crate namespace. +pub use pallet::*; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +#[cfg(feature = "try-runtime")] +use sp_runtime::TryRuntimeError; + +pub mod weights; +pub use weights::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + /// The config trait of the pallet. You can basically do anything with the config trait that you + /// can do with a normal rust trait: import items consisting of types, constants and functions. + /// + /// A very common pattern is for a pallet to import implementations of traits such as + /// [`frame_support::traits::Currency`], [`frame_support::traits::fungibles::Inspect`] and + /// [`frame_support::traits::Get`]. These are all types that the pallet is delegating to the top + /// level runtime to provide to it. + /// + /// The `FRAME`-specific syntax are: + /// + /// * the use of `#[pallet::constant]`([`frame_support::procedural`]), which places a `Get` + /// implementation in the metadata. + /// * `type RuntimeEvent`, which is mandatory if your pallet has events. See TODO. + /// * Needless to say, because [`Config`] is bounded by [`frame_system::Config`], you can use + /// all the items from [`frame_system::Config`] as well, such as `AccountId`. + /// * `#[pallet::disable_frame_system_supertrait_check]` would remove the need for + /// `frame_system::Config` to exist, which you should almost never need. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching runtime event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// Type representing the weight of this pallet + type WeightInfo: WeightInfo; + + /// This is a normal Rust type, nothing specific to FRAME here. + type Currency: frame_support::traits::tokens::fungible::Inspect; + + /// Similarly, let the runtime decide this. + fn some_function() -> u32; + + /// And this + const FOO: u32; + + /// This is a FRAME-specific item. It will be placed in the metadata of the pallet, and + /// therefore can be queried by offchain applications. + #[pallet::constant] + type InMetadata: Get; + } + + /// Allows you to define some extra constants to be added into constant metadata. + #[pallet::extra_constants] + impl Pallet { + #[allow(non_snake_case)] + fn SomeValue() -> u32 { + unimplemented!() + } + + #[pallet::constant_name(OtherValue)] + fn arbitrary_name() -> u32 { + unimplemented!() + } + } + + const STORAGE_VERSION: frame_support::traits::StorageVersion = StorageVersion::new(1); + + /// The pallet struct. There's nothing special to FRAME about this; it can implement functions + /// in an impl blocks, traits and so on. + #[pallet::pallet] + #[pallet::without_storage_info] + #[pallet::storage_version(STORAGE_VERSION)] + pub struct Pallet(_); + + /// Allows you to define some origin for the pallet. + #[pallet::origin] + pub type Origin = frame_system::RawOrigin<::AccountId>; + + // first, we showcase all the possible storage types, with most of their details. + + /// A storage value. We mark this as unbounded, alter its prefix, and define a custom storage + /// getter for it. + /// + /// The value is stored a single trie node, and therefore can be retrieved with a single + /// database access. + #[pallet::storage] + #[pallet::unbounded] // optional + #[pallet::storage_prefix = "OtherFoo"] // optional + #[pallet::getter(fn foo)] // optional + pub type Foo = StorageValue; + + #[pallet::type_value] + pub fn DefaultForFoo() -> u32 { + 1 + } + + #[pallet::storage] + pub type FooWithDefault = + StorageValue; + + /// A storage map. This creates a mapping from keys of type `u32` to values of type `u32`. + /// + /// Keys and values can be iterated, albeit each value is stored under a unique trie key, + /// meaning that an iteration consists of many database accesses. + #[pallet::storage] + pub type Bar = StorageMap; + + /// Conceptually same as `StorageMap<>` where the key is a tuple of `(u32, u32)`. On top, it + /// provides some functions to iterate or remove items based on only the first key. + #[pallet::storage] + pub type Qux = StorageDoubleMap< + Hasher1 = Blake2_128Concat, + Key1 = u32, + Hasher2 = Blake2_128Concat, + Key2 = u32, + Value = u32, + >; + + /// Same as `StorageDoubleMap`, but with arbitrary number of keys. + #[pallet::storage] + pub type Quux = StorageNMap< + Key = ( + NMapKey, + NMapKey, + NMapKey, + ), + Value = u64, + >; + + /// In all of these examples, we chose a syntax where the storage item is defined using the + /// explicit generic syntax (`X = Y`). Alternatively: + #[pallet::storage] + pub type AlternativeSyntax = StorageMap<_, Blake2_128Concat, u32, u32>; + + /// Lastly, all storage items, as you saw, had to be generic over `T`. If they want to use an + /// item from `Config`, `` should be used. + #[pallet::storage] + pub type AlternativeSyntax2 = StorageMap<_, Blake2_128Concat, T::AccountId, u32>; + + /// The genesis config type. This allows the pallet to define how it should initialized upon + /// genesis. + /// + /// It can be generic over `T` or not, depending on whether it is or not. + #[pallet::genesis_config] + pub struct GenesisConfig { + pub foo: u32, + pub bar: T::BlockNumber, + } + + impl Default for GenesisConfig { + fn default() -> Self { + Self { foo: 0, bar: Default::default() } + } + } + + /// Allows you to define how `genesis_configuration is built. + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + Foo::::put(self.foo); + } + } + + /// The call declaration. This states the entry points that we handle. The + /// macro takes care of the marshalling of arguments and dispatch. + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::set_foo_benchmark())] + pub fn set_foo( + _: OriginFor, + new_foo: u32, + #[pallet::compact] _other_compact: u128, + ) -> DispatchResult { + Foo::::set(Some(new_foo)); + + Ok(()) + } + } + + /// The event type. This exactly like a normal Rust enum. + /// + /// It can or cannot be generic over ``. Note that unlike a normal enum, if none of + /// the variants actually use ``, the macro will generate a hidden `PhantomData` + /// variant. + /// + /// The `generate_deposit` macro generates a function on `Pallet` called `deposit_event` which + /// will properly convert the error type of your pallet into `RuntimeEvent` (recall `type + /// RuntimeEvent: From>`, so it can be converted) and deposit it via + /// `frame_system::Pallet::deposit_event`. + #[pallet::event] + #[pallet::generate_deposit(pub fn deposit_event)] + pub enum Event { + /// A simple tuple style variant. + SomethingHappened(u32), + /// A simple struct-style variant. Note that we use `AccountId` from `T` because `T: + /// Config`, which by extension implies `T: frame_system::Config`. + SomethingDetailedHappened { at: u32, to: T::AccountId }, + /// Another variant. + SomeoneJoined(T::AccountId), + } + + /// The error enum. Must always be generic over ``, which is expanded to ``. + #[pallet::error] + pub enum Error { + SomethingWentWrong, + SomethingBroke, + } + + /// All the possible hooks that a pallet can have. See [`frame_support::traits::Hooks`] for more + /// info. + #[pallet::hooks] + impl Hooks for Pallet { + fn integrity_test() {} + + fn offchain_worker(_n: T::BlockNumber) { + unimplemented!() + } + + fn on_initialize(_n: T::BlockNumber) -> Weight { + unimplemented!() + } + + fn on_finalize(_n: T::BlockNumber) { + unimplemented!() + } + + fn on_idle(_n: T::BlockNumber, _remaining_weight: Weight) -> Weight { + unimplemented!() + } + + fn on_runtime_upgrade() -> Weight { + unimplemented!() + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result, TryRuntimeError> { + unimplemented!() + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), TryRuntimeError> { + unimplemented!() + } + + #[cfg(feature = "try-runtime")] + fn try_state(_n: T::BlockNumber) -> Result<(), TryRuntimeError> { + unimplemented!() + } + } + + /// Allows you to define an enum on the pallet which will then instruct + /// `construct_runtime` to amalgamate all similarly-named enums from other + /// pallets into an aggregate enum. + #[pallet::composite_enum] + pub enum HoldReason { + Staking, + } + + /// Allows the pallet to validate some unsigned transaction. See + /// [`sp_runtime::traits::ValidateUnsigned`] for more info. + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + fn validate_unsigned(_: TransactionSource, _: &Self::Call) -> TransactionValidity { + unimplemented!() + } + + fn pre_dispatch(_: &Self::Call) -> Result<(), TransactionValidityError> { + unimplemented!() + } + } + + /// Allows the pallet to provide some inherent. See [`frame_support::inherent::ProvideInherent`] + /// for more info. + #[pallet::inherent] + impl ProvideInherent for Pallet { + type Call = Call; + type Error = MakeFatalError<()>; + + const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234"; + + fn create_inherent(_data: &InherentData) -> Option { + unimplemented!(); + } + + fn is_inherent(_call: &Self::Call) -> bool { + unimplemented!() + } + } +} diff --git a/frame/examples/kitchensink/src/tests.rs b/frame/examples/kitchensink/src/tests.rs new file mode 100644 index 0000000000000..d6c0891df89d7 --- /dev/null +++ b/frame/examples/kitchensink/src/tests.rs @@ -0,0 +1,104 @@ +// 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. + +//! Tests for pallet-example-kitchensink. + +use crate::*; +#[use_attr] +use frame_support::derive_impl; +use frame_support::{macro_magic::use_attr, parameter_types, traits::ConstU64}; +use sp_runtime::BuildStorage; +// Reexport crate as its pallet name for construct_runtime. +use crate as pallet_example_kitchensink; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +// For testing the pallet, we construct a mock runtime. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Kitchensink: pallet_example_kitchensink::{Pallet, Call, Storage, Config, Event}, + } +); + +/// Using a default config for [`frame_system`] in tests. See `default-config` example for more +/// details. +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type PalletInfo = PalletInfo; + type OnSetCode = (); + + type AccountData = pallet_balances::AccountData; +} + +impl pallet_balances::Config for Test { + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type Balance = u64; + type DustRemoval = (); + type RuntimeEvent = RuntimeEvent; + type ExistentialDeposit = ConstU64<1>; + type AccountStore = System; + type WeightInfo = (); + type FreezeIdentifier = (); + type MaxFreezes = (); + type RuntimeHoldReason = (); + type MaxHolds = (); +} + +parameter_types! { + pub const InMetadata: u32 = 30; +} + +impl Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + + type Currency = Balances; + type InMetadata = InMetadata; + + const FOO: u32 = 100; + + fn some_function() -> u32 { + 5u32 + } +} + +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = RuntimeGenesisConfig { + // We use default for brevity, but you can configure as desired if needed. + system: Default::default(), + balances: Default::default(), + kitchensink: pallet_example_kitchensink::GenesisConfig { bar: 32, foo: 24 }, + } + .build_storage() + .unwrap(); + t.into() +} diff --git a/frame/examples/kitchensink/src/weights.rs b/frame/examples/kitchensink/src/weights.rs new file mode 100644 index 0000000000000..1d083a9b80eea --- /dev/null +++ b/frame/examples/kitchensink/src/weights.rs @@ -0,0 +1,68 @@ + +//! Autogenerated weights for `pallet_example_kitchensink` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-06-02, STEPS: `20`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `MacBook.local`, CPU: `` +//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ./target/release/node-template +// benchmark +// pallet +// --chain +// dev +// --pallet +// pallet_example_kitchensink +// --extrinsic +// * +// --steps +// 20 +// --repeat +// 10 +// --output +// frame/examples/kitchensink/src/weights.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for pallet_template. +pub trait WeightInfo { + fn set_foo_benchmark() -> Weight; +} + +/// Weight functions for `pallet_example_kitchensink`. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: Kitchensink OtherFoo (r:0 w:1) + /// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured) + fn set_foo_benchmark() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} + +impl WeightInfo for () { + /// Storage: Kitchensink OtherFoo (r:0 w:1) + /// Proof Skipped: Kitchensink OtherFoo (max_values: Some(1), max_size: None, mode: Measured) + fn set_foo_benchmark() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_000_000 picoseconds. + Weight::from_parts(1_000_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + .saturating_add(RocksDbWeight::get().writes(1)) + } +} diff --git a/frame/examples/src/lib.rs b/frame/examples/src/lib.rs new file mode 100644 index 0000000000000..3ff1aa7b9f1f2 --- /dev/null +++ b/frame/examples/src/lib.rs @@ -0,0 +1,37 @@ +// 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. + +//! # FRAME Pallet Examples +//! +//! This crate contains examples of FRAME pallets. It is not intended to be used in production. +//! +//! ## Pallets +//! +//! - [**`pallet_example_basic`**](./basic): A simple example of a FRAME pallet demonstrating +//! concepts, APIs and structures common to most FRAME runtimes. +//! +//! - [**`pallet_example_offchain_worker`**](./offchain-worker): A simple example of a FRAME pallet +//! demonstrating concepts, APIs and structures common to most offchain workers. +//! +//! - [**`pallet-default-config-example`**](./default-config): A simple example of a FRAME pallet +//! demonstrating the simpler way to implement `Config` trait of pallets. +//! +//! - [**`pallet-dev-mode`**](./dev-mode): A simple example of a FRAME pallet demonstrating the ease +//! of requirements for a pallet in dev mode. +//! +//! - [**`pallet-example-kitchensink`**](./kitchensink): A simple example of a FRAME pallet +//! demonstrating a catalog of the the FRAME macros and their various syntax options. diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 7800fd8bba8a5..8f3f27538a907 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1564,6 +1564,7 @@ pub mod pallet_prelude { pub use frame_support::pallet_macros::*; pub use frame_support_procedural::register_default_impl; pub use scale_info::TypeInfo; + pub use sp_inherents::MakeFatalError; pub use sp_runtime::{ traits::{MaybeSerializeDeserialize, Member, ValidateUnsigned}, transaction_validity::{