Newer
Older
Guanqun Lu
committed
// 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.
//!
//! ## Note on Tuple Traits
//!
//! Many of the traits defined in [`traits`] have auto-implementations on tuples as well. Usually,
//! the tuple is a function of number of pallets in the runtime. By default, the traits are
//! implemented for tuples of up to 64 items.
//
// If you have more pallets in your runtime, or for any other reason need more, enabled `tuples-96`
// or the `tuples-128` complication flag. Note that these features *will increase* the compilation
// of this crate.
#![cfg_attr(not(feature = "std"), no_std)]
/// Export ourself as `frame_support` to make tests happy.
/// Private exports that are being used by macros.
///
/// The exports are not stable and should not be relied on.
pub mod __private {
pub use codec;
pub use frame_metadata as metadata;
pub use log;
pub use paste;
pub use scale_info;
pub use serde;
pub use sp_core::{Get, OpaqueMetadata, Void};
pub use sp_crypto_hashing_proc_macro;
pub use sp_inherents;
#[cfg(feature = "std")]
pub use sp_io::TestExternalities;
pub use sp_io::{self, hashing, storage::root as storage_root};
pub use sp_metadata_ir as metadata_ir;
#[cfg(feature = "std")]
pub use sp_runtime::{bounded_btree_map, bounded_vec};
pub use sp_runtime::{
traits::Dispatchable, DispatchError, RuntimeDebug, StateVersion, TransactionOutcome,
#[cfg(feature = "std")]
pub use sp_state_machine::BasicExternalities;
pub use sp_std;
pub use sp_tracing;
pub use tt_call::*;
}
Sasha Gryaznov
committed
pub mod crypto;
Bastian Köcher
committed
pub mod dispatch_context;
mod hash;
pub mod inherent;
pub mod migrations;
Bastian Köcher
committed
#[cfg(test)]
mod tests;
pub mod weights;
#[doc(hidden)]
pub mod unsigned {
#[doc(hidden)]
pub use crate::sp_runtime::traits::ValidateUnsigned;
#[doc(hidden)]
pub use crate::sp_runtime::transaction_validity::{
TransactionSource, TransactionValidity, TransactionValidityError, UnknownTransaction,
#[cfg(any(feature = "std", feature = "runtime-benchmarks", feature = "try-runtime", test))]
pub use self::storage::storage_noop_guard::StorageNoopGuard;
pub use self::{
dispatch::{Callable, Parameter},
hash::{
Blake2_128, Blake2_128Concat, Blake2_256, Hashable, Identity, ReversibleStorageHasher,
StorageHasher, Twox128, Twox256, Twox64Concat,
},
storage::{
bounded_btree_map::BoundedBTreeMap,
bounded_btree_set::BoundedBTreeSet,
bounded_vec::{BoundedSlice, BoundedVec},
migration,
weak_bounded_vec::WeakBoundedVec,
IterableStorageDoubleMap, IterableStorageMap, IterableStorageNMap, StorageDoubleMap,
StorageMap, StorageNMap, StoragePrefixedMap, StorageValue,
},
pub use sp_runtime::{
self, print, traits::Printable, ConsensusEngineId, MAX_MODULE_ERROR_ENCODED_SIZE,
};
use codec::{Decode, Encode};
use sp_runtime::TypeId;
/// A unified log target for support operations.
pub const LOG_TARGET: &str = "runtime::frame-support";
/// A type that cannot be instantiated.
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
pub enum Never {}
/// A pallet identifier. These are per pallet and should be stored in a registry somewhere.
#[derive(Clone, Copy, Eq, PartialEq, Encode, Decode, TypeInfo)]
pub struct PalletId(pub [u8; 8]);
impl TypeId for PalletId {
const TYPE_ID: [u8; 4] = *b"modl";
}
Bastian Köcher
committed
/// Generate a [`#[pallet::storage]`](pallet_macros::storage) alias outside of a pallet.
Bastian Köcher
committed
/// This storage alias works similarly to the [`#[pallet::storage]`](pallet_macros::storage)
/// attribute macro. It supports [`StorageValue`](storage::types::StorageValue),
/// [`StorageMap`](storage::types::StorageMap),
/// [`StorageDoubleMap`](storage::types::StorageDoubleMap) and
/// [`StorageNMap`](storage::types::StorageNMap). The main difference to the normal
/// [`#[pallet::storage]`](pallet_macros::storage) is the flexibility around declaring the
/// storage prefix to use. The storage prefix determines where to find the value in the
/// storage. [`#[pallet::storage]`](pallet_macros::storage) uses the name of the pallet as
/// declared in [`construct_runtime!`].
Bastian Köcher
committed
/// The flexibility around declaring the storage prefix makes this macro very useful for
/// writing migrations etc.
Bastian Köcher
committed
/// # Examples
Bastian Köcher
committed
/// There are different ways to declare the `prefix` to use. The `prefix` type can either be
/// declared explicetly by passing it to the macro as an attribute or by letting the macro
/// guess on what the `prefix` type is. The `prefix` is always passed as the first generic
/// argument to the type declaration. When using [`#[pallet::storage]`](pallet_macros::storage)
/// this first generic argument is always `_`. Besides declaring the `prefix`, the rest of the
/// type declaration works as with [`#[pallet::storage]`](pallet_macros::storage).
///
/// 1. Use the `verbatim` prefix type. This prefix type uses the given identifier as the
/// `prefix`:
#[doc = docify::embed!("src/tests/storage_alias.rs", verbatim_attribute)]
///
/// 2. Use the `pallet_name` prefix type. This prefix type uses the name of the pallet as
/// configured in [`construct_runtime!`] as the `prefix`:
#[doc = docify::embed!("src/tests/storage_alias.rs", pallet_name_attribute)]
/// It requires that the given prefix type implements
/// [`PalletInfoAccess`](traits::PalletInfoAccess) (which is always the case for FRAME pallet
/// structs). In the example above, `Pallet<T>` is the prefix type.
///
/// 3. Use the `dynamic` prefix type. This prefix type calls [`Get::get()`](traits::Get::get)
/// to get the `prefix`:
#[doc = docify::embed!("src/tests/storage_alias.rs", dynamic_attribute)]
/// It requires that the given prefix type implements [`Get<'static str>`](traits::Get).
///
/// 4. Let the macro "guess" what kind of prefix type to use. This only supports verbatim or
/// pallet name. The macro uses the presence of generic arguments to the prefix type as an
/// indication that it should use the pallet name as the `prefix`:
Bastian Köcher
committed
#[doc = docify::embed!("src/tests/storage_alias.rs", storage_alias_guess)]
pub use frame_support_procedural::storage_alias;
pub use frame_support_procedural::derive_impl;
/// Experimental macros for defining dynamic params that can be used in pallet configs.
#[cfg(feature = "experimental")]
pub mod dynamic_params {
pub use frame_support_procedural::{
dynamic_aggregated_params_internal, dynamic_pallet_params, dynamic_params,
};
}
/// Create new implementations of the [`Get`](crate::traits::Get) trait.
///
/// The so-called parameter type can be created in four different ways:
/// - Using `const` to create a parameter type that provides a `const` getter. It is required that
/// the `value` is const.
///
/// - Declare the parameter type without `const` to have more freedom when creating the value.
///
/// - Using `storage` to create a storage parameter type. This type is special as it tries to 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 formula:
///
/// `twox_128(":" ++ NAME ++ ":")` where `NAME` is the name that is passed as type name.
///
/// - Using `static` to create a static parameter type. Its value is being provided by a static
/// variable with the equivalent name in `UPPER_SNAKE_CASE`. An additional `set` function is
/// provided in this case to alter the static variable. **This is intended for testing ONLY and is
/// ONLY available when `std` is enabled.**
/// ```
/// # use frame_support::traits::Get;
/// # use frame_support::parameter_types;
/// // This function cannot be used in a const context.
/// fn non_const_expression() -> u64 { 99 }
///
/// const FIXED_VALUE: u64 = 10;
/// pub const Argument: u64 = 42 + FIXED_VALUE;
/// /// Visibility of the type is optional
/// OtherArgument: u64 = non_const_expression();
/// pub storage StorageArgument: u64 = 5;
/// pub static StaticArgument: u32 = 7;
/// type Parameter: Get<u64>;
/// type OtherParameter: Get<u64>;
/// type StorageParameter: Get<u64>;
/// type StaticParameter: Get<u32>;
/// struct Runtime;
/// impl Config for Runtime {
/// type Parameter = Argument;
/// type OtherParameter = OtherArgument;
/// type StorageParameter = StorageArgument;
/// type StaticParameter = StaticArgument;
/// }
///
/// // In testing, `StaticArgument` can be altered later: `StaticArgument::set(8)`.
/// ```
///
/// # Invalid example:
///
/// ```compile_fail
/// # use frame_support::traits::Get;
/// # use frame_support::parameter_types;
/// // This function cannot be used in a const context.
/// fn non_const_expression() -> u64 { 99 }
///
/// parameter_types! {
/// pub const Argument: u64 = non_const_expression();
/// }
/// ```
#[macro_export]
macro_rules! parameter_types {
(
$( #[ $attr:meta ] )*
$vis:vis const $name:ident $(< $($ty_params:ident),* >)?: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
< $($ty_params),* >( $($crate::__private::sp_std::marker::PhantomData<$ty_params>),* )
)?;
$crate::parameter_types!(IMPL_CONST $name , $type , $value $( $(, $ty_params)* )?);
$crate::parameter_types!( $( $rest )* );
);
(
$( #[ $attr:meta ] )*
$vis:vis $name:ident $(< $($ty_params:ident),* >)?: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
< $($ty_params),* >( $($crate::__private::sp_std::marker::PhantomData<$ty_params>),* )
)?;
$crate::parameter_types!(IMPL $name, $type, $value $( $(, $ty_params)* )?);
$crate::parameter_types!( $( $rest )* );
);
(
$( #[ $attr:meta ] )*
$vis:vis storage $name:ident $(< $($ty_params:ident),* >)?: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
< $($ty_params),* >( $($crate::__private::sp_std::marker::PhantomData<$ty_params>),* )
)?;
$crate::parameter_types!(IMPL_STORAGE $name, $type, $value $( $(, $ty_params)* )?);
$crate::parameter_types!( $( $rest )* );
(IMPL_CONST $name:ident, $type:ty, $value:expr $(, $ty_params:ident)*) => {
impl< $($ty_params),* > $name< $($ty_params),* > {
/// Returns the value of this parameter type.
pub const fn get() -> $type {
$value
}
}
impl<_I: From<$type> $(, $ty_params)*> $crate::traits::Get<_I> for $name< $($ty_params),* > {
fn get() -> _I {
_I::from(Self::get())
}
}
impl< $($ty_params),* > $crate::traits::TypedGet for $name< $($ty_params),* > {
type Type = $type;
fn get() -> $type {
Self::get()
}
}
(IMPL $name:ident, $type:ty, $value:expr $(, $ty_params:ident)*) => {
impl< $($ty_params),* > $name< $($ty_params),* > {
/// Returns the value of this parameter type.
pub fn get() -> $type {
$value
}
}
impl<_I: From<$type>, $(, $ty_params)*> $crate::traits::Get<_I> for $name< $($ty_params),* > {
fn get() -> _I {
_I::from(Self::get())
impl< $($ty_params),* > $crate::traits::TypedGet for $name< $($ty_params),* > {
type Type = $type;
fn get() -> $type {
Self::get()
}
}
(IMPL_STORAGE $name:ident, $type:ty, $value:expr $(, $ty_params:ident)*) => {
impl< $($ty_params),* > $name< $($ty_params),* > {
/// Returns the key for this parameter type.
pub fn key() -> [u8; 16] {
$crate::__private::sp_crypto_hashing_proc_macro::twox_128!(b":", $name, b":")
}
/// Set the value of this parameter type in the storage.
///
Liam Aharon
committed
/// This needs to be executed in an externalities provided environment.
pub fn set(value: &$type) {
$crate::storage::unhashed::put(&Self::key(), value);
}
/// Returns the value of this parameter type.
///
Liam Aharon
committed
/// This needs to be executed in an externalities provided environment.
#[allow(unused)]
pub fn get() -> $type {
$crate::storage::unhashed::get(&Self::key()).unwrap_or_else(|| $value)
}
}
impl<_I: From<$type> $(, $ty_params)*> $crate::traits::Get<_I> for $name< $($ty_params),* > {
fn get() -> _I {
_I::from(Self::get())
impl< $($ty_params),* > $crate::traits::TypedGet for $name< $($ty_params),* > {
type Type = $type;
fn get() -> $type {
Self::get()
}
}
$( #[ $attr:meta ] )*
$vis:vis static $name:ident: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$crate::parameter_types_impl_thread_local!(
$( #[ $attr ] )*
$vis static $name: $type = $value;
$crate::parameter_types!( $( $rest )* );
);
}
#[cfg(not(feature = "std"))]
#[macro_export]
macro_rules! parameter_types_impl_thread_local {
( $( $any:tt )* ) => {
compile_error!("static parameter types is only available in std and for testing.");
};
}
#[cfg(feature = "std")]
#[macro_export]
macro_rules! parameter_types_impl_thread_local {
(
$(
$( #[ $attr:meta ] )*
$vis:vis static $name:ident: $type:ty = $value:expr;
)*
) => {
$crate::parameter_types_impl_thread_local!(
IMPL_THREAD_LOCAL $( $vis, $name, $type, $value, )*
);
$crate::__private::paste::item! {
$crate::parameter_types!(
$(
$( #[ $attr ] )*
$vis $name: $type = [<$name:snake:upper>].with(|v| v.borrow().clone());
)*
);
$(
impl $name {
/// Set the internal value.
pub fn set(t: $type) {
[<$name:snake:upper>].with(|v| *v.borrow_mut() = t);
}
/// Mutate the internal value in place.
pub fn mutate<R, F: FnOnce(&mut $type) -> R>(mutate: F) -> R{
let mut current = Self::get();
let result = mutate(&mut current);
Self::set(current);
result
}
/// Get current value and replace with initial value of the parameter type.
pub fn take() -> $type {
let current = Self::get();
Self::set($value);
current
}
}
)*
}
};
(IMPL_THREAD_LOCAL $( $vis:vis, $name:ident, $type:ty, $value:expr, )* ) => {
$crate::__private::paste::item! {
thread_local! {
$(
pub static [<$name:snake:upper>]: std::cell::RefCell<$type> =
std::cell::RefCell::new($value);
)*
}
}
};
/// Macro for easily creating a new implementation of both the `Get` and `Contains` traits. Use
/// exactly as with `parameter_types`, only the type must be `Ord`.
#[macro_export]
macro_rules! ord_parameter_types {
(
$( #[ $attr:meta ] )*
$vis:vis const $name:ident: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
$vis struct $name;
$crate::parameter_types!{IMPL $name , $type , $value}
$crate::ord_parameter_types!{IMPL $name , $type , $value}
$crate::ord_parameter_types!{ $( $rest )* }
);
() => ();
(IMPL $name:ident , $type:ty , $value:expr) => {
impl $crate::traits::SortedMembers<$type> for $name {
fn contains(t: &$type) -> bool { &$value == t }
fn sorted_members() -> $crate::__private::sp_std::prelude::Vec<$type> { vec![$value] }
#[cfg(feature = "runtime-benchmarks")]
fn add(_: &$type) {}
impl $crate::traits::Contains<$type> for $name {
fn contains(t: &$type) -> bool { &$value == t }
}
/// Print out a formatted message.
///
/// # Example
///
/// ```
/// frame_support::runtime_print!("my value is {}", 3);
/// ```
#[macro_export]
macro_rules! runtime_print {
($($arg:tt)+) => {
{
use core::fmt::Write;
let mut w = $crate::__private::sp_std::Writer::default();
let _ = core::write!(&mut w, $($arg)+);
$crate::__private::sp_io::misc::print_utf8(&w.inner())
}
}
}
/// Print out the debuggable type.
pub fn debug(data: &impl sp_std::fmt::Debug) {
runtime_print!("{:?}", data);
}
pub use frame_support_procedural::{
construct_runtime, match_and_insert, transactional, PalletError, RuntimeDebugNoBound,
#[cfg(feature = "experimental")]
pub use frame_support_procedural::runtime;
#[doc(hidden)]
pub use frame_support_procedural::{__create_tt_macro, __generate_dummy_part_checker};
/// Derive [`Clone`] but do not bound any generic.
///
/// This is useful for type generic over runtime:
/// ```
/// # use frame_support::CloneNoBound;
/// }
///
/// // Foo implements [`Clone`] because `C` bounds [`Clone`].
/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Clone`].
/// #[derive(CloneNoBound)]
/// struct Foo<T: Config> {
/// }
/// ```
pub use frame_support_procedural::CloneNoBound;
/// Derive [`Eq`] but do not bound any generic.
///
/// This is useful for type generic over runtime:
/// ```
/// # use frame_support::{EqNoBound, PartialEqNoBound};
/// }
///
/// // Foo implements [`Eq`] because `C` bounds [`Eq`].
/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Eq`].
/// #[derive(PartialEqNoBound, EqNoBound)]
/// struct Foo<T: Config> {
/// }
/// ```
pub use frame_support_procedural::EqNoBound;
/// Derive [`PartialEq`] but do not bound any generic.
///
/// This is useful for type generic over runtime:
/// ```
/// # use frame_support::PartialEqNoBound;
/// }
///
/// // Foo implements [`PartialEq`] because `C` bounds [`PartialEq`].
/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`PartialEq`].
/// #[derive(PartialEqNoBound)]
/// struct Foo<T: Config> {
/// }
/// ```
pub use frame_support_procedural::PartialEqNoBound;
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
/// Derive [`Ord`] but do not bound any generic.
///
/// This is useful for type generic over runtime:
/// ```
/// # use frame_support::{OrdNoBound, PartialOrdNoBound, EqNoBound, PartialEqNoBound};
/// trait Config {
/// type C: Ord;
/// }
///
/// // Foo implements [`Ord`] because `C` bounds [`Ord`].
/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Ord`].
/// #[derive(EqNoBound, OrdNoBound, PartialEqNoBound, PartialOrdNoBound)]
/// struct Foo<T: Config> {
/// c: T::C,
/// }
/// ```
pub use frame_support_procedural::OrdNoBound;
/// Derive [`PartialOrd`] but do not bound any generic.
///
/// This is useful for type generic over runtime:
/// ```
/// # use frame_support::{OrdNoBound, PartialOrdNoBound, EqNoBound, PartialEqNoBound};
/// trait Config {
/// type C: PartialOrd;
/// }
///
/// // Foo implements [`PartialOrd`] because `C` bounds [`PartialOrd`].
/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`PartialOrd`].
/// #[derive(PartialOrdNoBound, PartialEqNoBound, EqNoBound)]
/// struct Foo<T: Config> {
/// c: T::C,
/// }
/// ```
pub use frame_support_procedural::PartialOrdNoBound;
/// Derive [`Debug`] but do not bound any generic.
///
/// This is useful for type generic over runtime:
/// ```
/// # use frame_support::DebugNoBound;
/// # use core::fmt::Debug;
/// }
///
/// // Foo implements [`Debug`] because `C` bounds [`Debug`].
/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Debug`].
/// #[derive(DebugNoBound)]
/// struct Foo<T: Config> {
/// }
/// ```
pub use frame_support_procedural::DebugNoBound;
/// Derive [`Default`] but do not bound any generic.
///
/// This is useful for type generic over runtime:
/// ```
/// # use frame_support::DefaultNoBound;
/// # use core::default::Default;
/// trait Config {
/// }
///
/// // Foo implements [`Default`] because `C` bounds [`Default`].
/// // Otherwise compilation will fail with an output telling `c` doesn't implement [`Default`].
/// #[derive(DefaultNoBound)]
/// struct Foo<T: Config> {
/// c: T::C,
/// }
///
/// // Also works with enums, by specifying the default with #[default]:
/// #[derive(DefaultNoBound)]
/// enum Bar<T: Config> {
/// // Bar will implement Default as long as all of the types within Baz also implement default.
/// #[default]
/// Baz(T::C),
/// Quxx,
/// }
/// ```
pub use frame_support_procedural::DefaultNoBound;
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
/// Assert the annotated function is executed within a storage transaction.
///
/// The assertion is enabled for native execution and when `debug_assertions` are enabled.
///
/// # Example
///
/// ```
/// # use frame_support::{
/// # require_transactional, transactional, dispatch::DispatchResult
/// # };
///
/// #[require_transactional]
/// fn update_all(value: u32) -> DispatchResult {
/// // Update multiple storages.
/// // Return `Err` to indicate should revert.
/// Ok(())
/// }
///
/// #[transactional]
/// fn safe_update(value: u32) -> DispatchResult {
/// // This is safe
/// update_all(value)
/// }
///
/// fn unsafe_update(value: u32) -> DispatchResult {
/// // this may panic if unsafe_update is not called within a storage transaction
/// update_all(value)
/// }
/// ```
pub use frame_support_procedural::require_transactional;
/// Convert the current crate version into a [`CrateVersion`](crate::traits::CrateVersion).
///
/// It uses the `CARGO_PKG_VERSION_MAJOR`, `CARGO_PKG_VERSION_MINOR` and
/// `CARGO_PKG_VERSION_PATCH` environment variables to fetch the crate version.
/// This means that the [`CrateVersion`](crate::traits::CrateVersion)
/// object will correspond to the version of the crate the macro is called in!
///
/// # Example
///
/// ```
/// # use frame_support::{traits::CrateVersion, crate_to_crate_version};
/// const Version: CrateVersion = crate_to_crate_version!();
/// ```
pub use frame_support_procedural::crate_to_crate_version;
/// Return Err of the expression: `return Err($expression);`.
///
/// Used as `fail!(expression)`.
#[macro_export]
macro_rules! fail {
( $y:expr ) => {{
return Err($y.into());
/// Evaluate `$x:expr` and if not true return `Err($y:expr)`.
///
/// Used as `ensure!(expression_to_ensure, expression_to_return_on_false)`.
#[macro_export]
macro_rules! ensure {
$crate::fail!($y);
/// Evaluate an expression, assert it returns an expected `Err` value and that
/// runtime storage has not been mutated (i.e. expression is a no-operation).
///
/// Used as `assert_noop(expression_to_assert, expected_error_expression)`.
(
$x:expr,
$y:expr $(,)?
) => {
let h = $crate::__private::storage_root($crate::__private::StateVersion::V1);
$crate::assert_err!($x, $y);
assert_eq!(
h,
$crate::__private::storage_root($crate::__private::StateVersion::V1),
"storage has been mutated"
);
/// Evaluate any expression and assert that runtime storage has not been mutated
/// (i.e. expression is a storage no-operation).
///
/// Used as `assert_storage_noop(expression_to_assert)`.
#[macro_export]
macro_rules! assert_storage_noop {
(
$x:expr
) => {
let h = $crate::__private::storage_root($crate::__private::StateVersion::V1);
assert_eq!(h, $crate::__private::storage_root($crate::__private::StateVersion::V1));
/// Assert an expression returns an error specified.
///
/// Used as `assert_err!(expression_to_assert, expected_error_expression)`
assert_eq!($x, Err($y.into()));
/// Assert an expression returns an error specified.
///
Sam Johnson
committed
/// This can be used on `DispatchResultWithPostInfo` when the post info should
/// be ignored.
#[macro_export]
macro_rules! assert_err_ignore_postinfo {
( $x:expr , $y:expr $(,)? ) => {
$crate::assert_err!($x.map(|_| ()).map_err(|e| e.error), $y);
/// Assert an expression returns error with the given weight.
#[macro_export]
macro_rules! assert_err_with_weight {
($call:expr, $err:expr, $weight:expr $(,)? ) => {
if let Err(dispatch_err_with_post) = $call {
$crate::assert_err!($call.map(|_| ()).map_err(|e| e.error), $err);
assert_eq!(dispatch_err_with_post.post_info.actual_weight, $weight);
::core::panic!("expected Err(_), got Ok(_).")
/// Panic if an expression doesn't evaluate to `Ok`.
///
/// Used as `assert_ok!(expression_to_assert, expected_ok_expression)`,
/// or `assert_ok!(expression_to_assert)` which would assert against `Ok(())`.
( $x:expr $(,)? ) => {
let is = $x;
match is {
Ok(_) => (),
_ => assert!(false, "Expected Ok(_). Got {:#?}", is),
}
( $x:expr, $y:expr $(,)? ) => {
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
/// Assert that the maximum encoding size does not exceed the value defined in
/// [`MAX_MODULE_ERROR_ENCODED_SIZE`] during compilation.
///
/// This macro is intended to be used in conjunction with `tt_call!`.
#[macro_export]
macro_rules! assert_error_encoded_size {
{
path = [{ $($path:ident)::+ }]
runtime = [{ $runtime:ident }]
assert_message = [{ $assert_message:literal }]
error = [{ $error:ident }]
} => {
const _: () = assert!(
<
$($path::)+$error<$runtime> as $crate::traits::PalletError
>::MAX_ENCODED_SIZE <= $crate::MAX_MODULE_ERROR_ENCODED_SIZE,
$assert_message
);
};
{
path = [{ $($path:ident)::+ }]
runtime = [{ $runtime:ident }]
assert_message = [{ $assert_message:literal }]
} => {};
}
/// Do something hypothetically by rolling back any changes afterwards.
///
/// Returns the original result of the closure.
#[macro_export]
#[cfg(feature = "experimental")]
macro_rules! hypothetically {
( $e:expr ) => {
$crate::storage::transactional::with_transaction(|| -> $crate::__private::TransactionOutcome<Result<_, $crate::__private::DispatchError>> {
$crate::__private::TransactionOutcome::Rollback(Ok($e))
},
).expect("Always returning Ok; qed")
};
}
/// Assert something to be *hypothetically* `Ok`, without actually committing it.
///
/// Reverts any storage changes made by the closure.
#[macro_export]
#[cfg(feature = "experimental")]
macro_rules! hypothetically_ok {
($e:expr $(, $args:expr)* $(,)?) => {
$crate::assert_ok!($crate::hypothetically!($e) $(, $args)*);
};
}
Bastian Köcher
committed
#[doc(hidden)]
pub use serde::{Deserialize, Serialize};
Drew Stone
committed
#[doc(hidden)]
#[cfg(not(no_std))]
pub use macro_magic;
/// Prelude to be used for pallet testing, for ease of use.
#[cfg(feature = "std")]
pub mod testing_prelude {
pub use super::{
assert_err, assert_err_ignore_postinfo, assert_err_with_weight, assert_error_encoded_size,
assert_noop, assert_ok, assert_storage_noop, parameter_types, traits::Get,
};
pub use sp_arithmetic::assert_eq_error_rate;
pub use sp_runtime::{bounded_btree_map, bounded_vec};
/// Prelude to be used alongside pallet macro, for ease of use.
pub mod pallet_prelude {
dispatch::{DispatchClass, DispatchResult, DispatchResultWithPostInfo, Parameter, Pays},
ensure,
inherent::{InherentData, InherentIdentifier, ProvideInherent},
storage,
storage::{
bounded_btree_map::BoundedBTreeMap,
bounded_btree_set::BoundedBTreeSet,
bounded_vec::BoundedVec,
types::{
CountedStorageMap, CountedStorageNMap, Key as NMapKey, OptionQuery, ResultQuery,
StorageDoubleMap, StorageMap, StorageNMap, StorageValue, ValueQuery,
thiolliere
committed
traits::{
BuildGenesisConfig, ConstU32, EnsureOrigin, Get, GetDefault, GetStorageVersion, Hooks,
IsType, PalletInfoAccess, StorageInfoTrait, StorageVersion, Task, TypedGet,
thiolliere
committed
},
Blake2_128, Blake2_128Concat, Blake2_256, CloneNoBound, DebugNoBound, EqNoBound, Identity,
PartialEqNoBound, RuntimeDebugNoBound, Twox128, Twox256, Twox64Concat,
pub use codec::{Decode, Encode, MaxEncodedLen};
Sam Johnson
committed
pub use frame_support::pallet_macros::*;
gupnik
committed
/// The optional attribute `#[inject_runtime_type]` can be attached to `RuntimeCall`,
/// `RuntimeEvent`, `RuntimeOrigin` or `PalletInfo` in an impl statement that has
/// `#[register_default_impl]` attached to indicate that this item is generated by
/// `construct_runtime`.
///
/// Attaching this attribute to such an item ensures that the combined impl generated via
/// [`#[derive_impl(..)]`](`frame_support::derive_impl`) will use the correct
/// type auto-generated by
/// `construct_runtime!`.
gupnik
committed
#[doc = docify::embed!("src/tests/inject_runtime_type.rs", derive_impl_works_with_runtime_type_injection)]
///
/// However, if `no_aggregated_types` is specified while using
/// `[`#[derive_impl(..)]`](`frame_support::derive_impl`)`, then these items are attached
gupnik
committed
/// verbatim to the combined impl.
#[doc = docify::embed!("src/tests/inject_runtime_type.rs", derive_impl_works_with_no_aggregated_types)]
pub use frame_support_procedural::inject_runtime_type;
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::{
InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource,
TransactionTag, TransactionValidity, TransactionValidityError, UnknownTransaction,
ValidTransaction,
DispatchError, RuntimeDebug, MAX_MODULE_ERROR_ENCODED_SIZE,
pub use sp_std::marker::PhantomData;
pub use sp_weights::Weight;
/// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to
/// specify pallet information.
/// The struct must be defined as follows:
/// #[frame_support::pallet]
/// mod pallet {
/// #[pallet::pallet] // <- the macro
/// pub struct Pallet<T>(_); // <- the struct definition
/// #[pallet::config]
/// pub trait Config: frame_system::Config {}
Sam Johnson
committed
/// I.e. a regular struct definition named `Pallet`, with generic T and no where clause.
Sam Johnson
committed
/// ## Macro expansion:
///
/// The macro adds this attribute to the Pallet struct definition:
Sam Johnson
committed
/// ```ignore
/// #[derive(
/// frame_support::CloneNoBound,
/// frame_support::EqNoBound,
/// frame_support::PartialEqNoBound,
/// frame_support::RuntimeDebugNoBound,
/// )]
/// ```
/// and replaces the type `_` with `PhantomData<T>`.
Sam Johnson
committed
///
/// It also implements on the pallet:
Sam Johnson
committed
///
/// * [`GetStorageVersion`](frame_support::traits::GetStorageVersion)
/// * [`OnGenesis`](frame_support::traits::OnGenesis): contains some logic to write the pallet
/// version into storage.
/// * [`PalletInfoAccess`](frame_support::traits::PalletInfoAccess) to ease access to pallet
/// information given by [`frame_support::traits::PalletInfo`]. (The implementation uses the
/// associated type [`frame_support::traits::PalletInfo`]).
/// * [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) to give information about
/// storages.
Sam Johnson
committed
///
/// If the attribute `set_storage_max_encoded_len` is set then the macro calls
/// [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) for each storage in the
/// implementation of [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) for the
/// pallet. Otherwise it implements
/// [`StorageInfoTrait`](frame_support::traits::StorageInfoTrait) for the pallet using the
/// [`PartialStorageInfoTrait`](frame_support::traits::PartialStorageInfoTrait)
/// implementation of storages.
/// ## Dev Mode (`#[pallet(dev_mode)]`)
Sam Johnson
committed
///
/// Specifying the argument `dev_mode` will allow you to enable dev mode for a pallet. The
/// aim of dev mode is to loosen some of the restrictions and requirements placed on
/// production pallets for easy tinkering and development. Dev mode pallets should not be
/// used in production. Enabling dev mode has the following effects:
Sam Johnson
committed
///
/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By
/// default, dev mode pallets will assume a weight of zero (`0`) if a weight is not
/// specified. This is equivalent to specifying `#[weight(0)]` on all calls that do not
/// specify a weight.
/// * Call indices no longer need to be specified on every `#[pallet::call]` declaration. By
/// default, dev mode pallets will assume a call index based on the order of the call.