#![cfg_attr(not(feature = "std"), no_std)]
#[doc(hidden)]
extern crate self as frame_support;
#[doc(hidden)]
extern crate alloc;
pub const MAX_EXTRINSIC_DEPTH: u32 = 256;
#[doc(hidden)]
pub mod __private {
pub use alloc::{
boxed::Box,
fmt::Debug,
rc::Rc,
string::String,
vec,
vec::{IntoIter, Vec},
};
pub use codec;
pub use frame_metadata as metadata;
pub use log;
pub use paste;
pub use scale_info;
pub use serde;
pub use serde_json;
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::{AsSystemOriginSigner, AsTransactionAuthorizedOrigin, 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::*;
}
#[macro_use]
pub mod dispatch;
pub mod crypto;
pub mod dispatch_context;
mod hash;
pub mod inherent;
pub mod instances;
pub mod migrations;
pub mod storage;
#[cfg(test)]
mod tests;
pub mod traits;
pub mod view_functions;
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 scale_info::TypeInfo;
use sp_runtime::TypeId;
pub const LOG_TARGET: &str = "runtime::frame-support";
#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
pub enum Never {}
#[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";
}
#[doc = docify::embed!("src/tests/storage_alias.rs", verbatim_attribute)]
#[doc = docify::embed!("src/tests/storage_alias.rs", pallet_name_attribute)]
#[doc = docify::embed!("src/tests/storage_alias.rs", dynamic_attribute)]
#[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;
#[cfg(feature = "experimental")]
pub mod dynamic_params {
pub use frame_support_procedural::{
dynamic_aggregated_params_internal, dynamic_pallet_params, dynamic_params,
};
}
#[macro_export]
macro_rules! parameter_types {
(
$( #[ $attr:meta ] )*
$vis:vis const $name:ident $(< $($ty_params:ident),* >)?: $type:ty = $value:expr;
$( $rest:tt )*
) => (
$( #[ $attr ] )*
$vis struct $name $(
< $($ty_params),* >( $(core::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 ] )*
$vis struct $name $(
< $($ty_params),* >( $(core::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 ] )*
$vis struct $name $(
< $($ty_params),* >( $(core::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),* > {
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),* > {
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)*) => {
#[allow(unused)]
impl< $($ty_params),* > $name< $($ty_params),* > {
pub fn key() -> [u8; 16] {
$crate::__private::sp_crypto_hashing_proc_macro::twox_128!(b":", $name, b":")
}
pub fn set(value: &$type) {
$crate::storage::unhashed::put(&Self::key(), value);
}
#[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);
}
#[allow(unused)]
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
}
#[allow(unused)]
pub fn take() -> $type {
let current = Self::get();
Self::set($value);
current
}
#[allow(unused)]
pub fn reset() {
Self::set($value);
}
}
)*
}
};
(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_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::Vec<$type> { vec![$value] }
fn count() -> usize { 1 }
#[cfg(feature = "runtime-benchmarks")]
fn add(_: &$type) {}
}
impl $crate::traits::Contains<$type> for $name {
fn contains(t: &$type) -> bool { &$value == t }
}
}
}
#[macro_export]
macro_rules! runtime_print {
($($arg:tt)+) => {
{
use core::fmt::Write;
let mut msg = $crate::__private::String::default();
let _ = core::write!(&mut msg, $($arg)+);
$crate::__private::sp_io::misc::print_utf8(msg.as_bytes())
}
}
}
pub fn debug(data: &impl core::fmt::Debug) {
runtime_print!("{:?}", data);
}
#[doc(inline)]
pub use frame_support_procedural::{
construct_runtime, match_and_insert, transactional, PalletError, RuntimeDebugNoBound,
};
pub use frame_support_procedural::runtime;
#[doc(hidden)]
pub use frame_support_procedural::{__create_tt_macro, __generate_dummy_part_checker};
pub use frame_support_procedural::CloneNoBound;
pub use frame_support_procedural::EqNoBound;
pub use frame_support_procedural::PartialEqNoBound;
pub use frame_support_procedural::OrdNoBound;
pub use frame_support_procedural::PartialOrdNoBound;
pub use frame_support_procedural::DebugNoBound;
pub use frame_support_procedural::DefaultNoBound;
pub use frame_support_procedural::require_transactional;
pub use frame_support_procedural::crate_to_crate_version;
#[macro_export]
macro_rules! fail {
( $y:expr ) => {{
return Err($y.into());
}};
}
#[macro_export]
macro_rules! ensure {
( $x:expr, $y:expr $(,)? ) => {{
if !$x {
$crate::fail!($y);
}
}};
}
#[macro_export]
macro_rules! assert_noop {
(
$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"
);
};
}
#[macro_export]
macro_rules! assert_storage_noop {
(
$x:expr
) => {
let h = $crate::__private::storage_root($crate::__private::StateVersion::V1);
$x;
assert_eq!(h, $crate::__private::storage_root($crate::__private::StateVersion::V1));
};
}
#[macro_export]
macro_rules! assert_err {
( $x:expr , $y:expr $(,)? ) => {
assert_eq!($x, Err($y.into()));
};
}
#[macro_export]
macro_rules! assert_err_ignore_postinfo {
( $x:expr , $y:expr $(,)? ) => {
$crate::assert_err!($x.map(|_| ()).map_err(|e| e.error), $y);
};
}
#[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);
} else {
::core::panic!("expected Err(_), got Ok(_).")
}
};
}
#[macro_export]
macro_rules! assert_ok {
( $x:expr $(,)? ) => {
let is = $x;
match is {
Ok(_) => (),
_ => assert!(false, "Expected Ok(_). Got {:#?}", is),
}
};
( $x:expr, $y:expr $(,)? ) => {
assert_eq!($x, Ok($y));
};
}
#[macro_export]
macro_rules! assert_error_encoded_size {
{
path = [{ $($path:ident)::+ }]
runtime = [{ $runtime:ident }]
assert_message = [{ $assert_message:literal }]
error = [{ $error:ident }]
} => {
#[allow(deprecated)]
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 }]
} => {};
}
#[macro_export]
macro_rules! hypothetically {
( $e:expr ) => {
$crate::storage::transactional::with_transaction(|| -> $crate::__private::TransactionOutcome<::core::result::Result<_, $crate::__private::DispatchError>> {
$crate::__private::TransactionOutcome::Rollback(::core::result::Result::Ok($e))
},
).expect("Always returning Ok; qed")
};
}
#[macro_export]
macro_rules! hypothetically_ok {
($e:expr $(, $args:expr)* $(,)?) => {
$crate::assert_ok!($crate::hypothetically!($e) $(, $args)*);
};
}
#[doc(hidden)]
pub use serde::{Deserialize, Serialize};
#[doc(hidden)]
pub use macro_magic;
#[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};
}
pub mod pallet_prelude {
pub use crate::{
defensive, defensive_assert,
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,
},
weak_bounded_vec::WeakBoundedVec,
StorageList,
},
traits::{
Authorize, BuildGenesisConfig, ConstU32, ConstUint, EnsureOrigin, Get, GetDefault,
GetStorageVersion, Hooks, IsType, OriginTrait, PalletInfoAccess, StorageInfoTrait,
StorageVersion, Task, TypedGet,
},
Blake2_128, Blake2_128Concat, Blake2_256, CloneNoBound, DebugNoBound, EqNoBound, Identity,
PartialEqNoBound, RuntimeDebugNoBound, Twox128, Twox256, Twox64Concat,
};
pub use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
pub use core::marker::PhantomData;
pub use frame_support::pallet_macros::*;
pub use frame_support_procedural::{inject_runtime_type, register_default_impl};
pub use scale_info::TypeInfo;
pub use sp_inherents::MakeFatalError;
pub use sp_runtime::{
traits::{
CheckedAdd, CheckedConversion, CheckedDiv, CheckedMul, CheckedShl, CheckedShr,
CheckedSub, MaybeSerializeDeserialize, Member, One, ValidateResult, ValidateUnsigned,
Zero,
},
transaction_validity::{
InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource,
TransactionTag, TransactionValidity, TransactionValidityError,
TransactionValidityWithRefund, UnknownTransaction, ValidTransaction,
},
DispatchError, RuntimeDebug, MAX_MODULE_ERROR_ENCODED_SIZE,
};
pub use sp_weights::Weight;
}
pub use frame_support_procedural::pallet;
pub mod pallet_macros {
pub use frame_support_procedural::whitelist_storage;
pub use frame_support_procedural::weight;
pub use frame_support_procedural::disable_try_decode_storage;
pub use frame_support_procedural::unbounded;
pub use frame_support_procedural::storage_prefix;
pub use frame_support_procedural::no_default_bounds;
pub use frame_support_procedural::no_default;
pub use frame_support_procedural::pallet_section;
pub use frame_support_procedural::inherent;
pub use frame_support_procedural::import_section;
pub use frame_support_procedural::getter;
pub use frame_support_procedural::extra_constants;
#[rustfmt::skip]
pub use frame_support_procedural::disable_frame_system_supertrait_check;
pub use frame_support_procedural::config;
pub use frame_support_procedural::composite_enum;
pub use frame_support_procedural::validate_unsigned;
pub use frame_support_procedural::view_functions;
pub use frame_support_procedural::type_value;
pub use frame_support_procedural::storage_version;
pub use frame_support_procedural::hooks;
pub use frame_support_procedural::generate_deposit;
pub use frame_support_procedural::feeless_if;
pub use frame_support_procedural::error;
pub use frame_support_procedural::event;
pub use frame_support_procedural::include_metadata;
pub use frame_support_procedural::call;
pub use frame_support_procedural::call_index;
pub use frame_support_procedural::compact;
pub use frame_support_procedural::genesis_config;
pub use frame_support_procedural::genesis_build;
pub use frame_support_procedural::constant;
#[doc = docify::embed!("src/lib.rs", example_storage_value_append)]
#[doc = docify::embed!("src/lib.rs", example_storage_value_try_append)]
#[doc = docify::embed!("src/lib.rs", example_storage_value_decode_len)]
#[doc = docify::embed!("src/lib.rs", example_storage_value_map_prefixes)]
pub use frame_support_procedural::storage;
pub use frame_support_procedural::{
authorize, task_condition, task_index, task_list, task_weight, tasks_experimental,
weight_of_authorize,
};
pub use frame_support_procedural::origin;
}
#[deprecated(note = "Will be removed after July 2023; Use `sp_runtime::traits` directly instead.")]
pub mod error {
#[doc(hidden)]
pub use sp_runtime::traits::{BadOrigin, LookupError};
}
#[doc(inline)]
pub use frame_support_procedural::register_default_impl;
sp_core::generate_feature_enabled_macro!(std_enabled, feature = "std", $);
sp_core::generate_feature_enabled_macro!(try_runtime_enabled, feature = "try-runtime", $);
sp_core::generate_feature_enabled_macro!(try_runtime_or_std_enabled, any(feature = "try-runtime", feature = "std"), $);
sp_core::generate_feature_enabled_macro!(try_runtime_and_std_not_enabled, all(not(feature = "try-runtime"), not(feature = "std")), $);
pub mod genesis_builder_helper;
pub mod generate_genesis_config;
#[cfg(test)]
mod test {
use crate::{
hash::*,
storage::types::{StorageMap, StorageValue, ValueQuery},
traits::{ConstU32, StorageInstance},
BoundedVec,
};
use sp_io::{hashing::twox_128, TestExternalities};
struct Prefix;
impl StorageInstance for Prefix {
fn pallet_prefix() -> &'static str {
"test"
}
const STORAGE_PREFIX: &'static str = "foo";
}
struct Prefix1;
impl StorageInstance for Prefix1 {
fn pallet_prefix() -> &'static str {
"test"
}
const STORAGE_PREFIX: &'static str = "MyVal";
}
struct Prefix2;
impl StorageInstance for Prefix2 {
fn pallet_prefix() -> &'static str {
"test"
}
const STORAGE_PREFIX: &'static str = "MyMap";
}
#[docify::export]
#[test]
pub fn example_storage_value_try_append() {
type MyVal = StorageValue<Prefix, BoundedVec<u8, ConstU32<10>>, ValueQuery>;
TestExternalities::default().execute_with(|| {
MyVal::set(BoundedVec::try_from(vec![42, 43]).unwrap());
assert_eq!(MyVal::get(), vec![42, 43]);
assert_ok!(MyVal::try_append(40));
assert_eq!(MyVal::get(), vec![42, 43, 40]);
});
}
#[docify::export]
#[test]
pub fn example_storage_value_append() {
type MyVal = StorageValue<Prefix, Vec<u8>, ValueQuery>;
TestExternalities::default().execute_with(|| {
MyVal::set(vec![42, 43]);
assert_eq!(MyVal::get(), vec![42, 43]);
MyVal::append(40);
assert_eq!(MyVal::get(), vec![42, 43, 40]);
});
}
#[docify::export]
#[test]
pub fn example_storage_value_decode_len() {
type MyVal = StorageValue<Prefix, BoundedVec<u8, ConstU32<10>>, ValueQuery>;
TestExternalities::default().execute_with(|| {
MyVal::set(BoundedVec::try_from(vec![42, 43]).unwrap());
assert_eq!(MyVal::decode_len().unwrap(), 2);
});
}
#[docify::export]
#[test]
pub fn example_storage_value_map_prefixes() {
type MyVal = StorageValue<Prefix1, u32, ValueQuery>;
type MyMap = StorageMap<Prefix2, Blake2_128Concat, u16, u32, ValueQuery>;
TestExternalities::default().execute_with(|| {
assert_eq!(
MyVal::hashed_key().to_vec(),
[twox_128(b"test"), twox_128(b"MyVal")].concat()
);
let mut k: Vec<u8> = vec![];
k.extend(&twox_128(b"test"));
k.extend(&twox_128(b"MyMap"));
k.extend(&1u16.blake2_128_concat());
assert_eq!(MyMap::hashed_key_for(1).to_vec(), k);
});
}
}