mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-22 14:58:04 +00:00
Use scale-encode and scale-decode to encode and decode based on metadata (#842)
* WIP EncodeAsType and DecodeAsType * remove silly cli experiment code * Get things finally compiling with EncodeAsType and DecodeAsType * update codegen test and WrapperKeepOpaque proper impl (in case it shows up in codegen) * fix tests * accomodate scale-value changes * starting to migrate to EncodeAsType/DecodeAsType * static event decoding and tx encoding to use DecodeAsFields/EncodeAsFields * some tidy up and add decode(skip) attrs where needed * fix root event decoding * #[codec(skip)] will do, and combine map_key stuff into storage_address since it's all specific to that * fmt and clippy * update Cargo.lock * remove patched scale-encode * bump scale-encode to 0.1 and remove unused dep in testing crate * update deps and use released scale-decode * update scale-value to latest to remove git branch * Apply suggestions from code review Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> * remove sorting in derives/attr generation; spit them out in order given * re-add derive sorting; it's a hashmap * StaticTxPayload and DynamicTxPayload rolled into single Payload struct * StaticStorageAddress and DynamicStorageAddress into single Address struct * Fix storage address byte retrieval * StaticConstantAddress and DynamicConstantAddress => Address * Simplify storage codegen to fix test * Add comments * Alias to RuntimeEvent rather than making another, and prep for substituting call type * remove unnecessary clone * Fix docs and failing UI test * root_bytes -> to_root_bytes * document error case in StorageClient::address_bytes() --------- Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
This commit is contained in:
+28
-59
@@ -12,7 +12,6 @@ use frame_metadata::{
|
||||
StorageEntryMetadata,
|
||||
StorageEntryModifier,
|
||||
StorageEntryType,
|
||||
StorageHasher,
|
||||
};
|
||||
use heck::ToSnakeCase as _;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
@@ -84,31 +83,12 @@ fn generate_storage_entry_fns(
|
||||
crate_path: &CratePath,
|
||||
should_gen_docs: bool,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let (fields, key_impl) = match storage_entry.ty {
|
||||
let (fields, key_impl) = match &storage_entry.ty {
|
||||
StorageEntryType::Plain(_) => (vec![], quote!(vec![])),
|
||||
StorageEntryType::Map {
|
||||
ref key,
|
||||
ref hashers,
|
||||
..
|
||||
} => {
|
||||
StorageEntryType::Map { key, .. } => {
|
||||
let key_ty = type_gen.resolve_type(key.id());
|
||||
let hashers = hashers
|
||||
.iter()
|
||||
.map(|hasher| {
|
||||
let hasher = match hasher {
|
||||
StorageHasher::Blake2_128 => "Blake2_128",
|
||||
StorageHasher::Blake2_256 => "Blake2_256",
|
||||
StorageHasher::Blake2_128Concat => "Blake2_128Concat",
|
||||
StorageHasher::Twox128 => "Twox128",
|
||||
StorageHasher::Twox256 => "Twox256",
|
||||
StorageHasher::Twox64Concat => "Twox64Concat",
|
||||
StorageHasher::Identity => "Identity",
|
||||
};
|
||||
let hasher = format_ident!("{}", hasher);
|
||||
quote!( #crate_path::storage::address::StorageHasher::#hasher )
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
match key_ty.type_def() {
|
||||
// An N-map; return each of the keys separately.
|
||||
TypeDef::Tuple(tuple) => {
|
||||
let fields = tuple
|
||||
.fields()
|
||||
@@ -121,46 +101,23 @@ fn generate_storage_entry_fns(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let key_impl = if hashers.len() == fields.len() {
|
||||
// If the number of hashers matches the number of fields, we're dealing with
|
||||
// something shaped like a StorageNMap, and each field should be hashed separately
|
||||
// according to the corresponding hasher.
|
||||
let keys = hashers
|
||||
.into_iter()
|
||||
.zip(&fields)
|
||||
.map(|(hasher, (field_name, _))| {
|
||||
quote!( #crate_path::storage::address::StorageMapKey::new(#field_name.borrow(), #hasher) )
|
||||
});
|
||||
quote! {
|
||||
vec![ #( #keys ),* ]
|
||||
}
|
||||
} else if hashers.len() == 1 {
|
||||
// If there is one hasher, then however many fields we have, we want to hash a
|
||||
// tuple of them using the one hasher we're told about. This corresponds to a
|
||||
// StorageMap.
|
||||
let hasher = hashers.get(0).expect("checked for 1 hasher");
|
||||
let items =
|
||||
fields.iter().map(|(field_name, _)| quote!( #field_name ));
|
||||
quote! {
|
||||
vec![ #crate_path::storage::address::StorageMapKey::new(&(#( #items.borrow() ),*), #hasher) ]
|
||||
}
|
||||
} else {
|
||||
return Err(CodegenError::MismatchHashers(
|
||||
hashers.len(),
|
||||
fields.len(),
|
||||
))
|
||||
let keys = fields
|
||||
.iter()
|
||||
.map(|(field_name, _)| {
|
||||
quote!( #crate_path::storage::address::StaticStorageMapKey::new(#field_name.borrow()) )
|
||||
});
|
||||
let key_impl = quote! {
|
||||
vec![ #( #keys ),* ]
|
||||
};
|
||||
|
||||
(fields, key_impl)
|
||||
}
|
||||
// A map with a single key; return the single key.
|
||||
_ => {
|
||||
let ty_path = type_gen.resolve_type_path(key.id());
|
||||
let fields = vec![(format_ident!("_0"), ty_path)];
|
||||
let Some(hasher) = hashers.get(0) else {
|
||||
return Err(CodegenError::MissingHasher)
|
||||
};
|
||||
let key_impl = quote! {
|
||||
vec![ #crate_path::storage::address::StorageMapKey::new(_0.borrow(), #hasher) ]
|
||||
vec![ #crate_path::storage::address::StaticStorageMapKey::new(_0.borrow()) ]
|
||||
};
|
||||
(fields, key_impl)
|
||||
}
|
||||
@@ -233,8 +190,14 @@ fn generate_storage_entry_fns(
|
||||
#docs
|
||||
pub fn #fn_name_root(
|
||||
&self,
|
||||
) -> #crate_path::storage::address::StaticStorageAddress::<#crate_path::metadata::DecodeStaticType<#storage_entry_value_ty>, (), #is_defaultable_type, #is_iterable_type> {
|
||||
#crate_path::storage::address::StaticStorageAddress::new(
|
||||
) -> #crate_path::storage::address::Address::<
|
||||
#crate_path::storage::address::StaticStorageMapKey,
|
||||
#storage_entry_value_ty,
|
||||
(),
|
||||
#is_defaultable_type,
|
||||
#is_iterable_type
|
||||
> {
|
||||
#crate_path::storage::address::Address::new_static(
|
||||
#pallet_name,
|
||||
#storage_name,
|
||||
Vec::new(),
|
||||
@@ -252,8 +215,14 @@ fn generate_storage_entry_fns(
|
||||
pub fn #fn_name(
|
||||
&self,
|
||||
#( #key_args, )*
|
||||
) -> #crate_path::storage::address::StaticStorageAddress::<#crate_path::metadata::DecodeStaticType<#storage_entry_value_ty>, #crate_path::storage::address::Yes, #is_defaultable_type, #is_iterable_type> {
|
||||
#crate_path::storage::address::StaticStorageAddress::new(
|
||||
) -> #crate_path::storage::address::Address::<
|
||||
#crate_path::storage::address::StaticStorageMapKey,
|
||||
#storage_entry_value_ty,
|
||||
#crate_path::storage::address::Yes,
|
||||
#is_defaultable_type,
|
||||
#is_iterable_type
|
||||
> {
|
||||
#crate_path::storage::address::Address::new_static(
|
||||
#pallet_name,
|
||||
#storage_name,
|
||||
#key_impl,
|
||||
|
||||
Reference in New Issue
Block a user