mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-18 01:21:01 +00:00
Correctly serialize code in chain spec as hex (#4025)
* Correctly serialize code in chain spec as hex. Due to a bug, the runtime code was previously serialized as a JSON array of numbers, pretty printed one byte per line. * Remove panic in macro and whitelist attribute types for storage genesis config lines. * Use syn::Error to enforce whitelisted attributes on genesis config. * Blacklist genesis extra config line attributes instead of whitelist.
This commit is contained in:
committed by
Bastian Köcher
parent
cca9ab436c
commit
d9c2ac5fd7
+24
-14
@@ -18,14 +18,14 @@
|
|||||||
|
|
||||||
use srml_support_procedural_tools::syn_ext as ext;
|
use srml_support_procedural_tools::syn_ext as ext;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use syn::parse_quote;
|
use syn::{spanned::Spanned, parse_quote};
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use super::super::{DeclStorageDefExt, StorageLineTypeDef};
|
use super::super::{DeclStorageDefExt, StorageLineTypeDef};
|
||||||
|
|
||||||
pub struct GenesisConfigFieldDef {
|
pub struct GenesisConfigFieldDef {
|
||||||
pub doc: Vec<syn::Meta>,
|
|
||||||
pub name: syn::Ident,
|
pub name: syn::Ident,
|
||||||
pub typ: syn::Type,
|
pub typ: syn::Type,
|
||||||
|
pub attrs: Vec<syn::Meta>,
|
||||||
pub default: TokenStream,
|
pub default: TokenStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,8 +43,8 @@ pub struct GenesisConfigDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GenesisConfigDef {
|
impl GenesisConfigDef {
|
||||||
pub fn from_def(def: &DeclStorageDefExt) -> Self {
|
pub fn from_def(def: &DeclStorageDefExt) -> syn::Result<Self> {
|
||||||
let fields = Self::get_genesis_config_field_defs(def);
|
let fields = Self::get_genesis_config_field_defs(def)?;
|
||||||
|
|
||||||
let is_generic = fields.iter()
|
let is_generic = fields.iter()
|
||||||
.any(|field| ext::type_contains_ident(&field.typ, &def.module_runtime_generic));
|
.any(|field| ext::type_contains_ident(&field.typ, &def.module_runtime_generic));
|
||||||
@@ -71,17 +71,19 @@ impl GenesisConfigDef {
|
|||||||
(quote!(), quote!(), quote!(), None)
|
(quote!(), quote!(), quote!(), None)
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Ok(Self {
|
||||||
is_generic,
|
is_generic,
|
||||||
fields,
|
fields,
|
||||||
genesis_struct_decl,
|
genesis_struct_decl,
|
||||||
genesis_struct,
|
genesis_struct,
|
||||||
genesis_impl,
|
genesis_impl,
|
||||||
genesis_where_clause,
|
genesis_where_clause,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_genesis_config_field_defs(def: &DeclStorageDefExt) -> Vec<GenesisConfigFieldDef> {
|
fn get_genesis_config_field_defs(def: &DeclStorageDefExt)
|
||||||
|
-> syn::Result<Vec<GenesisConfigFieldDef>>
|
||||||
|
{
|
||||||
let mut config_field_defs = Vec::new();
|
let mut config_field_defs = Vec::new();
|
||||||
|
|
||||||
for (config_field, line) in def.storage_lines.iter()
|
for (config_field, line) in def.storage_lines.iter()
|
||||||
@@ -114,31 +116,39 @@ impl GenesisConfigDef {
|
|||||||
.unwrap_or_else(|| quote!( Default::default() ));
|
.unwrap_or_else(|| quote!( Default::default() ));
|
||||||
|
|
||||||
config_field_defs.push(GenesisConfigFieldDef {
|
config_field_defs.push(GenesisConfigFieldDef {
|
||||||
doc: line.doc_attrs.clone(),
|
|
||||||
name: config_field,
|
name: config_field,
|
||||||
typ,
|
typ,
|
||||||
|
attrs: line.doc_attrs.clone(),
|
||||||
default,
|
default,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for line in &def.extra_genesis_config_lines {
|
for line in &def.extra_genesis_config_lines {
|
||||||
let doc = line.attrs.iter()
|
let attrs = line.attrs.iter()
|
||||||
.filter_map(|a| a.parse_meta().ok())
|
.map(|attr| {
|
||||||
.filter(|m| m.path().is_ident("doc"))
|
let meta = attr.parse_meta()?;
|
||||||
.collect();
|
if meta.path().is_ident("cfg") {
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
meta.span(),
|
||||||
|
"extra genesis config items do not support `cfg` attribute"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(meta)
|
||||||
|
})
|
||||||
|
.collect::<syn::Result<_>>()?;
|
||||||
|
|
||||||
let default = line.default.as_ref().map(|e| quote!( #e ))
|
let default = line.default.as_ref().map(|e| quote!( #e ))
|
||||||
.unwrap_or_else(|| quote!( Default::default() ));
|
.unwrap_or_else(|| quote!( Default::default() ));
|
||||||
|
|
||||||
|
|
||||||
config_field_defs.push(GenesisConfigFieldDef {
|
config_field_defs.push(GenesisConfigFieldDef {
|
||||||
doc,
|
|
||||||
name: line.name.clone(),
|
name: line.name.clone(),
|
||||||
typ: line.typ.clone(),
|
typ: line.typ.clone(),
|
||||||
|
attrs,
|
||||||
default,
|
default,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
config_field_defs
|
Ok(config_field_defs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ fn decl_genesis_config_and_impl_default(
|
|||||||
genesis_config: &GenesisConfigDef,
|
genesis_config: &GenesisConfigDef,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let config_fields = genesis_config.fields.iter().map(|field| {
|
let config_fields = genesis_config.fields.iter().map(|field| {
|
||||||
let (name, typ, doc) = (&field.name, &field.typ, &field.doc);
|
let (name, typ, attrs) = (&field.name, &field.typ, &field.attrs);
|
||||||
quote!( #( #[ #doc] )* pub #name: #typ, )
|
quote!( #( #[ #attrs] )* pub #name: #typ, )
|
||||||
});
|
});
|
||||||
|
|
||||||
let config_field_defaults = genesis_config.fields.iter().map(|field| {
|
let config_field_defaults = genesis_config.fields.iter().map(|field| {
|
||||||
let (name, default, doc) = (&field.name, &field.default, &field.doc);
|
let (name, default) = (&field.name, &field.default);
|
||||||
quote!( #( #[ #doc] )* #name: #default, )
|
quote!( #name: #default, )
|
||||||
});
|
});
|
||||||
|
|
||||||
let serde_bug_bound = if !genesis_config.fields.is_empty() {
|
let serde_bug_bound = if !genesis_config.fields.is_empty() {
|
||||||
@@ -188,10 +188,13 @@ pub fn genesis_config_and_build_storage(
|
|||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let builders = BuilderDef::from_def(scrate, def);
|
let builders = BuilderDef::from_def(scrate, def);
|
||||||
if !builders.blocks.is_empty() {
|
if !builders.blocks.is_empty() {
|
||||||
let genesis_config = &GenesisConfigDef::from_def(def);
|
let genesis_config = match GenesisConfigDef::from_def(def) {
|
||||||
|
Ok(genesis_config) => genesis_config,
|
||||||
|
Err(err) => return err.to_compile_error(),
|
||||||
|
};
|
||||||
let decl_genesis_config_and_impl_default =
|
let decl_genesis_config_and_impl_default =
|
||||||
decl_genesis_config_and_impl_default(scrate, genesis_config);
|
decl_genesis_config_and_impl_default(scrate, &genesis_config);
|
||||||
let impl_build_storage = impl_build_storage(scrate, def, genesis_config, &builders);
|
let impl_build_storage = impl_build_storage(scrate, def, &genesis_config, &builders);
|
||||||
|
|
||||||
quote!{
|
quote!{
|
||||||
#decl_genesis_config_and_impl_default
|
#decl_genesis_config_and_impl_default
|
||||||
|
|||||||
Reference in New Issue
Block a user