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:
Keith Yeung
2022-08-25 16:56:18 +08:00
committed by GitHub
parent edc8f7b409
commit 948af11977
20 changed files with 480 additions and 85 deletions
@@ -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(),
}
}