pub use crate::{
codec::{
Codec, Decode, Encode, EncodeAsRef, EncodeLike, HasCompact, Input, MaxEncodedLen, Output,
},
scale_info::TypeInfo,
sp_std::{
fmt, marker,
prelude::{Clone, Eq, PartialEq, Vec},
result,
},
traits::{
CallMetadata, GetCallMetadata, GetCallName, GetStorageVersion, UnfilteredDispatchable,
},
};
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_runtime::{
generic::{CheckedExtrinsic, UncheckedExtrinsic},
traits::SignedExtension,
};
pub use sp_runtime::{
traits::Dispatchable, transaction_validity::TransactionPriority, DispatchError, RuntimeDebug,
};
pub use sp_weights::Weight;
pub type DispatchResultWithPostInfo = sp_runtime::DispatchResultWithInfo<PostDispatchInfo>;
pub type DispatchResult = Result<(), sp_runtime::DispatchError>;
pub type DispatchErrorWithPostInfo = sp_runtime::DispatchErrorWithPostInfo<PostDispatchInfo>;
pub trait Callable<T> {
type RuntimeCall: UnfilteredDispatchable + Codec + Clone + PartialEq + Eq;
}
pub type CallableCallFor<A, R> = <A as Callable<R>>::RuntimeCall;
#[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub enum RawOrigin<AccountId> {
Root,
Signed(AccountId),
None,
}
impl<AccountId> From<Option<AccountId>> for RawOrigin<AccountId> {
fn from(s: Option<AccountId>) -> RawOrigin<AccountId> {
match s {
Some(who) => RawOrigin::Signed(who),
None => RawOrigin::None,
}
}
}
pub trait Parameter: Codec + EncodeLike + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
impl<T> Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
pub trait ClassifyDispatch<T> {
fn classify_dispatch(&self, target: T) -> DispatchClass;
}
pub trait PaysFee<T> {
fn pays_fee(&self, _target: T) -> Pays;
}
#[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode, TypeInfo)]
pub enum Pays {
Yes,
No,
}
impl Default for Pays {
fn default() -> Self {
Self::Yes
}
}
impl From<Pays> for PostDispatchInfo {
fn from(pays_fee: Pays) -> Self {
Self { actual_weight: None, pays_fee }
}
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug, TypeInfo)]
pub enum DispatchClass {
Normal,
Operational,
Mandatory,
}
impl Default for DispatchClass {
fn default() -> Self {
Self::Normal
}
}
impl DispatchClass {
pub fn all() -> &'static [DispatchClass] {
&[DispatchClass::Normal, DispatchClass::Operational, DispatchClass::Mandatory]
}
pub fn non_mandatory() -> &'static [DispatchClass] {
&[DispatchClass::Normal, DispatchClass::Operational]
}
}
pub trait OneOrMany<T> {
type Iter: Iterator<Item = T>;
fn into_iter(self) -> Self::Iter;
}
impl OneOrMany<DispatchClass> for DispatchClass {
type Iter = sp_std::iter::Once<DispatchClass>;
fn into_iter(self) -> Self::Iter {
sp_std::iter::once(self)
}
}
impl<'a> OneOrMany<DispatchClass> for &'a [DispatchClass] {
type Iter = sp_std::iter::Cloned<sp_std::slice::Iter<'a, DispatchClass>>;
fn into_iter(self) -> Self::Iter {
self.iter().cloned()
}
}
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
pub struct DispatchInfo {
pub weight: Weight,
pub class: DispatchClass,
pub pays_fee: Pays,
}
pub trait GetDispatchInfo {
fn get_dispatch_info(&self) -> DispatchInfo;
}
impl GetDispatchInfo for () {
fn get_dispatch_info(&self) -> DispatchInfo {
DispatchInfo::default()
}
}
pub fn extract_actual_weight(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Weight {
match result {
Ok(post_info) => post_info,
Err(err) => &err.post_info,
}
.calc_actual_weight(info)
}
pub fn extract_actual_pays_fee(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Pays {
match result {
Ok(post_info) => post_info,
Err(err) => &err.post_info,
}
.pays_fee(info)
}
#[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
pub struct PostDispatchInfo {
pub actual_weight: Option<Weight>,
pub pays_fee: Pays,
}
impl PostDispatchInfo {
pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight {
info.weight - self.calc_actual_weight(info)
}
pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight {
if let Some(actual_weight) = self.actual_weight {
actual_weight.min(info.weight)
} else {
info.weight
}
}
pub fn pays_fee(&self, info: &DispatchInfo) -> Pays {
if info.pays_fee == Pays::No || self.pays_fee == Pays::No {
Pays::No
} else {
Pays::Yes
}
}
}
impl From<()> for PostDispatchInfo {
fn from(_: ()) -> Self {
Self { actual_weight: None, pays_fee: Default::default() }
}
}
impl sp_runtime::traits::Printable for PostDispatchInfo {
fn print(&self) {
"actual_weight=".print();
match self.actual_weight {
Some(weight) => weight.print(),
None => "max-weight".print(),
};
"pays_fee=".print();
match self.pays_fee {
Pays::Yes => "Yes".print(),
Pays::No => "No".print(),
}
}
}
pub trait WithPostDispatchInfo {
fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo;
}
impl<T> WithPostDispatchInfo for T
where
T: Into<DispatchError>,
{
fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo {
DispatchErrorWithPostInfo {
post_info: PostDispatchInfo {
actual_weight: Some(actual_weight),
pays_fee: Default::default(),
},
error: self.into(),
}
}
}
impl<Address, Call, Signature, Extra> GetDispatchInfo
for UncheckedExtrinsic<Address, Call, Signature, Extra>
where
Call: GetDispatchInfo,
Extra: SignedExtension,
{
fn get_dispatch_info(&self) -> DispatchInfo {
self.function.get_dispatch_info()
}
}
impl<AccountId, Call, Extra> GetDispatchInfo for CheckedExtrinsic<AccountId, Call, Extra>
where
Call: GetDispatchInfo,
{
fn get_dispatch_info(&self) -> DispatchInfo {
self.function.get_dispatch_info()
}
}
#[cfg(feature = "std")]
impl<Call: Encode + GetDispatchInfo, Extra: Encode> GetDispatchInfo
for sp_runtime::testing::TestXt<Call, Extra>
{
fn get_dispatch_info(&self) -> DispatchInfo {
DispatchInfo {
weight: Weight::from_ref_time(self.encode().len() as _),
pays_fee: Pays::Yes,
class: self.call.get_dispatch_info().class,
}
}
}
#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct PerDispatchClass<T> {
normal: T,
operational: T,
mandatory: T,
}
impl<T> PerDispatchClass<T> {
pub fn new(val: impl Fn(DispatchClass) -> T) -> Self {
Self {
normal: val(DispatchClass::Normal),
operational: val(DispatchClass::Operational),
mandatory: val(DispatchClass::Mandatory),
}
}
pub fn get_mut(&mut self, class: DispatchClass) -> &mut T {
match class {
DispatchClass::Operational => &mut self.operational,
DispatchClass::Normal => &mut self.normal,
DispatchClass::Mandatory => &mut self.mandatory,
}
}
pub fn get(&self, class: DispatchClass) -> &T {
match class {
DispatchClass::Normal => &self.normal,
DispatchClass::Operational => &self.operational,
DispatchClass::Mandatory => &self.mandatory,
}
}
}
impl<T: Clone> PerDispatchClass<T> {
pub fn set(&mut self, new: T, class: impl OneOrMany<DispatchClass>) {
for class in class.into_iter() {
*self.get_mut(class) = new.clone();
}
}
}
impl PerDispatchClass<Weight> {
pub fn total(&self) -> Weight {
let mut sum = Weight::zero();
for class in DispatchClass::all() {
sum = sum.saturating_add(*self.get(*class));
}
sum
}
pub fn add(&mut self, weight: Weight, class: DispatchClass) {
let value = self.get_mut(class);
*value = value.saturating_add(weight);
}
pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> {
let value = self.get_mut(class);
*value = value.checked_add(&weight).ok_or(())?;
Ok(())
}
pub fn sub(&mut self, weight: Weight, class: DispatchClass) {
let value = self.get_mut(class);
*value = value.saturating_sub(weight);
}
}
pub trait WeighData<T> {
fn weigh_data(&self, target: T) -> Weight;
}
impl<T> WeighData<T> for Weight {
fn weigh_data(&self, _: T) -> Weight {
return *self
}
}
impl<T> PaysFee<T> for (Weight, DispatchClass, Pays) {
fn pays_fee(&self, _: T) -> Pays {
self.2
}
}
impl<T> WeighData<T> for (Weight, DispatchClass) {
fn weigh_data(&self, args: T) -> Weight {
return self.0.weigh_data(args)
}
}
impl<T> WeighData<T> for (Weight, DispatchClass, Pays) {
fn weigh_data(&self, args: T) -> Weight {
return self.0.weigh_data(args)
}
}
impl<T> ClassifyDispatch<T> for (Weight, DispatchClass) {
fn classify_dispatch(&self, _: T) -> DispatchClass {
self.1
}
}
impl<T> PaysFee<T> for (Weight, DispatchClass) {
fn pays_fee(&self, _: T) -> Pays {
Pays::Yes
}
}
impl<T> WeighData<T> for (Weight, Pays) {
fn weigh_data(&self, args: T) -> Weight {
return self.0.weigh_data(args)
}
}
impl<T> ClassifyDispatch<T> for (Weight, Pays) {
fn classify_dispatch(&self, _: T) -> DispatchClass {
DispatchClass::Normal
}
}
impl<T> PaysFee<T> for (Weight, Pays) {
fn pays_fee(&self, _: T) -> Pays {
self.1
}
}
impl From<(Option<Weight>, Pays)> for PostDispatchInfo {
fn from(post_weight_info: (Option<Weight>, Pays)) -> Self {
let (actual_weight, pays_fee) = post_weight_info;
Self { actual_weight, pays_fee }
}
}
impl From<Option<Weight>> for PostDispatchInfo {
fn from(actual_weight: Option<Weight>) -> Self {
Self { actual_weight, pays_fee: Default::default() }
}
}
impl<T> ClassifyDispatch<T> for Weight {
fn classify_dispatch(&self, _: T) -> DispatchClass {
DispatchClass::Normal
}
}
impl<T> PaysFee<T> for Weight {
fn pays_fee(&self, _: T) -> Pays {
Pays::Yes
}
}
impl<T> ClassifyDispatch<T> for (Weight, DispatchClass, Pays) {
fn classify_dispatch(&self, _: T) -> DispatchClass {
self.1
}
}
impl From<Option<u64>> for PostDispatchInfo {
fn from(maybe_actual_computation: Option<u64>) -> Self {
let actual_weight = match maybe_actual_computation {
Some(actual_computation) => Some(Weight::zero().set_ref_time(actual_computation)),
None => None,
};
Self { actual_weight, pays_fee: Default::default() }
}
}
impl From<(Option<u64>, Pays)> for PostDispatchInfo {
fn from(post_weight_info: (Option<u64>, Pays)) -> Self {
let (maybe_actual_time, pays_fee) = post_weight_info;
let actual_weight = match maybe_actual_time {
Some(actual_time) => Some(Weight::zero().set_ref_time(actual_time)),
None => None,
};
Self { actual_weight, pays_fee }
}
}
impl<T> ClassifyDispatch<T> for u64 {
fn classify_dispatch(&self, _: T) -> DispatchClass {
DispatchClass::Normal
}
}
impl<T> PaysFee<T> for u64 {
fn pays_fee(&self, _: T) -> Pays {
Pays::Yes
}
}
impl<T> WeighData<T> for u64 {
fn weigh_data(&self, _: T) -> Weight {
return Weight::zero().set_ref_time(*self)
}
}
impl<T> WeighData<T> for (u64, DispatchClass, Pays) {
fn weigh_data(&self, args: T) -> Weight {
return self.0.weigh_data(args)
}
}
impl<T> ClassifyDispatch<T> for (u64, DispatchClass, Pays) {
fn classify_dispatch(&self, _: T) -> DispatchClass {
self.1
}
}
impl<T> PaysFee<T> for (u64, DispatchClass, Pays) {
fn pays_fee(&self, _: T) -> Pays {
self.2
}
}
impl<T> WeighData<T> for (u64, DispatchClass) {
fn weigh_data(&self, args: T) -> Weight {
return self.0.weigh_data(args)
}
}
impl<T> ClassifyDispatch<T> for (u64, DispatchClass) {
fn classify_dispatch(&self, _: T) -> DispatchClass {
self.1
}
}
impl<T> PaysFee<T> for (u64, DispatchClass) {
fn pays_fee(&self, _: T) -> Pays {
Pays::Yes
}
}
impl<T> WeighData<T> for (u64, Pays) {
fn weigh_data(&self, args: T) -> Weight {
return self.0.weigh_data(args)
}
}
impl<T> ClassifyDispatch<T> for (u64, Pays) {
fn classify_dispatch(&self, _: T) -> DispatchClass {
DispatchClass::Normal
}
}
impl<T> PaysFee<T> for (u64, Pays) {
fn pays_fee(&self, _: T) -> Pays {
self.1
}
}
#[macro_export]
macro_rules! decl_module {
(
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident
$( <I>, I: $instantiable:path $( = $module_default_instance:path )? )?
>
for enum $call_type:ident where origin: $origin_type:ty $(, $where_ty:ty: $where_bound:path )* $(,)? {
$( $t:tt )*
}
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name $(<I>, I: $instantiable $(= $module_default_instance)?)?
>
for enum $call_type where origin: $origin_type, system = frame_system
{ $( $where_ty: $where_bound ),* }
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
[]
$($t)*
);
};
(
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident
$( <I>, I: $instantiable:path $( = $module_default_instance:path )? )?
>
for enum $call_type:ident where
origin: $origin_type:ty,
system = $system:ident
$(, $where_ty:ty: $where_bound:path )*
$(,)?
{
$($t:tt)*
}
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name $(<I>, I: $instantiable $( = $module_default_instance )? )?
>
for enum $call_type where origin: $origin_type, system = $system
{ $( $where_ty: $where_bound ),* }
{}
{}
{}
{}
{}
{}
{}
{}
{}
{}
[]
$($t)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{}
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$vis:vis fn deposit_event() = default;
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $vis fn deposit_event() = default; }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{}
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$vis:vis fn deposit_event
$($rest:tt)*
) => {
compile_error!(
"`deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;`"
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )+ }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$vis:vis fn deposit_event() = default;
$($rest:tt)*
) => {
compile_error!("`deposit_event` can only be passed once as input.");
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{}
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{
fn on_finalize( $( $param_name : $param ),* ) { $( $impl )* }
}
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{}
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"`on_finalize` can't be given weight attribute anymore, weight must be returned by \
`on_initialize` or `on_runtime_upgrade` instead"
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )+ }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!("`on_finalize` can only be passed once as input.");
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{}
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_idle($param_name1:ident : $param1:ty, $param_name2:ident: $param2:ty $(,)? ) -> $return:ty { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{
fn on_idle( $param_name1: $param1, $param_name2: $param2 ) -> $return { $( $impl )* }
}
{ $( $on_finalize:tt )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[weight = $weight:expr])?
fn on_idle
$($rest:tt)*
) => {
compile_error!("`on_idle` method is reserved and syntax doesn't match expected syntax.");
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{}
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"`on_runtime_upgrade` must return Weight, signature has changed."
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{}
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"`on_runtime_upgrade` can't be given weight attribute anymore, weight must be returned \
by the function directly."
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{}
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{
fn on_runtime_upgrade( $( $param_name : $param ),* ) -> $return { $( $impl )* }
}
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )+ }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!("`on_runtime_upgrade` can only be passed once as input.");
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{}
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn integrity_test() { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{
$(#[doc = $doc_attr])*
fn integrity_test() { $( $impl)* }
}
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )+ }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn integrity_test() { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!("`integrity_test` can only be passed once as input.");
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{}
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"`on_initialize` must return Weight, signature has changed."
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{}
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"`on_initialize` can't be given weight attribute anymore, weight must be returned \
by the function directly."
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{}
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{
fn on_initialize( $( $param_name : $param ),* ) -> $return { $( $impl )* }
}
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )+ }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!("`on_initialize` can only be passed once as input.");
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident
$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn offchain_worker( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?
>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ fn offchain_worker( $( $param_name : $param ),* ) { $( $impl )* } }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )+ }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
fn offchain_worker( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!("`offchain_worker` can only be passed once as input.");
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident
$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$( #[doc = $doc_attr:tt] )*
const $name:ident: $ty:ty = $value:expr;
$( $rest:tt )*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name
$( <I>, $instance: $instantiable $(= $module_default_instance)? )?
>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{
$( $constants )*
$( #[doc = $doc_attr ] )*
$name: $ty = $value;
}
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident:
$trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
type Error = $error_type:ty;
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name$(<I>, $instance: $instantiable $(= $module_default_instance)?)?
>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $error_type }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident:
$trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $($t:tt)* ]
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name$(<I>, $instance: $instantiable $(= $module_default_instance)?)?
>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ __NO_ERROR_DEFINED }
{ $( $integrity_test )* }
{ $( $storage_version )* }
[ $($t)* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident:
$trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
type StorageVersion = $storage_version:path;
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name$(<I>, $instance: $instantiable $(= $module_default_instance)?)?
>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
{ $storage_version }
[ $( $dispatchables )* ]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident
$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
$(#[$fn_attr:meta])*
$fn_vis:vis fn $fn_name:ident(
$origin:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty )* $(,)?
) $( -> $result:ty )* { $( $impl:tt )* }
$($rest:tt)*
) => {
$crate::decl_module!(@normalize
$(#[$attr])*
pub struct $mod_type<
$trait_instance: $trait_name$(<I>, $instance: $instantiable $(= $module_default_instance)?)?
>
for enum $call_type where origin: $origin_type, system = $system
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test)* }
{ $( $storage_version )* }
[
$( $dispatchables )*
$(#[doc = $doc_attr])*
#[weight = $weight]
$(#[$fn_attr])*
$fn_vis fn $fn_name(
$origin $( , $(#[$codec_attr])* $param_name : $param )*
) $( -> $result )* { $( $impl )* }
{ $($instance: $instantiable)? }
]
$($rest)*
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident:
$trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[$fn_attr:meta])*
$fn_vis:vis fn $fn_name:ident(
$from:ident $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)?
) $( -> $result:ty )* { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(concat!(
"Missing weight for ", stringify!($ident),
". Every dispatchable must have a #[weight] attribute."
)
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[weight = $weight:expr])?
$(#[$fn_attr:meta])*
$fn_vis:vis fn $fn_name:ident(
$origin:ident : T::RuntimeOrigin $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)?
) $( -> $result:ty )* { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"First parameter of dispatch should be marked `origin` only, with no type specified \
(a bit like `self`)."
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[weight = $weight:expr])?
$(#[$fn_attr:meta])*
$fn_vis:vis fn $fn_name:ident(
origin : $origin:ty $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)?
) $( -> $result:ty )* { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"First parameter of dispatch should be marked `origin` only, with no type specified \
(a bit like `self`)."
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
$(#[doc = $doc_attr:tt])*
$(#[weight = $weight:expr])?
$(#[$fn_attr:meta])*
$fn_vis:vis fn $fn_name:ident(
$( $(#[$codec_attr:ident])* $param_name:ident : $param:ty ),* $(,)?
) $( -> $result:ty )* { $( $impl:tt )* }
$($rest:tt)*
) => {
compile_error!(
"Implicit conversion to privileged function has been removed. \
First parameter of dispatch should be marked `origin`. \
For root-matching dispatch, also add `ensure_root(origin)?`."
);
};
(@normalize
$(#[$attr:meta])*
pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path $(= $module_default_instance:path)?)?>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
[ $( $dispatchables:tt )* ]
) => {
$crate::decl_module!(@imp
$(#[$attr])*
pub struct $mod_type<$trait_instance: $trait_name$(<I>, I: $instantiable $(= $module_default_instance)?)?>
for enum $call_type where origin: $origin_type, system = $system {
$( $dispatchables )*
}
{ $( $other_where_bounds )* }
{ $( $deposit_event )* }
{ $( $on_initialize )* }
{ $( $on_runtime_upgrade )* }
{ $( $on_idle )* }
{ $( $on_finalize )* }
{ $( $offchain )* }
{ $( $constants )* }
{ $( $error_type )* }
{ $( $integrity_test )* }
{ $( $storage_version )* }
);
};
(@call
$ignore:ident
$mod_type:ident<$trait_instance:ident $(, $instance:ident)?> $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ]
) => {
$crate::storage::with_storage_layer(|| {
<$mod_type<$trait_instance $(, $instance)?>>::$fn_name( $origin $(, $param_name )* ).map(Into::into).map_err(Into::into)
})
};
(@impl_deposit_event
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, I: $instantiable:path)?>;
$system:ident;
{ $( $other_where_bounds:tt )* }
) => {};
(@impl_deposit_event
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
$system:ident;
{ $( $other_where_bounds:tt )* }
$vis:vis fn deposit_event$(<$event_trait_instance:ident $(, $event_instance:ident)?>)?() = default;
) => {
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?> $module<$trait_instance $(, $instance)?>
where $( $other_where_bounds )*
{
$vis fn deposit_event(
event: impl Into<< $trait_instance as $trait_name $(<$instance>)? >::RuntimeEvent>
) {
<$system::Pallet<$trait_instance>>::deposit_event(event.into())
}
}
};
(@impl_on_initialize
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn on_initialize() -> $return:ty { $( $impl:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$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::Config>::BlockNumber) -> $return {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_initialize"));
{ $( $impl )* }
}
}
};
(@impl_on_initialize
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn on_initialize($param:ident : $param_ty:ty) -> $return:ty { $( $impl:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$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 {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_initialize"));
{ $( $impl )* }
}
}
};
(@impl_on_initialize
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OnInitialize<<$trait_instance as $system::Config>::BlockNumber>
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{}
};
(@impl_try_state_default
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
#[cfg(feature = "try-runtime")]
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::TryState<<$trait_instance as $system::Config>::BlockNumber>
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
fn try_state(
_: <$trait_instance as $system::Config>::BlockNumber,
_: $crate::traits::TryStateSelect,
) -> Result<(), &'static str> {
let pallet_name = <<
$trait_instance
as
$system::Config
>::PalletInfo as $crate::traits::PalletInfo>::name::<Self>().unwrap_or("<unknown pallet name>");
$crate::log::debug!(
target: $crate::LOG_TARGET,
"⚠️ pallet {} cannot have try-state because it is using decl_module!",
pallet_name,
);
Ok(())
}
}
};
(@impl_on_runtime_upgrade
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn on_runtime_upgrade() -> $return:ty { $( $impl:tt )* }
) => {
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OnRuntimeUpgrade
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
fn on_runtime_upgrade() -> $return {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_runtime_upgrade"));
let pallet_name = <<
$trait_instance
as
$system::Config
>::PalletInfo as $crate::traits::PalletInfo>::name::<Self>().unwrap_or("<unknown pallet name>");
$crate::log::info!(
target: $crate::LOG_TARGET,
"⚠️ {} declares internal migrations (which *might* execute). \
On-chain `{:?}` vs current storage version `{:?}`",
pallet_name,
<Self as $crate::traits::GetStorageVersion>::on_chain_storage_version(),
<Self as $crate::traits::GetStorageVersion>::current_storage_version(),
);
{ $( $impl )* }
}
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<$crate::sp_std::vec::Vec<u8>, &'static str> {
Ok($crate::sp_std::vec::Vec::new())
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(_: $crate::sp_std::vec::Vec<u8>) -> Result<(), &'static str> {
Ok(())
}
}
};
(@impl_on_runtime_upgrade
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OnRuntimeUpgrade
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
fn on_runtime_upgrade() -> $crate::dispatch::Weight {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_runtime_upgrade"));
let pallet_name = <<
$trait_instance
as
$system::Config
>::PalletInfo as $crate::traits::PalletInfo>::name::<Self>().unwrap_or("<unknown pallet name>");
$crate::log::debug!(
target: $crate::LOG_TARGET,
"✅ no migration for {}",
pallet_name,
);
$crate::dispatch::Weight::zero()
}
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<$crate::sp_std::vec::Vec<u8>, &'static str> {
Ok($crate::sp_std::vec::Vec::new())
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(_: $crate::sp_std::vec::Vec<u8>) -> Result<(), &'static str> {
Ok(())
}
}
};
(@impl_integrity_test
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
$(#[doc = $doc_attr:tt])*
fn integrity_test() { $( $impl:tt )* }
) => {
#[cfg(feature = "std")]
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::IntegrityTest
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
$(#[doc = $doc_attr])*
fn integrity_test() {
$( $impl )*
}
}
};
(@impl_integrity_test
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
#[cfg(feature = "std")]
impl<$trait_instance: $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::IntegrityTest
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{}
};
(@impl_on_finalize
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn on_finalize() { $( $impl:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$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::Config>::BlockNumber) {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_finalize"));
{ $( $impl )* }
}
}
};
(@impl_on_finalize
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn on_finalize($param:ident : $param_ty:ty) { $( $impl:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber>
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
fn on_finalize($param: $param_ty) {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_finalize"));
{ $( $impl )* }
}
}
};
(@impl_on_finalize
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OnFinalize<<$trait_instance as $system::Config>::BlockNumber>
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
}
};
(@impl_on_idle
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn on_idle($param1:ident : $param1_ty:ty, $param2:ident: $param2_ty:ty) -> $return:ty { $( $impl:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OnIdle<<$trait_instance as $system::Config>::BlockNumber>
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
fn on_idle($param1: $param1_ty, $param2: $param2_ty) -> $return {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!("on_idle"));
{ $( $impl )* }
}
}
};
(@impl_on_idle
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OnIdle<<$trait_instance as $system::Config>::BlockNumber>
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{
}
};
(@impl_offchain
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn offchain_worker() { $( $impl:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$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::Config>::BlockNumber) { $( $impl )* }
}
};
(@impl_offchain
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
fn offchain_worker($param:ident : $param_ty:ty) { $( $impl:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$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 )* }
}
};
(@impl_offchain
{ $system:ident }
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
impl<$trait_instance: $system::Config + $trait_name$(<I>, $instance: $instantiable)?>
$crate::traits::OffchainWorker<<$trait_instance as $system::Config>::BlockNumber>
for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )*
{}
};
(@impl_function
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
$origin_ty:ty;
$ignore:ident;
$(#[$fn_attr:meta])*
$vis:vis fn $name:ident (
$origin:ident $(, $param:ident : $param_ty:ty )*
) { $( $impl:tt )* }
) => {
#[allow(unreachable_code)]
$(#[$fn_attr])*
$vis fn $name(
$origin: $origin_ty $(, $param: $param_ty )*
) -> $crate::dispatch::DispatchResult {
$crate::storage::with_storage_layer(|| {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!(stringify!($name)));
{ $( $impl )* }
Ok(())
})
}
};
(@impl_function
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
$origin_ty:ty;
$ignore:ident;
$(#[$fn_attr:meta])*
$vis:vis fn $name:ident (
$origin:ident $(, $param:ident : $param_ty:ty )*
) -> $result:ty { $( $impl:tt )* }
) => {
$(#[$fn_attr])*
$vis fn $name($origin: $origin_ty $(, $param: $param_ty )* ) -> $result {
$crate::storage::with_storage_layer(|| {
$crate::sp_tracing::enter_span!($crate::sp_tracing::trace_span!(stringify!($name)));
$( $impl )*
})
}
};
(@create_call_enum
$call_type:ident;
<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?>
{ $( $other_where_bounds:tt )* }
{ $( $generated_variants:tt )* }
{ $( $current_params:tt )* }
variant $fn_name:ident;
$( #[doc = $doc_attr:tt] )*
#[compact]
$name:ident : $type:ty;
$( $rest:tt )*
) => {
$crate::decl_module! {
@create_call_enum
$call_type;
<$trait_instance: $trait_name $(<I>, $instance: $instantiable $(= $module_default_instance)? )?>
{ $( $other_where_bounds )* }
{ $( $generated_variants )* }
{
$( $current_params )*
#[codec(compact)]
$name: $type,
}
variant $fn_name;
$( #[doc = $doc_attr] )*
$( $rest )*
}
};
(@create_call_enum
$call_type:ident;
<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?>
{ $( $other_where_bounds:tt )* }
{ $( $generated_variants:tt )* }
{ $( $current_params:tt )* }
variant $fn_name:ident;
$(#[doc = $doc_attr:tt])*
$name:ident : $type:ty;
$( $rest:tt )*
) => {
$crate::decl_module! {
@create_call_enum
$call_type;
<$trait_instance: $trait_name $(<I>, $instance: $instantiable $(= $module_default_instance)? )?>
{ $( $other_where_bounds )* }
{ $( $generated_variants )* }
{
$( $current_params )*
$name: $type,
}
variant $fn_name;
$( #[doc = $doc_attr] )*
$( $rest )*
}
};
(@create_call_enum
$call_type:ident;
<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?>
{ $( $other_where_bounds:tt )* }
{ $( $generated_variants:tt )* }
{ $( $current_params:tt )* }
variant $fn_name:ident;
$(#[doc = $doc_attr:tt])*
$(
variant $next_fn_name:ident;
$( $rest:tt )*
)?
) => {
$crate::decl_module! {
@create_call_enum
$call_type;
<$trait_instance: $trait_name $(<I>, $instance: $instantiable $(= $module_default_instance)? )?>
{ $( $other_where_bounds )* }
{
$( $generated_variants )*
#[allow(non_camel_case_types)]
$(#[doc = $doc_attr])*
$fn_name {
$( $current_params )*
},
}
{}
$(
variant $next_fn_name;
$( $rest )*
)?
}
};
(@create_call_enum
$call_type:ident;
<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?>
{ $( $other_where_bounds:tt )* }
{ $( $generated_variants:tt )* }
{}
) => {
#[derive($crate::codec::Encode, $crate::codec::Decode, $crate::scale_info::TypeInfo)]
#[scale_info(skip_type_params($trait_instance $(, $instance)?), capture_docs = "always")]
pub enum $call_type<$trait_instance: $trait_name$(<I>, $instance: $instantiable $( = $module_default_instance)?)?>
where $( $other_where_bounds )*
{
#[doc(hidden)]
#[codec(skip)]
__PhantomItem($crate::sp_std::marker::PhantomData<($trait_instance, $($instance)?)>, $crate::Never),
$( $generated_variants )*
}
};
(@impl_get_storage_version
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
$( $storage_version:tt )+
) => {
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::traits::GetStorageVersion
for $module<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn current_storage_version() -> $crate::traits::StorageVersion {
$( $storage_version )*
}
fn on_chain_storage_version() -> $crate::traits::StorageVersion {
$crate::traits::StorageVersion::get::<Self>()
}
}
};
(@impl_get_storage_version
$module:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>;
{ $( $other_where_bounds:tt )* }
) => {
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::traits::GetStorageVersion
for $module<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn current_storage_version() -> $crate::traits::StorageVersion {
Default::default()
}
fn on_chain_storage_version() -> $crate::traits::StorageVersion {
$crate::traits::StorageVersion::get::<Self>()
}
}
};
(@imp
$(#[$attr:meta])*
pub struct $mod_type:ident<
$trait_instance:ident: $trait_name:ident
$(<I>, $instance:ident: $instantiable:path $(= $module_default_instance:path)?)?
>
for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident {
$(
$(#[doc = $doc_attr:tt])*
#[weight = $weight:expr]
$(#[$fn_attr:meta])*
$fn_vis:vis fn $fn_name:ident(
$from:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty)*
) $( -> $result:ty )* { $( $impl:tt )* }
{ $($fn_instance:ident: $fn_instantiable:path)? }
)*
}
{ $( $other_where_bounds:tt )* }
{ $( $deposit_event:tt )* }
{ $( $on_initialize:tt )* }
{ $( $on_runtime_upgrade:tt )* }
{ $( $on_idle:tt )* }
{ $( $on_finalize:tt )* }
{ $( $offchain:tt )* }
{ $( $constants:tt )* }
{ $( $error_type:tt )* }
{ $( $integrity_test:tt )* }
{ $( $storage_version:tt )* }
) => {
$crate::__check_reserved_fn_name! { $( $fn_name )* }
#[derive(Clone, Copy, PartialEq, Eq, $crate::RuntimeDebug)]
$( #[$attr] )*
pub struct $mod_type<
$trait_instance: $trait_name
$(<I>, $instance: $instantiable $( = $module_default_instance)?)?
>($crate::sp_std::marker::PhantomData<($trait_instance, $( $instance)?)>) where
$( $other_where_bounds )*;
#[allow(dead_code)]
pub type Pallet<$trait_instance $(, $instance $( = $module_default_instance)?)?>
= $mod_type<$trait_instance $(, $instance)?>;
$crate::__create_tt_macro! {
tt_error_token,
}
$crate::decl_module! {
@impl_on_initialize
{ $system }
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $on_initialize )*
}
$crate::decl_module! {
@impl_try_state_default
{ $system }
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
}
$crate::decl_module! {
@impl_on_runtime_upgrade
{ $system }
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $on_runtime_upgrade )*
}
$crate::decl_module! {
@impl_on_finalize
{ $system }
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $on_finalize )*
}
$crate::decl_module! {
@impl_on_idle
{ $system }
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $on_idle )*
}
$crate::decl_module! {
@impl_offchain
{ $system }
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $offchain )*
}
$crate::decl_module! {
@impl_deposit_event
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
$system;
{ $( $other_where_bounds )* }
$( $deposit_event )*
}
$crate::decl_module! {
@impl_integrity_test
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $integrity_test )*
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $mod_type<$trait_instance $(, $instance)?>
where $( $other_where_bounds )*
{
$(
$crate::decl_module! {
@impl_function
$mod_type<$trait_instance: $trait_name $(<I>, $fn_instance: $fn_instantiable)?>;
$origin_type;
$from;
$(#[doc = $doc_attr])*
$(#[$fn_attr])*
$fn_vis fn $fn_name (
$from $(, $param_name : $param )*
) $( -> $result )* { $( $impl )* }
}
)*
}
$crate::decl_module! {
@create_call_enum
$call_type;
<$trait_instance: $trait_name $(<I>, $instance: $instantiable $(= $module_default_instance)? )?>
{ $( $other_where_bounds )* }
{}
{}
$(
variant $fn_name;
$(#[doc = $doc_attr])*
$(
$(#[$codec_attr])*
$param_name : $param;
)*
)*
}
$crate::paste::paste! {
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>
$call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
$(
#[doc = "Create a call with the variant `" $fn_name "`."]
pub fn [< new_call_variant_ $fn_name >](
$( $param_name: $param ),*
) -> Self {
Self::$fn_name {
$( $param_name ),*
}
}
)*
}
}
$crate::decl_module! {
@impl_get_storage_version
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>;
{ $( $other_where_bounds )* }
$( $storage_version )*
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::GetDispatchInfo
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn get_dispatch_info(&self) -> $crate::dispatch::DispatchInfo {
match *self {
$(
$call_type::$fn_name { $( ref $param_name ),* } => {
let __pallet_base_weight = $weight;
let __pallet_weight = <dyn $crate::dispatch::WeighData<( $( & $param, )* )>>::weigh_data(
&__pallet_base_weight,
($( $param_name, )*)
);
let __pallet_class = <dyn $crate::dispatch::ClassifyDispatch<( $( & $param, )* )>>::classify_dispatch(
&__pallet_base_weight,
($( $param_name, )*)
);
let __pallet_pays_fee = <dyn $crate::dispatch::PaysFee<( $( & $param, )* )>>::pays_fee(
&__pallet_base_weight,
($( $param_name, )*)
);
$crate::dispatch::DispatchInfo {
weight: __pallet_weight,
class: __pallet_class,
pays_fee: __pallet_pays_fee,
}
},
)*
$call_type::__PhantomItem(_, _) => unreachable!("__PhantomItem should never be used."),
}
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::traits::PalletInfoAccess
for $mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn index() -> usize {
<
<$trait_instance as $system::Config>::PalletInfo as $crate::traits::PalletInfo
>::index::<Self>()
.expect("Pallet is part of the runtime because pallet `Config` trait is \
implemented by the runtime")
}
fn name() -> &'static str {
<
<$trait_instance as $system::Config>::PalletInfo as $crate::traits::PalletInfo
>::name::<Self>()
.expect("Pallet is part of the runtime because pallet `Config` trait is \
implemented by the runtime")
}
fn module_name() -> &'static str {
<
<$trait_instance as $system::Config>::PalletInfo as $crate::traits::PalletInfo
>::module_name::<Self>()
.expect("Pallet is part of the runtime because pallet `Config` trait is \
implemented by the runtime")
}
fn crate_version() -> $crate::traits::CrateVersion {
$crate::crate_to_crate_version!()
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::traits::PalletsInfoAccess
for $mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn count() -> usize { 1 }
fn infos() -> $crate::sp_std::vec::Vec<$crate::traits::PalletInfoData> {
use $crate::traits::PalletInfoAccess;
let item = $crate::traits::PalletInfoData {
index: Self::index(),
name: Self::name(),
module_name: Self::module_name(),
crate_version: Self::crate_version(),
};
vec![item]
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::GetCallName
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn get_call_name(&self) -> &'static str {
match *self {
$(
$call_type::$fn_name { $( ref $param_name ),* } => {
let _ = ( $( $param_name ),* );
stringify!($fn_name)
},
)*
$call_type::__PhantomItem(_, _) => unreachable!("__PhantomItem should never be used."),
}
}
fn get_call_names() -> &'static [&'static str] {
&[
$(
stringify!($fn_name),
)*
]
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::traits::OnGenesis
for $mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn on_genesis() {
let storage_version = <Self as $crate::traits::GetStorageVersion>::current_storage_version();
storage_version.put::<Self>();
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::Clone
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn clone(&self) -> Self {
match *self {
$(
$call_type::$fn_name { $( ref $param_name ),* } =>
$call_type::$fn_name { $( $param_name: (*$param_name).clone() ),* }
,)*
_ => unreachable!(),
}
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::PartialEq
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn eq(&self, _other: &Self) -> bool {
match *self {
$(
$call_type::$fn_name { $( ref $param_name ),* } => {
let self_params = ( $( $param_name, )* );
if let $call_type::$fn_name { $( ref $param_name ),* } = *_other {
self_params == ( $( $param_name, )* )
} else {
match *_other {
$call_type::__PhantomItem(_, _) => unreachable!(),
_ => false,
}
}
}
)*
_ => unreachable!(),
}
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::Eq
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::fmt::Debug
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn fmt(
&self,
_f: &mut $crate::dispatch::fmt::Formatter,
) -> $crate::dispatch::result::Result<(), $crate::dispatch::fmt::Error> {
match *self {
$(
$call_type::$fn_name { $( ref $param_name ),* } =>
write!(_f, "{}{:?}",
stringify!($fn_name),
( $( $param_name.clone(), )* )
)
,)*
_ => unreachable!(),
}
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::traits::UnfilteredDispatchable
for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
type RuntimeOrigin = $origin_type;
fn dispatch_bypass_filter(self, _origin: Self::RuntimeOrigin) -> $crate::dispatch::DispatchResultWithPostInfo {
match self {
$(
$call_type::$fn_name { $( $param_name ),* } => {
$crate::decl_module!(
@call
$from
$mod_type<$trait_instance $(, $fn_instance)?> $fn_name _origin $system [ $( $param_name ),* ]
)
},
)*
$call_type::__PhantomItem(_, _) => { unreachable!("__PhantomItem should never be used.") },
}
}
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::Callable<$trait_instance>
for $mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
type RuntimeCall = $call_type<$trait_instance $(, $instance)?>;
}
$crate::__dispatch_impl_metadata! {
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>
{ $( $other_where_bounds )* }
$call_type $origin_type
{
$(
$(#[doc = $doc_attr])*
fn $fn_name($from $(, $(#[$codec_attr])* $param_name : $param )*);
)*
}
}
$crate::__impl_error_metadata! {
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>
{ $( $other_where_bounds )* }
$( $error_type )*
}
$crate::__impl_module_constants_metadata ! {
$mod_type<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?>
{ $( $other_where_bounds )* }
$( $constants )*
}
$crate::__generate_dummy_part_checker!();
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! __dispatch_impl_metadata {
(
$mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>
{ $( $other_where_bounds:tt )* }
$call_type:ident
$($rest:tt)*
) => {
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $mod_type<$trait_instance $(, $instance)?>
where $( $other_where_bounds )*
{
#[doc(hidden)]
#[allow(dead_code)]
pub fn call_functions() -> $crate::metadata::PalletCallMetadata {
$crate::scale_info::meta_type::<$call_type<$trait_instance $(, $instance)?>>().into()
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! __impl_error_metadata {
(
$mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>
{ $( $other_where_bounds:tt )* }
__NO_ERROR_DEFINED
) => {
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $mod_type<$trait_instance $(, $instance)?>
where $( $other_where_bounds )*
{
#[doc(hidden)]
#[allow(dead_code)]
pub fn error_metadata() -> Option<$crate::metadata::PalletErrorMetadata> {
None
}
}
};
(
$mod_type:ident<$trait_instance:ident: $trait_name:ident$(<I>, $instance:ident: $instantiable:path)?>
{ $( $other_where_bounds:tt )* }
$( $error_type:tt )*
) => {
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $mod_type<$trait_instance $(, $instance)?>
where $( $other_where_bounds )*
{
#[doc(hidden)]
#[allow(dead_code)]
pub fn error_metadata() -> Option<$crate::metadata::PalletErrorMetadata> {
Some($crate::metadata::PalletErrorMetadata {
ty: $crate::scale_info::meta_type::<$( $error_type )*>()
})
}
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __impl_module_constants_metadata {
(
$mod_type:ident<$trait_instance:ident: $trait_name:ident>
{ $( $other_where_bounds:tt )* }
$(
$( #[doc = $doc_attr:tt] )*
$name:ident: $type:ty = $value:expr;
)*
) => {
$crate::paste::item! {
$crate::__impl_module_constants_metadata! {
GENERATE_CODE
$mod_type<$trait_instance: $trait_name>
{ $( $other_where_bounds )* }
$(
$( #[doc = $doc_attr] )*
[< $name DefaultByteGetter >]
$name<$trait_instance: $trait_name>: $type = $value;
)*
}
}
};
(
$mod_type:ident<$trait_instance:ident: $trait_name:ident<I>, $instance:ident: $instantiable:path>
{ $( $other_where_bounds:tt )* }
$(
$( #[doc = $doc_attr:tt] )*
$name:ident: $type:ty = $value:expr;
)*
) => {
$crate::paste::item! {
$crate::__impl_module_constants_metadata! {
GENERATE_CODE
$mod_type<$trait_instance: $trait_name<I>, $instance: $instantiable>
{ $( $other_where_bounds )* }
$(
$( #[doc = $doc_attr] )*
[< $name DefaultByteGetter >]
$name<$trait_instance: $trait_name<I>, $instance: $instantiable>: $type = $value;
)*
}
}
};
(GENERATE_CODE
$mod_type:ident<$trait_instance:ident: $trait_name:ident $(<I>, $instance:ident: $instantiable:path)?>
{ $( $other_where_bounds:tt )* }
$(
$( #[doc = $doc_attr:tt] )*
$default_byte_name:ident
$name:ident<
$const_trait_instance:ident: $const_trait_name:ident $(
<I>, $const_instance:ident: $const_instantiable:path
)*
>: $type:ty = $value:expr;
)*
) => {
impl<$trait_instance: 'static + $trait_name $(<I>, $instance: $instantiable)?>
$mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
#[doc(hidden)]
#[allow(dead_code)]
pub fn pallet_constants_metadata() -> $crate::sp_std::vec::Vec<$crate::metadata::PalletConstantMetadata> {
$(
#[allow(non_upper_case_types)]
#[allow(non_camel_case_types)]
struct $default_byte_name<
$const_trait_instance: $const_trait_name $(
<I>, $const_instance: $const_instantiable
)?
>($crate::dispatch::marker::PhantomData<
($const_trait_instance, $( $const_instance)?)
>);
impl<$const_trait_instance: 'static + $const_trait_name $(
<I>, $const_instance: $const_instantiable)?
> $default_byte_name <$const_trait_instance $(, $const_instance)?>
{
fn default_byte(&self) -> $crate::dispatch::Vec<u8> {
let value: $type = $value;
$crate::dispatch::Encode::encode(&value)
}
}
)*
$crate::sp_std::vec![
$(
$crate::metadata::PalletConstantMetadata {
name: stringify!($name),
ty: $crate::scale_info::meta_type::<$type>(),
value: $default_byte_name::<$const_trait_instance $(, $const_instance)?>(
Default::default()
).default_byte(),
docs: $crate::sp_std::vec![ $( $doc_attr ),* ],
}
),*
]
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! __check_reserved_fn_name {
(deposit_event $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error deposit_event);
};
(on_initialize $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error on_initialize);
};
(on_runtime_upgrade $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error on_runtime_upgrade);
};
(on_idle $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error on_idle);
};
(on_finalize $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error on_finalize);
};
(offchain_worker $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error offchain_worker);
};
(integrity_test $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!(@compile_error integrity_test);
};
($t:ident $( $rest:ident )*) => {
$crate::__check_reserved_fn_name!($( $rest )*);
};
() => {};
(@compile_error $ident:ident) => {
compile_error!(
concat!(
"Invalid call fn name: `",
stringify!($ident),
"`, name is reserved and doesn't match expected signature, please refer to ",
"`decl_module!` documentation to see the appropriate usage, or rename it to an ",
"unreserved keyword."
),
);
};
(@compile_error_renamed $ident:ident $new_ident:ident) => {
compile_error!(
concat!(
"`",
stringify!($ident),
"` was renamed to `",
stringify!($new_ident),
"`. Please rename your function accordingly.",
),
);
};
}
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use super::*;
use crate::{
dispatch::{DispatchClass, DispatchInfo, Pays},
metadata::*,
traits::{
CallerTrait, CrateVersion, Get, GetCallName, IntegrityTest, OnFinalize, OnIdle,
OnInitialize, OnRuntimeUpgrade, PalletInfo,
},
};
use sp_weights::RuntimeDbWeight;
pub trait Config: system::Config + Sized
where
Self::AccountId: From<u32>,
{
}
pub mod system {
use super::*;
pub trait Config: 'static {
type AccountId;
type RuntimeCall;
type BaseCallFilter;
type RuntimeOrigin: crate::traits::OriginTrait<Call = Self::RuntimeCall>;
type BlockNumber: Into<u32>;
type PalletInfo: crate::traits::PalletInfo;
type DbWeight: Get<RuntimeDbWeight>;
}
pub use super::super::RawOrigin;
pub type Origin<T> = RawOrigin<<T as Config>::AccountId>;
}
decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::RuntimeOrigin, system = system, T::AccountId: From<u32> {
#[weight = 0]
fn aux_0(_origin) -> DispatchResult { unreachable!() }
#[weight = 0]
fn aux_1(_origin, #[compact] _data: u32,) -> DispatchResult { unreachable!() }
#[weight = 0]
fn aux_2(_origin, _data: i32, _data2: String) -> DispatchResult { unreachable!() }
#[weight = 3]
fn aux_3(_origin) -> DispatchResult { unreachable!() }
#[weight = 0]
fn aux_4(_origin, _data: i32) -> DispatchResult { unreachable!() }
#[weight = 0]
fn aux_5(_origin, _data: i32, #[compact] _data2: u32,) -> DispatchResult { unreachable!() }
#[weight = (5, DispatchClass::Operational)]
fn operational(_origin) { unreachable!() }
fn on_initialize(n: T::BlockNumber,) -> Weight { if n.into() == 42 { panic!("on_initialize") } Weight::from_ref_time(7) }
fn on_idle(n: T::BlockNumber, remaining_weight: Weight,) -> Weight {
if n.into() == 42 || remaining_weight == Weight::from_ref_time(42) { panic!("on_idle") }
Weight::from_ref_time(7)
}
fn on_finalize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_finalize") } }
fn on_runtime_upgrade() -> Weight { Weight::from_ref_time(10) }
fn offchain_worker() {}
fn integrity_test() { panic!("integrity_test") }
}
}
#[derive(Eq, PartialEq, Clone, crate::RuntimeDebug, scale_info::TypeInfo)]
pub struct TraitImpl {}
impl Config for TraitImpl {}
type Test = Module<TraitImpl>;
impl PalletInfo for TraitImpl {
fn index<P: 'static>() -> Option<usize> {
let type_id = sp_std::any::TypeId::of::<P>();
if type_id == sp_std::any::TypeId::of::<Test>() {
return Some(0)
}
None
}
fn name<P: 'static>() -> Option<&'static str> {
let type_id = sp_std::any::TypeId::of::<P>();
if type_id == sp_std::any::TypeId::of::<Test>() {
return Some("Test")
}
None
}
fn module_name<P: 'static>() -> Option<&'static str> {
let type_id = sp_std::any::TypeId::of::<P>();
if type_id == sp_std::any::TypeId::of::<Test>() {
return Some("tests")
}
None
}
fn crate_version<P: 'static>() -> Option<CrateVersion> {
let type_id = sp_std::any::TypeId::of::<P>();
if type_id == sp_std::any::TypeId::of::<Test>() {
return Some(frame_support::crate_to_crate_version!())
}
None
}
}
#[derive(
TypeInfo, crate::RuntimeDebug, Eq, PartialEq, Clone, Encode, Decode, MaxEncodedLen,
)]
pub struct OuterOrigin;
impl From<RawOrigin<<TraitImpl as system::Config>::AccountId>> for OuterOrigin {
fn from(_: RawOrigin<<TraitImpl as system::Config>::AccountId>) -> Self {
unimplemented!("Not required in tests!")
}
}
impl CallerTrait<<TraitImpl as system::Config>::AccountId> for OuterOrigin {
fn into_system(self) -> Option<RawOrigin<<TraitImpl as system::Config>::AccountId>> {
unimplemented!("Not required in tests!")
}
fn as_system_ref(&self) -> Option<&RawOrigin<<TraitImpl as system::Config>::AccountId>> {
unimplemented!("Not required in tests!")
}
}
impl crate::traits::OriginTrait for OuterOrigin {
type Call = <TraitImpl as system::Config>::RuntimeCall;
type PalletsOrigin = OuterOrigin;
type AccountId = <TraitImpl as system::Config>::AccountId;
fn add_filter(&mut self, _filter: impl Fn(&Self::Call) -> bool + 'static) {
unimplemented!("Not required in tests!")
}
fn reset_filter(&mut self) {
unimplemented!("Not required in tests!")
}
fn set_caller_from(&mut self, _other: impl Into<Self>) {
unimplemented!("Not required in tests!")
}
fn filter_call(&self, _call: &Self::Call) -> bool {
unimplemented!("Not required in tests!")
}
fn caller(&self) -> &Self::PalletsOrigin {
unimplemented!("Not required in tests!")
}
fn into_caller(self) -> Self::PalletsOrigin {
unimplemented!("Not required in tests!")
}
fn try_with_caller<R>(
self,
_f: impl FnOnce(Self::PalletsOrigin) -> Result<R, Self::PalletsOrigin>,
) -> Result<R, Self> {
unimplemented!("Not required in tests!")
}
fn none() -> Self {
unimplemented!("Not required in tests!")
}
fn root() -> Self {
unimplemented!("Not required in tests!")
}
fn signed(_by: <TraitImpl as system::Config>::AccountId) -> Self {
unimplemented!("Not required in tests!")
}
fn as_signed(self) -> Option<Self::AccountId> {
unimplemented!("Not required in tests!")
}
fn as_system_ref(&self) -> Option<&RawOrigin<Self::AccountId>> {
unimplemented!("Not required in tests!")
}
}
impl system::Config for TraitImpl {
type RuntimeOrigin = OuterOrigin;
type AccountId = u32;
type RuntimeCall = ();
type BaseCallFilter = frame_support::traits::Everything;
type BlockNumber = u32;
type PalletInfo = Self;
type DbWeight = ();
}
#[test]
fn module_json_metadata() {
let metadata = Module::<TraitImpl>::call_functions();
let expected_metadata =
PalletCallMetadata { ty: scale_info::meta_type::<Call<TraitImpl>>() };
assert_eq!(expected_metadata, metadata);
}
#[test]
fn compact_attr() {
let call: Call<TraitImpl> = Call::aux_1 { _data: 1 };
let encoded = call.encode();
assert_eq!(2, encoded.len());
assert_eq!(vec![1, 4], encoded);
let call: Call<TraitImpl> = Call::aux_5 { _data: 1, _data2: 2 };
let encoded = call.encode();
assert_eq!(6, encoded.len());
assert_eq!(vec![5, 1, 0, 0, 0, 8], encoded);
}
#[test]
fn encode_is_correct_and_decode_works() {
let call: Call<TraitImpl> = Call::aux_0 {};
let encoded = call.encode();
assert_eq!(vec![0], encoded);
let decoded = Call::<TraitImpl>::decode(&mut &encoded[..]).unwrap();
assert_eq!(decoded, call);
let call: Call<TraitImpl> = Call::aux_2 { _data: 32, _data2: "hello".into() };
let encoded = call.encode();
assert_eq!(vec![2, 32, 0, 0, 0, 20, 104, 101, 108, 108, 111], encoded);
let decoded = Call::<TraitImpl>::decode(&mut &encoded[..]).unwrap();
assert_eq!(decoded, call);
}
#[test]
#[should_panic(expected = "on_initialize")]
fn on_initialize_should_work_1() {
<Module<TraitImpl> as OnInitialize<u32>>::on_initialize(42);
}
#[test]
fn on_initialize_should_work_2() {
assert_eq!(
<Module<TraitImpl> as OnInitialize<u32>>::on_initialize(10),
Weight::from_ref_time(7)
);
}
#[test]
#[should_panic(expected = "on_idle")]
fn on_idle_should_work_1() {
<Module<TraitImpl> as OnIdle<u32>>::on_idle(42, Weight::from_ref_time(9));
}
#[test]
#[should_panic(expected = "on_idle")]
fn on_idle_should_work_2() {
<Module<TraitImpl> as OnIdle<u32>>::on_idle(9, Weight::from_ref_time(42));
}
#[test]
fn on_idle_should_work_3() {
assert_eq!(
<Module<TraitImpl> as OnIdle<u32>>::on_idle(10, Weight::from_ref_time(11)),
Weight::from_ref_time(7)
);
}
#[test]
#[should_panic(expected = "on_finalize")]
fn on_finalize_should_work() {
<Module<TraitImpl> as OnFinalize<u32>>::on_finalize(42);
}
#[test]
fn on_runtime_upgrade_should_work() {
sp_io::TestExternalities::default().execute_with(|| {
assert_eq!(
<Module<TraitImpl> as OnRuntimeUpgrade>::on_runtime_upgrade(),
Weight::from_ref_time(10)
)
});
}
#[test]
fn weight_should_attach_to_call_enum() {
assert_eq!(
Call::<TraitImpl>::operational {}.get_dispatch_info(),
DispatchInfo {
weight: Weight::from_ref_time(5),
class: DispatchClass::Operational,
pays_fee: Pays::Yes
},
);
assert_eq!(
Call::<TraitImpl>::aux_3 {}.get_dispatch_info(),
DispatchInfo {
weight: Weight::from_ref_time(3),
class: DispatchClass::Normal,
pays_fee: Pays::Yes
},
);
}
#[test]
fn call_name() {
let name = Call::<TraitImpl>::aux_3 {}.get_call_name();
assert_eq!("aux_3", name);
}
#[test]
fn get_call_names() {
let call_names = Call::<TraitImpl>::get_call_names();
assert_eq!(
["aux_0", "aux_1", "aux_2", "aux_3", "aux_4", "aux_5", "operational"],
call_names
);
}
#[test]
#[should_panic(expected = "integrity_test")]
fn integrity_test_should_work() {
<Module<TraitImpl> as IntegrityTest>::integrity_test();
}
#[test]
fn test_new_call_variant() {
Call::<TraitImpl>::new_call_variant_aux_0();
}
}
#[cfg(test)]
#[allow(dead_code)]
mod weight_tests {
use super::*;
use sp_core::{parameter_types, Get};
use sp_weights::RuntimeDbWeight;
pub trait Config: 'static {
type RuntimeOrigin;
type Balance;
type BlockNumber;
type DbWeight: Get<RuntimeDbWeight>;
type PalletInfo: crate::traits::PalletInfo;
}
pub struct TraitImpl {}
parameter_types! {
pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight {
read: 100,
write: 1000,
};
}
impl Config for TraitImpl {
type RuntimeOrigin = u32;
type BlockNumber = u32;
type Balance = u32;
type DbWeight = DbWeight;
type PalletInfo = crate::tests::PanicPalletInfo;
}
decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::RuntimeOrigin, system=self {
#[weight = 1000]
fn f00(_origin) { unimplemented!(); }
#[weight = (1000, DispatchClass::Mandatory)]
fn f01(_origin) { unimplemented!(); }
#[weight = (1000, Pays::No)]
fn f02(_origin) { unimplemented!(); }
#[weight = (1000, DispatchClass::Operational, Pays::No)]
fn f03(_origin) { unimplemented!(); }
#[weight = ((_a * 10 + _eb * 1) as u64, DispatchClass::Normal, Pays::Yes)]
fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); }
#[weight = (0, DispatchClass::Operational, Pays::Yes)]
fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); }
#[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + Weight::from_ref_time(10_000)]
fn f20(_origin) { unimplemented!(); }
#[weight = T::DbWeight::get().reads_writes(6, 5) + Weight::from_ref_time(40_000)]
fn f21(_origin) { unimplemented!(); }
}
}
#[test]
fn weights_are_correct() {
let info = Call::<TraitImpl>::f00 {}.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(1000));
assert_eq!(info.class, DispatchClass::Normal);
assert_eq!(info.pays_fee, Pays::Yes);
let info = Call::<TraitImpl>::f01 {}.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(1000));
assert_eq!(info.class, DispatchClass::Mandatory);
assert_eq!(info.pays_fee, Pays::Yes);
let info = Call::<TraitImpl>::f02 {}.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(1000));
assert_eq!(info.class, DispatchClass::Normal);
assert_eq!(info.pays_fee, Pays::No);
let info = Call::<TraitImpl>::f03 {}.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(1000));
assert_eq!(info.class, DispatchClass::Operational);
assert_eq!(info.pays_fee, Pays::No);
let info = Call::<TraitImpl>::f11 { _a: 13, _eb: 20 }.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(150)); assert_eq!(info.class, DispatchClass::Normal);
assert_eq!(info.pays_fee, Pays::Yes);
let info = Call::<TraitImpl>::f12 { _a: 10, _eb: 20 }.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(0));
assert_eq!(info.class, DispatchClass::Operational);
assert_eq!(info.pays_fee, Pays::Yes);
let info = Call::<TraitImpl>::f20 {}.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(12300)); assert_eq!(info.class, DispatchClass::Normal);
assert_eq!(info.pays_fee, Pays::Yes);
let info = Call::<TraitImpl>::f21 {}.get_dispatch_info();
assert_eq!(info.weight, Weight::from_ref_time(45600)); assert_eq!(info.class, DispatchClass::Normal);
assert_eq!(info.pays_fee, Pays::Yes);
}
#[test]
fn extract_actual_weight_works() {
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
assert_eq!(extract_actual_weight(&Ok(Some(7).into()), &pre), Weight::from_ref_time(7));
assert_eq!(
extract_actual_weight(&Ok(Some(1000).into()), &pre),
Weight::from_ref_time(1000)
);
assert_eq!(
extract_actual_weight(
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(9))),
&pre
),
Weight::from_ref_time(9)
);
}
#[test]
fn extract_actual_weight_caps_at_pre_weight() {
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
assert_eq!(
extract_actual_weight(&Ok(Some(1250).into()), &pre),
Weight::from_ref_time(1000)
);
assert_eq!(
extract_actual_weight(
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(1300))),
&pre
),
Weight::from_ref_time(1000),
);
}
#[test]
fn extract_actual_pays_fee_works() {
let pre = DispatchInfo { weight: Weight::from_ref_time(1000), ..Default::default() };
assert_eq!(extract_actual_pays_fee(&Ok(Some(7).into()), &pre), Pays::Yes);
assert_eq!(extract_actual_pays_fee(&Ok(Some(1000).into()), &pre), Pays::Yes);
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::Yes).into()), &pre), Pays::Yes);
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::No).into()), &pre), Pays::No);
assert_eq!(
extract_actual_pays_fee(
&Err(DispatchError::BadOrigin.with_weight(Weight::from_ref_time(9))),
&pre
),
Pays::Yes
);
assert_eq!(
extract_actual_pays_fee(
&Err(DispatchErrorWithPostInfo {
post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::No },
error: DispatchError::BadOrigin,
}),
&pre
),
Pays::No
);
let pre = DispatchInfo {
weight: Weight::from_ref_time(1000),
pays_fee: Pays::No,
..Default::default()
};
assert_eq!(extract_actual_pays_fee(&Ok(Some(7).into()), &pre), Pays::No);
assert_eq!(extract_actual_pays_fee(&Ok(Some(1000).into()), &pre), Pays::No);
assert_eq!(extract_actual_pays_fee(&Ok((Some(1000), Pays::Yes).into()), &pre), Pays::No);
}
}