mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-09 16:27:58 +00:00
Allow construct_runtime to take cfg attributes for pallets (#11818)
* Allow construct_runtime to take cfg attributes for pallets * cargo fmt * Remove commented out code * Fixes * cargo fmt * Remove inaccurate comments * Fix typo * Properly reverse pallets * Fixes * cargo fmt * Add missing newlines
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
use crate::construct_runtime::Pallet;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
use syn::Ident;
|
||||
|
||||
pub fn expand_outer_dispatch(
|
||||
@@ -30,6 +31,7 @@ pub fn expand_outer_dispatch(
|
||||
let mut variant_patterns = Vec::new();
|
||||
let mut query_call_part_macros = Vec::new();
|
||||
let mut pallet_names = Vec::new();
|
||||
let mut pallet_attrs = Vec::new();
|
||||
let system_path = &system_pallet.path;
|
||||
|
||||
let pallets_with_call = pallet_decls.iter().filter(|decl| decl.exists_part("Call"));
|
||||
@@ -38,12 +40,24 @@ pub fn expand_outer_dispatch(
|
||||
let name = &pallet_declaration.name;
|
||||
let path = &pallet_declaration.path;
|
||||
let index = pallet_declaration.index;
|
||||
let attr =
|
||||
pallet_declaration.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
variant_defs.extend(
|
||||
quote!(#[codec(index = #index)] #name( #scrate::dispatch::CallableCallFor<#name, #runtime> ),),
|
||||
);
|
||||
variant_defs.extend(quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#name( #scrate::dispatch::CallableCallFor<#name, #runtime> ),
|
||||
});
|
||||
variant_patterns.push(quote!(Call::#name(call)));
|
||||
pallet_names.push(name);
|
||||
pallet_attrs.push(attr);
|
||||
query_call_part_macros.push(quote! {
|
||||
#path::__substrate_call_check::is_call_part_defined!(#name);
|
||||
});
|
||||
@@ -69,6 +83,7 @@ pub fn expand_outer_dispatch(
|
||||
use #scrate::dispatch::Callable;
|
||||
use core::mem::size_of;
|
||||
&[#(
|
||||
#pallet_attrs
|
||||
(
|
||||
stringify!(#pallet_names),
|
||||
size_of::< <#pallet_names as Callable<#runtime>>::Call >(),
|
||||
@@ -101,7 +116,10 @@ pub fn expand_outer_dispatch(
|
||||
impl #scrate::dispatch::GetDispatchInfo for Call {
|
||||
fn get_dispatch_info(&self) -> #scrate::dispatch::DispatchInfo {
|
||||
match self {
|
||||
#( #variant_patterns => call.get_dispatch_info(), )*
|
||||
#(
|
||||
#pallet_attrs
|
||||
#variant_patterns => call.get_dispatch_info(),
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,6 +128,7 @@ pub fn expand_outer_dispatch(
|
||||
use #scrate::dispatch::GetCallName;
|
||||
match self {
|
||||
#(
|
||||
#pallet_attrs
|
||||
#variant_patterns => {
|
||||
let function_name = call.get_call_name();
|
||||
let pallet_name = stringify!(#pallet_names);
|
||||
@@ -121,6 +140,7 @@ pub fn expand_outer_dispatch(
|
||||
|
||||
fn get_module_names() -> &'static [&'static str] {
|
||||
&[#(
|
||||
#pallet_attrs
|
||||
stringify!(#pallet_names),
|
||||
)*]
|
||||
}
|
||||
@@ -129,6 +149,7 @@ pub fn expand_outer_dispatch(
|
||||
use #scrate::dispatch::{Callable, GetCallName};
|
||||
match module {
|
||||
#(
|
||||
#pallet_attrs
|
||||
stringify!(#pallet_names) =>
|
||||
<<#pallet_names as Callable<#runtime>>::Call
|
||||
as GetCallName>::get_call_names(),
|
||||
@@ -157,6 +178,7 @@ pub fn expand_outer_dispatch(
|
||||
fn dispatch_bypass_filter(self, origin: Origin) -> #scrate::dispatch::DispatchResultWithPostInfo {
|
||||
match self {
|
||||
#(
|
||||
#pallet_attrs
|
||||
#variant_patterns =>
|
||||
#scrate::traits::UnfilteredDispatchable::dispatch_bypass_filter(call, origin),
|
||||
)*
|
||||
@@ -165,6 +187,7 @@ pub fn expand_outer_dispatch(
|
||||
}
|
||||
|
||||
#(
|
||||
#pallet_attrs
|
||||
impl #scrate::traits::IsSubType<#scrate::dispatch::CallableCallFor<#pallet_names, #runtime>> for Call {
|
||||
#[allow(unreachable_patterns)]
|
||||
fn is_sub_type(&self) -> Option<&#scrate::dispatch::CallableCallFor<#pallet_names, #runtime>> {
|
||||
@@ -176,6 +199,7 @@ pub fn expand_outer_dispatch(
|
||||
}
|
||||
}
|
||||
|
||||
#pallet_attrs
|
||||
impl From<#scrate::dispatch::CallableCallFor<#pallet_names, #runtime>> for Call {
|
||||
fn from(call: #scrate::dispatch::CallableCallFor<#pallet_names, #runtime>) -> Self {
|
||||
#variant_patterns
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::construct_runtime::Pallet;
|
||||
use inflector::Inflector;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use std::str::FromStr;
|
||||
use syn::Ident;
|
||||
|
||||
pub fn expand_outer_config(
|
||||
@@ -40,11 +41,19 @@ pub fn expand_outer_config(
|
||||
let field_name =
|
||||
&Ident::new(&pallet_name.to_string().to_snake_case(), decl.name.span());
|
||||
let part_is_generic = !pallet_entry.generics.params.is_empty();
|
||||
let attr = &decl.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
types.extend(expand_config_types(runtime, decl, &config, part_is_generic));
|
||||
fields.extend(quote!(pub #field_name: #config,));
|
||||
types.extend(expand_config_types(attr, runtime, decl, &config, part_is_generic));
|
||||
fields.extend(quote!(#attr pub #field_name: #config,));
|
||||
build_storage_calls
|
||||
.extend(expand_config_build_storage_call(scrate, runtime, decl, field_name));
|
||||
.extend(expand_config_build_storage_call(scrate, attr, runtime, decl, field_name));
|
||||
query_genesis_config_part_macros.push(quote! {
|
||||
#path::__substrate_genesis_config_check::is_genesis_config_defined!(#pallet_name);
|
||||
#[cfg(feature = "std")]
|
||||
@@ -88,6 +97,7 @@ pub fn expand_outer_config(
|
||||
}
|
||||
|
||||
fn expand_config_types(
|
||||
attr: &TokenStream,
|
||||
runtime: &Ident,
|
||||
decl: &Pallet,
|
||||
config: &Ident,
|
||||
@@ -97,14 +107,17 @@ fn expand_config_types(
|
||||
|
||||
match (decl.instance.as_ref(), part_is_generic) {
|
||||
(Some(inst), true) => quote! {
|
||||
#attr
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub type #config = #path::GenesisConfig<#runtime, #path::#inst>;
|
||||
},
|
||||
(None, true) => quote! {
|
||||
#attr
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub type #config = #path::GenesisConfig<#runtime>;
|
||||
},
|
||||
(_, false) => quote! {
|
||||
#attr
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub type #config = #path::GenesisConfig;
|
||||
},
|
||||
@@ -113,6 +126,7 @@ fn expand_config_types(
|
||||
|
||||
fn expand_config_build_storage_call(
|
||||
scrate: &TokenStream,
|
||||
attr: &TokenStream,
|
||||
runtime: &Ident,
|
||||
decl: &Pallet,
|
||||
field_name: &Ident,
|
||||
@@ -125,6 +139,7 @@ fn expand_config_build_storage_call(
|
||||
};
|
||||
|
||||
quote! {
|
||||
#attr
|
||||
#scrate::sp_runtime::BuildModuleGenesisStorage::
|
||||
<#runtime, #instance>::build_module_genesis_storage(&self.#field_name, storage)?;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use crate::construct_runtime::Pallet;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
use syn::{Generics, Ident};
|
||||
|
||||
pub fn expand_outer_event(
|
||||
@@ -97,19 +98,35 @@ fn expand_event_variant(
|
||||
let path = &pallet.path;
|
||||
let variant_name = &pallet.name;
|
||||
let part_is_generic = !generics.params.is_empty();
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
match instance {
|
||||
Some(inst) if part_is_generic => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Event<#runtime, #path::#inst>),)
|
||||
Some(inst) if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event<#runtime, #path::#inst>),
|
||||
},
|
||||
Some(inst) => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Event<#path::#inst>),)
|
||||
Some(inst) => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event<#path::#inst>),
|
||||
},
|
||||
None if part_is_generic => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Event<#runtime>),)
|
||||
None if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event<#runtime>),
|
||||
},
|
||||
None => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Event),)
|
||||
None => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -120,13 +137,23 @@ fn expand_event_conversion(
|
||||
pallet_event: &TokenStream,
|
||||
) -> TokenStream {
|
||||
let variant_name = &pallet.name;
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#attr
|
||||
impl From<#pallet_event> for Event {
|
||||
fn from(x: #pallet_event) -> Self {
|
||||
Event::#variant_name(x)
|
||||
}
|
||||
}
|
||||
#attr
|
||||
impl TryInto<#pallet_event> for Event {
|
||||
type Error = ();
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use crate::construct_runtime::Pallet;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
use syn::{Ident, TypePath};
|
||||
|
||||
pub fn expand_outer_inherent(
|
||||
@@ -28,14 +29,24 @@ pub fn expand_outer_inherent(
|
||||
scrate: &TokenStream,
|
||||
) -> TokenStream {
|
||||
let mut pallet_names = Vec::new();
|
||||
let mut pallet_attrs = Vec::new();
|
||||
let mut query_inherent_part_macros = Vec::new();
|
||||
|
||||
for pallet_decl in pallet_decls {
|
||||
if pallet_decl.exists_part("Inherent") {
|
||||
let name = &pallet_decl.name;
|
||||
let path = &pallet_decl.path;
|
||||
let attr = pallet_decl.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
pallet_names.push(name);
|
||||
pallet_attrs.push(attr);
|
||||
query_inherent_part_macros.push(quote! {
|
||||
#path::__substrate_inherent_check::is_inherent_part_defined!(#name);
|
||||
});
|
||||
@@ -60,6 +71,7 @@ pub fn expand_outer_inherent(
|
||||
let mut inherents = Vec::new();
|
||||
|
||||
#(
|
||||
#pallet_attrs
|
||||
if let Some(inherent) = #pallet_names::create_inherent(self) {
|
||||
let inherent = <#unchecked_extrinsic as #scrate::inherent::Extrinsic>::new(
|
||||
inherent.into(),
|
||||
@@ -90,22 +102,25 @@ pub fn expand_outer_inherent(
|
||||
|
||||
let mut is_inherent = false;
|
||||
|
||||
#({
|
||||
let call = <#unchecked_extrinsic as ExtrinsicCall>::call(xt);
|
||||
if let Some(call) = IsSubType::<_>::is_sub_type(call) {
|
||||
if #pallet_names::is_inherent(call) {
|
||||
is_inherent = true;
|
||||
if let Err(e) = #pallet_names::check_inherent(call, self) {
|
||||
result.put_error(
|
||||
#pallet_names::INHERENT_IDENTIFIER, &e
|
||||
).expect("There is only one fatal error; qed");
|
||||
if e.is_fatal_error() {
|
||||
return result;
|
||||
#(
|
||||
#pallet_attrs
|
||||
{
|
||||
let call = <#unchecked_extrinsic as ExtrinsicCall>::call(xt);
|
||||
if let Some(call) = IsSubType::<_>::is_sub_type(call) {
|
||||
if #pallet_names::is_inherent(call) {
|
||||
is_inherent = true;
|
||||
if let Err(e) = #pallet_names::check_inherent(call, self) {
|
||||
result.put_error(
|
||||
#pallet_names::INHERENT_IDENTIFIER, &e
|
||||
).expect("There is only one fatal error; qed");
|
||||
if e.is_fatal_error() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})*
|
||||
)*
|
||||
|
||||
// Inherents are before any other extrinsics.
|
||||
// No module marked it as inherent thus it is not.
|
||||
@@ -115,6 +130,7 @@ pub fn expand_outer_inherent(
|
||||
}
|
||||
|
||||
#(
|
||||
#pallet_attrs
|
||||
match #pallet_names::is_inherent_required(self) {
|
||||
Ok(Some(e)) => {
|
||||
let found = block.extrinsics().iter().any(|xt| {
|
||||
@@ -177,14 +193,17 @@ pub fn expand_outer_inherent(
|
||||
false
|
||||
} else {
|
||||
let mut is_inherent = false;
|
||||
#({
|
||||
let call = <#unchecked_extrinsic as ExtrinsicCall>::call(xt);
|
||||
if let Some(call) = IsSubType::<_>::is_sub_type(call) {
|
||||
if #pallet_names::is_inherent(&call) {
|
||||
is_inherent = true;
|
||||
#(
|
||||
#pallet_attrs
|
||||
{
|
||||
let call = <#unchecked_extrinsic as ExtrinsicCall>::call(xt);
|
||||
if let Some(call) = IsSubType::<_>::is_sub_type(call) {
|
||||
if #pallet_names::is_inherent(&call) {
|
||||
is_inherent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
})*
|
||||
)*
|
||||
is_inherent
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use crate::construct_runtime::Pallet;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
use syn::{Ident, TypePath};
|
||||
|
||||
pub fn expand_runtime_metadata(
|
||||
@@ -47,8 +48,17 @@ pub fn expand_runtime_metadata(
|
||||
let event = expand_pallet_metadata_events(&filtered_names, runtime, scrate, decl);
|
||||
let constants = expand_pallet_metadata_constants(runtime, decl);
|
||||
let errors = expand_pallet_metadata_errors(runtime, decl);
|
||||
let attr = decl.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#attr
|
||||
#scrate::metadata::PalletMetadata {
|
||||
name: stringify!(#name),
|
||||
index: #index,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use crate::construct_runtime::{Pallet, SYSTEM_PALLET_NAME};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
use syn::{Generics, Ident};
|
||||
|
||||
pub fn expand_outer_origin(
|
||||
@@ -303,19 +304,35 @@ fn expand_origin_caller_variant(
|
||||
let part_is_generic = !generics.params.is_empty();
|
||||
let variant_name = &pallet.name;
|
||||
let path = &pallet.path;
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
match instance {
|
||||
Some(inst) if part_is_generic => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Origin<#runtime, #path::#inst>),)
|
||||
Some(inst) if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Origin<#runtime, #path::#inst>),
|
||||
},
|
||||
Some(inst) => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Origin<#path::#inst>),)
|
||||
Some(inst) => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Origin<#path::#inst>),
|
||||
},
|
||||
None if part_is_generic => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Origin<#runtime>),)
|
||||
None if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Origin<#runtime>),
|
||||
},
|
||||
None => {
|
||||
quote!(#[codec(index = #index)] #variant_name(#path::Origin),)
|
||||
None => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Origin),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -339,14 +356,24 @@ fn expand_origin_pallet_conversions(
|
||||
};
|
||||
|
||||
let doc_string = get_intra_doc_string(" Convert to runtime origin using", &path.module_name());
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#attr
|
||||
impl From<#pallet_origin> for OriginCaller {
|
||||
fn from(x: #pallet_origin) -> Self {
|
||||
OriginCaller::#variant_name(x)
|
||||
}
|
||||
}
|
||||
|
||||
#attr
|
||||
impl From<#pallet_origin> for Origin {
|
||||
#[doc = #doc_string]
|
||||
fn from(x: #pallet_origin) -> Self {
|
||||
@@ -355,6 +382,7 @@ fn expand_origin_pallet_conversions(
|
||||
}
|
||||
}
|
||||
|
||||
#attr
|
||||
impl From<Origin> for #scrate::sp_std::result::Result<#pallet_origin, Origin> {
|
||||
/// NOTE: converting to pallet origin loses the origin filter information.
|
||||
fn from(val: Origin) -> Self {
|
||||
@@ -366,6 +394,7 @@ fn expand_origin_pallet_conversions(
|
||||
}
|
||||
}
|
||||
|
||||
#attr
|
||||
impl TryFrom<OriginCaller> for #pallet_origin {
|
||||
type Error = OriginCaller;
|
||||
fn try_from(
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use crate::construct_runtime::Pallet;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
use syn::Ident;
|
||||
|
||||
pub fn expand_outer_validate_unsigned(
|
||||
@@ -26,14 +27,24 @@ pub fn expand_outer_validate_unsigned(
|
||||
scrate: &TokenStream,
|
||||
) -> TokenStream {
|
||||
let mut pallet_names = Vec::new();
|
||||
let mut pallet_attrs = Vec::new();
|
||||
let mut query_validate_unsigned_part_macros = Vec::new();
|
||||
|
||||
for pallet_decl in pallet_decls {
|
||||
if pallet_decl.exists_part("ValidateUnsigned") {
|
||||
let name = &pallet_decl.name;
|
||||
let path = &pallet_decl.path;
|
||||
let attr = pallet_decl.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
pallet_names.push(name);
|
||||
pallet_attrs.push(attr);
|
||||
query_validate_unsigned_part_macros.push(quote! {
|
||||
#path::__substrate_validate_unsigned_check::is_validate_unsigned_part_defined!(#name);
|
||||
});
|
||||
@@ -49,7 +60,10 @@ pub fn expand_outer_validate_unsigned(
|
||||
fn pre_dispatch(call: &Self::Call) -> Result<(), #scrate::unsigned::TransactionValidityError> {
|
||||
#[allow(unreachable_patterns)]
|
||||
match call {
|
||||
#( Call::#pallet_names(inner_call) => #pallet_names::pre_dispatch(inner_call), )*
|
||||
#(
|
||||
#pallet_attrs
|
||||
Call::#pallet_names(inner_call) => #pallet_names::pre_dispatch(inner_call),
|
||||
)*
|
||||
// pre-dispatch should not stop inherent extrinsics, validation should prevent
|
||||
// including arbitrary (non-inherent) extrinsics to blocks.
|
||||
_ => Ok(()),
|
||||
@@ -63,7 +77,10 @@ pub fn expand_outer_validate_unsigned(
|
||||
) -> #scrate::unsigned::TransactionValidity {
|
||||
#[allow(unreachable_patterns)]
|
||||
match call {
|
||||
#( Call::#pallet_names(inner_call) => #pallet_names::validate_unsigned(source, inner_call), )*
|
||||
#(
|
||||
#pallet_attrs
|
||||
Call::#pallet_names(inner_call) => #pallet_names::validate_unsigned(source, inner_call),
|
||||
)*
|
||||
_ => #scrate::unsigned::UnknownTransaction::NoUnsignedValidator.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,9 +144,11 @@
|
||||
mod expand;
|
||||
mod parse;
|
||||
|
||||
use cfg_expr::Predicate;
|
||||
use frame_support_procedural_tools::{
|
||||
generate_crate_access, generate_crate_access_2018, generate_hidden_includes,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use parse::{
|
||||
ExplicitRuntimeDeclaration, ImplicitRuntimeDeclaration, Pallet, RuntimeDeclaration,
|
||||
WhereSection,
|
||||
@@ -154,6 +156,10 @@ use parse::{
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
str::FromStr,
|
||||
};
|
||||
use syn::{Ident, Result};
|
||||
|
||||
/// The fixed name of the system pallet.
|
||||
@@ -223,6 +229,28 @@ fn construct_runtime_final_expansion(
|
||||
Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event<T>},`",
|
||||
)
|
||||
})?;
|
||||
if !system_pallet.cfg_pattern.is_empty() {
|
||||
return Err(syn::Error::new(
|
||||
system_pallet.name.span(),
|
||||
"`System` pallet declaration is feature gated, please remove any `#[cfg]` attributes",
|
||||
))
|
||||
}
|
||||
|
||||
let features = pallets
|
||||
.iter()
|
||||
.filter_map(|decl| {
|
||||
(!decl.cfg_pattern.is_empty()).then(|| {
|
||||
decl.cfg_pattern.iter().flat_map(|attr| {
|
||||
attr.predicates().filter_map(|pred| match pred {
|
||||
Predicate::Feature(feat) => Some(feat),
|
||||
Predicate::Test => Some("test"),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
let hidden_crate_name = "construct_runtime";
|
||||
let scrate = generate_crate_access(hidden_crate_name, "frame-support");
|
||||
@@ -231,7 +259,7 @@ fn construct_runtime_final_expansion(
|
||||
let outer_event = expand::expand_outer_event(&name, &pallets, &scrate)?;
|
||||
|
||||
let outer_origin = expand::expand_outer_origin(&name, system_pallet, &pallets, &scrate)?;
|
||||
let all_pallets = decl_all_pallets(&name, pallets.iter());
|
||||
let all_pallets = decl_all_pallets(&name, pallets.iter(), &features);
|
||||
let pallet_to_index = decl_pallet_runtime_setup(&name, &pallets, &scrate);
|
||||
|
||||
let dispatch = expand::expand_outer_dispatch(&name, system_pallet, &pallets, &scrate);
|
||||
@@ -293,40 +321,140 @@ fn construct_runtime_final_expansion(
|
||||
fn decl_all_pallets<'a>(
|
||||
runtime: &'a Ident,
|
||||
pallet_declarations: impl Iterator<Item = &'a Pallet>,
|
||||
features: &HashSet<&str>,
|
||||
) -> TokenStream2 {
|
||||
let mut types = TokenStream2::new();
|
||||
let mut names = Vec::new();
|
||||
let mut names_by_feature = features
|
||||
.iter()
|
||||
.powerset()
|
||||
.map(|feat| (feat, Vec::new()))
|
||||
.collect::<HashMap<_, _>>();
|
||||
for pallet_declaration in pallet_declarations {
|
||||
let type_name = &pallet_declaration.name;
|
||||
let pallet = &pallet_declaration.path;
|
||||
let mut generics = vec![quote!(#runtime)];
|
||||
generics.extend(pallet_declaration.instance.iter().map(|name| quote!(#pallet::#name)));
|
||||
let mut attrs = Vec::new();
|
||||
for cfg in &pallet_declaration.cfg_pattern {
|
||||
let feat = format!("#[cfg({})]\n", cfg.original());
|
||||
attrs.extend(TokenStream2::from_str(&feat).expect("was parsed successfully; qed"));
|
||||
}
|
||||
let type_decl = quote!(
|
||||
#(#attrs)*
|
||||
pub type #type_name = #pallet::Pallet <#(#generics),*>;
|
||||
);
|
||||
types.extend(type_decl);
|
||||
names.push(&pallet_declaration.name);
|
||||
|
||||
if pallet_declaration.cfg_pattern.is_empty() {
|
||||
for names in names_by_feature.values_mut() {
|
||||
names.push(&pallet_declaration.name);
|
||||
}
|
||||
} else {
|
||||
for (feature_set, names) in &mut names_by_feature {
|
||||
// Rust tidbit: if we have multiple `#[cfg]` feature on the same item, then the
|
||||
// predicates listed in all `#[cfg]` attributes are effectively joined by `and()`,
|
||||
// meaning that all of them must match in order to activate the item
|
||||
let is_feature_active = pallet_declaration.cfg_pattern.iter().all(|expr| {
|
||||
expr.eval(|pred| match pred {
|
||||
Predicate::Feature(f) => feature_set.contains(&f),
|
||||
Predicate::Test => feature_set.contains(&&"test"),
|
||||
_ => false,
|
||||
})
|
||||
});
|
||||
if is_feature_active {
|
||||
names.push(&pallet_declaration.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let system_pallet = match names.iter().find(|n| **n == SYSTEM_PALLET_NAME) {
|
||||
Some(name) => name,
|
||||
None =>
|
||||
return syn::Error::new(
|
||||
proc_macro2::Span::call_site(),
|
||||
"`System` pallet declaration is missing. \
|
||||
Please add this line: `System: frame_system::{Pallet, Call, Storage, Config, Event<T>},`",
|
||||
)
|
||||
.into_compile_error(),
|
||||
};
|
||||
let all_pallets_without_system = names_by_feature.iter().map(|(feature_set, names)| {
|
||||
let mut feature_set = feature_set.iter().collect::<HashSet<_>>();
|
||||
let test_cfg = feature_set.remove(&&&"test").then_some(quote!(test)).into_iter();
|
||||
let feature_set = feature_set.into_iter();
|
||||
let attr = quote!(#[cfg(all( #(#test_cfg),* #(feature = #feature_set),* ))]);
|
||||
let names = names.iter().filter(|n| **n != SYSTEM_PALLET_NAME);
|
||||
quote! {
|
||||
#attr
|
||||
/// All pallets included in the runtime as a nested tuple of types.
|
||||
/// Excludes the System pallet.
|
||||
pub type AllPalletsWithoutSystem = ( #(#names,)* );
|
||||
}
|
||||
});
|
||||
|
||||
let names_without_system =
|
||||
names.iter().filter(|n| **n != SYSTEM_PALLET_NAME).collect::<Vec<_>>();
|
||||
let names_reversed = names.clone().into_iter().rev().collect::<Vec<_>>();
|
||||
let names_without_system_reverse =
|
||||
names_without_system.clone().into_iter().rev().collect::<Vec<_>>();
|
||||
let names_reversed_with_system_first = std::iter::once(system_pallet)
|
||||
.chain(names_without_system_reverse.clone().into_iter())
|
||||
.collect::<Vec<_>>();
|
||||
let all_pallets_with_system = names_by_feature.iter().map(|(feature_set, names)| {
|
||||
let mut feature_set = feature_set.iter().collect::<HashSet<_>>();
|
||||
let test_cfg = feature_set.remove(&&&"test").then_some(quote!(test)).into_iter();
|
||||
let feature_set = feature_set.into_iter();
|
||||
let attr = quote!(#[cfg(all( #(#test_cfg),* #(feature = #feature_set),* ))]);
|
||||
quote! {
|
||||
#attr
|
||||
/// All pallets included in the runtime as a nested tuple of types.
|
||||
pub type AllPalletsWithSystem = ( #(#names,)* );
|
||||
}
|
||||
});
|
||||
|
||||
let all_pallets_without_system_reversed =
|
||||
names_by_feature.iter().map(|(feature_set, names)| {
|
||||
let mut feature_set = feature_set.iter().collect::<HashSet<_>>();
|
||||
let test_cfg = feature_set.remove(&&&"test").then_some(quote!(test)).into_iter();
|
||||
let feature_set = feature_set.into_iter();
|
||||
let attr = quote!(#[cfg(all( #(#test_cfg),* #(feature = #feature_set),* ))]);
|
||||
let names = names.iter().filter(|n| **n != SYSTEM_PALLET_NAME).rev();
|
||||
quote! {
|
||||
#attr
|
||||
/// All pallets included in the runtime as a nested tuple of types in reversed order.
|
||||
/// Excludes the System pallet.
|
||||
#[deprecated(note = "Using reverse pallet orders is deprecated. use only \
|
||||
`AllPalletWithSystem or AllPalletsWithoutSystem`")]
|
||||
pub type AllPalletsWithoutSystemReversed = ( #(#names,)* );
|
||||
}
|
||||
});
|
||||
|
||||
let all_pallets_with_system_reversed = names_by_feature.iter().map(|(feature_set, names)| {
|
||||
let mut feature_set = feature_set.iter().collect::<HashSet<_>>();
|
||||
let test_cfg = feature_set.remove(&&&"test").then_some(quote!(test)).into_iter();
|
||||
let feature_set = feature_set.into_iter();
|
||||
let attr = quote!(#[cfg(all( #(#test_cfg),* #(feature = #feature_set),* ))]);
|
||||
let names = names.iter().rev();
|
||||
quote! {
|
||||
#attr
|
||||
/// All pallets included in the runtime as a nested tuple of types in reversed order.
|
||||
#[deprecated(note = "Using reverse pallet orders is deprecated. use only \
|
||||
`AllPalletWithSystem or AllPalletsWithoutSystem`")]
|
||||
pub type AllPalletsWithSystemReversed = ( #(#names,)* );
|
||||
}
|
||||
});
|
||||
|
||||
let system_pallet =
|
||||
match names_by_feature[&Vec::new()].iter().find(|n| **n == SYSTEM_PALLET_NAME) {
|
||||
Some(name) => name,
|
||||
None =>
|
||||
return syn::Error::new(
|
||||
proc_macro2::Span::call_site(),
|
||||
"`System` pallet declaration is missing. \
|
||||
Please add this line: `System: frame_system,`",
|
||||
)
|
||||
.into_compile_error(),
|
||||
};
|
||||
|
||||
let all_pallets_reversed_with_system_first =
|
||||
names_by_feature.iter().map(|(feature_set, names)| {
|
||||
let mut feature_set = feature_set.iter().collect::<HashSet<_>>();
|
||||
let test_cfg = feature_set.remove(&&&"test").then_some(quote!(test)).into_iter();
|
||||
let feature_set = feature_set.into_iter();
|
||||
let attr = quote!(#[cfg(all( #(#test_cfg),* #(feature = #feature_set),* ))]);
|
||||
let names = std::iter::once(system_pallet)
|
||||
.chain(names.iter().rev().filter(|n| **n != SYSTEM_PALLET_NAME));
|
||||
quote! {
|
||||
#attr
|
||||
/// All pallets included in the runtime as a nested tuple of types in reversed order.
|
||||
/// With the system pallet first.
|
||||
#[deprecated(note = "Using reverse pallet orders is deprecated. use only \
|
||||
`AllPalletWithSystem or AllPalletsWithoutSystem`")]
|
||||
pub type AllPalletsReversedWithSystemFirst = ( #(#names,)* );
|
||||
}
|
||||
});
|
||||
|
||||
quote!(
|
||||
#types
|
||||
@@ -342,29 +470,15 @@ fn decl_all_pallets<'a>(
|
||||
https://github.com/paritytech/substrate/pull/10043")]
|
||||
pub type AllPallets = AllPalletsWithSystem;
|
||||
|
||||
/// All pallets included in the runtime as a nested tuple of types.
|
||||
pub type AllPalletsWithSystem = ( #(#names),* );
|
||||
#( #all_pallets_with_system )*
|
||||
|
||||
/// All pallets included in the runtime as a nested tuple of types.
|
||||
/// Excludes the System pallet.
|
||||
pub type AllPalletsWithoutSystem = ( #(#names_without_system),* );
|
||||
#( #all_pallets_without_system )*
|
||||
|
||||
/// All pallets included in the runtime as a nested tuple of types in reversed order.
|
||||
/// Excludes the System pallet.
|
||||
#[deprecated(note = "Using reverse pallet orders is deprecated. use only \
|
||||
`AllPalletWithSystem or AllPalletsWithoutSystem`")]
|
||||
pub type AllPalletsWithoutSystemReversed =( #(#names_without_system_reverse),* );
|
||||
#( #all_pallets_with_system_reversed )*
|
||||
|
||||
/// All pallets included in the runtime as a nested tuple of types in reversed order.
|
||||
#[deprecated(note = "Using reverse pallet orders is deprecated. use only \
|
||||
`AllPalletWithSystem or AllPalletsWithoutSystem`")]
|
||||
pub type AllPalletsWithSystemReversed = ( #(#names_reversed),* );
|
||||
#( #all_pallets_without_system_reversed )*
|
||||
|
||||
/// All pallets included in the runtime as a nested tuple of types in reversed order.
|
||||
/// With the system pallet first.
|
||||
#[deprecated(note = "Using reverse pallet orders is deprecated. use only \
|
||||
`AllPalletWithSystem or AllPalletsWithoutSystem`")]
|
||||
pub type AllPalletsReversedWithSystemFirst = ( #(#names_reversed_with_system_first),* );
|
||||
#( #all_pallets_reversed_with_system_first )*
|
||||
)
|
||||
}
|
||||
|
||||
@@ -387,6 +501,19 @@ fn decl_pallet_runtime_setup(
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let pallet_attrs = pallet_declarations
|
||||
.iter()
|
||||
.map(|pallet| {
|
||||
pallet.cfg_pattern.iter().fold(TokenStream2::new(), |acc, pattern| {
|
||||
let attr = TokenStream2::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote!(
|
||||
/// Provides an implementation of `PalletInfo` to provide information
|
||||
@@ -397,6 +524,7 @@ fn decl_pallet_runtime_setup(
|
||||
fn index<P: 'static>() -> Option<usize> {
|
||||
let type_id = #scrate::sp_std::any::TypeId::of::<P>();
|
||||
#(
|
||||
#pallet_attrs
|
||||
if type_id == #scrate::sp_std::any::TypeId::of::<#names>() {
|
||||
return Some(#indices)
|
||||
}
|
||||
@@ -408,6 +536,7 @@ fn decl_pallet_runtime_setup(
|
||||
fn name<P: 'static>() -> Option<&'static str> {
|
||||
let type_id = #scrate::sp_std::any::TypeId::of::<P>();
|
||||
#(
|
||||
#pallet_attrs
|
||||
if type_id == #scrate::sp_std::any::TypeId::of::<#names>() {
|
||||
return Some(#name_strings)
|
||||
}
|
||||
@@ -419,6 +548,7 @@ fn decl_pallet_runtime_setup(
|
||||
fn module_name<P: 'static>() -> Option<&'static str> {
|
||||
let type_id = #scrate::sp_std::any::TypeId::of::<P>();
|
||||
#(
|
||||
#pallet_attrs
|
||||
if type_id == #scrate::sp_std::any::TypeId::of::<#names>() {
|
||||
return Some(#module_names)
|
||||
}
|
||||
@@ -430,6 +560,7 @@ fn decl_pallet_runtime_setup(
|
||||
fn crate_version<P: 'static>() -> Option<#scrate::traits::CrateVersion> {
|
||||
let type_id = #scrate::sp_std::any::TypeId::of::<P>();
|
||||
#(
|
||||
#pallet_attrs
|
||||
if type_id == #scrate::sp_std::any::TypeId::of::<#names>() {
|
||||
return Some(
|
||||
<#pallet_structs as #scrate::traits::PalletInfoAccess>::crate_version()
|
||||
|
||||
@@ -23,7 +23,7 @@ use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
token, Error, Ident, Path, Result, Token,
|
||||
token, Attribute, Error, Ident, Path, Result, Token,
|
||||
};
|
||||
|
||||
mod keyword {
|
||||
@@ -185,6 +185,8 @@ impl Parse for WhereDefinition {
|
||||
pub struct PalletDeclaration {
|
||||
/// The name of the pallet, e.g.`System` in `System: frame_system`.
|
||||
pub name: Ident,
|
||||
/// Optional attributes tagged right above a pallet declaration.
|
||||
pub attrs: Vec<Attribute>,
|
||||
/// Optional fixed index, e.g. `MyPallet ... = 3,`.
|
||||
pub index: Option<u8>,
|
||||
/// The path of the pallet, e.g. `frame_system` in `System: frame_system`.
|
||||
@@ -212,6 +214,8 @@ pub enum SpecifiedParts {
|
||||
|
||||
impl Parse for PalletDeclaration {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let attrs = input.call(Attribute::parse_outer)?;
|
||||
|
||||
let name = input.parse()?;
|
||||
let _: Token![:] = input.parse()?;
|
||||
let path = input.parse()?;
|
||||
@@ -279,7 +283,7 @@ impl Parse for PalletDeclaration {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Self { name, path, instance, pallet_parts, specified_parts, index })
|
||||
Ok(Self { attrs, name, path, instance, pallet_parts, specified_parts, index })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,6 +539,8 @@ pub struct Pallet {
|
||||
pub instance: Option<Ident>,
|
||||
/// The pallet parts to use for the pallet.
|
||||
pub pallet_parts: Vec<PalletPart>,
|
||||
/// Expressions specified inside of a #[cfg] attribute.
|
||||
pub cfg_pattern: Vec<cfg_expr::Expression>,
|
||||
}
|
||||
|
||||
impl Pallet {
|
||||
@@ -647,11 +653,32 @@ fn convert_pallets(pallets: Vec<PalletDeclaration>) -> syn::Result<PalletsConver
|
||||
SpecifiedParts::All => (),
|
||||
}
|
||||
|
||||
let cfg_pattern = pallet
|
||||
.attrs
|
||||
.iter()
|
||||
.map(|attr| {
|
||||
if attr.path.segments.len() != 1 || attr.path.segments[0].ident != "cfg" {
|
||||
let msg = "Unsupported attribute, only #[cfg] is supported on pallet \
|
||||
declarations in `construct_runtime`";
|
||||
return Err(syn::Error::new(attr.span(), msg))
|
||||
}
|
||||
|
||||
attr.parse_args_with(|input: syn::parse::ParseStream| {
|
||||
// Required, otherwise the parse stream doesn't advance and will result in
|
||||
// an error.
|
||||
let input = input.parse::<proc_macro2::TokenStream>()?;
|
||||
cfg_expr::Expression::parse(&input.to_string())
|
||||
.map_err(|e| syn::Error::new(attr.span(), e.to_string()))
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
Ok(Pallet {
|
||||
name: pallet.name,
|
||||
index: final_index,
|
||||
path: pallet.path,
|
||||
instance: pallet.instance,
|
||||
cfg_pattern,
|
||||
pallet_parts,
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user