mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 17:31:03 +00:00
config: Handle hasher and header
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
@@ -3,9 +3,10 @@
|
|||||||
// see LICENSE for license details.
|
// see LICENSE for license details.
|
||||||
|
|
||||||
use heck::ToSnakeCase as _;
|
use heck::ToSnakeCase as _;
|
||||||
|
use scale_info::{TypeDef, TypeDefComposite};
|
||||||
use scale_typegen::typegen::ir::ToTokensWithSettings;
|
use scale_typegen::typegen::ir::ToTokensWithSettings;
|
||||||
use scale_typegen::TypeGenerator;
|
use scale_typegen::TypeGenerator;
|
||||||
use std::collections::HashSet;
|
use std::{any::Any, collections::HashSet};
|
||||||
use subxt_metadata::{CustomValueMetadata, Metadata};
|
use subxt_metadata::{CustomValueMetadata, Metadata};
|
||||||
|
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
@@ -20,14 +21,113 @@ pub fn generate_custom_values(
|
|||||||
let mut fn_names_taken = HashSet::new();
|
let mut fn_names_taken = HashSet::new();
|
||||||
let custom = metadata.custom();
|
let custom = metadata.custom();
|
||||||
let custom_types = custom.iter().map(|custom| {
|
let custom_types = custom.iter().map(|custom| {
|
||||||
let name = format_ident!("{}", custom.name());
|
let name_str = custom.name();
|
||||||
|
|
||||||
let Ok(ty) = type_gen.resolve_type_path(custom.type_id()) else {
|
let name = format_ident!("{}", name_str);
|
||||||
|
|
||||||
|
let Ok(ty_path) = type_gen.resolve_type_path(custom.type_id()) else {
|
||||||
return quote! {};
|
return quote! {};
|
||||||
};
|
};
|
||||||
let ty = ty.to_token_stream(type_gen.settings());
|
let ty = ty_path.to_token_stream(type_gen.settings());
|
||||||
|
|
||||||
|
let mut maybe_impl = None;
|
||||||
|
let mut extra = None;
|
||||||
|
if name_str == "Hashing" {
|
||||||
|
// Extract hasher name
|
||||||
|
let ty_path_str = ty.to_string();
|
||||||
|
if ty_path_str.contains("BlakeTwo256") {
|
||||||
|
maybe_impl = Some(quote! {
|
||||||
|
impl #crate_path::config::Hasher for #ty {
|
||||||
|
type Output = #crate_path::utils::H256;
|
||||||
|
|
||||||
|
fn hash(s: &[u8]) -> Self::Output {
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
#crate_path::storage::utils::hash_bytes(s, #crate_path::storage::utils::StorageHasher::Blake2_256, &mut bytes);
|
||||||
|
let arr: [u8; 32] = bytes.try_into().expect("Invalid hashing output provided");
|
||||||
|
arr.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if name_str == "Header" {
|
||||||
|
// Extract header number from the provided type.
|
||||||
|
let Ok(ty_res) = type_gen.resolve_type(custom.type_id()) else {
|
||||||
|
return quote! {};
|
||||||
|
};
|
||||||
|
|
||||||
|
let TypeDef::Composite(composite) = &ty_res.type_def else {
|
||||||
|
return quote! {};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sanity check for the number type.
|
||||||
|
let number_ty = composite.fields.iter().find_map(
|
||||||
|
|field| if let Some(n) = &field.name {
|
||||||
|
if n == "number" {
|
||||||
|
Some(field.ty.id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(num) = number_ty {
|
||||||
|
|
||||||
|
let Ok(ty_path) = type_gen.resolve_type_path(num) else {
|
||||||
|
return quote! {};
|
||||||
|
};
|
||||||
|
|
||||||
|
if !ty_path.is_compact() {
|
||||||
|
let ty = ty_path.to_token_stream(type_gen.settings());
|
||||||
|
|
||||||
|
extra = Some(quote! {
|
||||||
|
pub type HeaderNumber = #ty;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Ty is compact.
|
||||||
|
let Ok(ty_res) = type_gen.resolve_type(num) else {
|
||||||
|
return quote! {};
|
||||||
|
};
|
||||||
|
|
||||||
|
let TypeDef::Compact(compact) = &ty_res.type_def else {
|
||||||
|
return quote! {};
|
||||||
|
};
|
||||||
|
let compact_ty_id = compact.type_param.id;
|
||||||
|
|
||||||
|
let Ok(ty_path) = type_gen.resolve_type_path(compact_ty_id) else {
|
||||||
|
return quote! {};
|
||||||
|
};
|
||||||
|
let ty = ty_path.to_token_stream(type_gen.settings());
|
||||||
|
|
||||||
|
extra = Some(quote! {
|
||||||
|
pub type HeaderNumber = #ty;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
maybe_impl = Some(quote! {
|
||||||
|
impl #crate_path::config::Header for #ty {
|
||||||
|
type Number = HeaderNumber;
|
||||||
|
type Hasher = Hashing;
|
||||||
|
|
||||||
|
// If we got to this point, the `number` field exists on the header
|
||||||
|
// structure.
|
||||||
|
fn number(&self) -> Self::Number {
|
||||||
|
self.number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
pub type #name = #ty;
|
pub type #name = #ty;
|
||||||
|
|
||||||
|
#maybe_impl
|
||||||
|
#extra
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
mod storage_key;
|
mod storage_key;
|
||||||
mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
pub mod address;
|
pub mod address;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ use crate::error::{Error, MetadataError};
|
|||||||
use crate::metadata::Metadata;
|
use crate::metadata::Metadata;
|
||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use subxt_metadata::{PalletMetadata, StorageEntryMetadata, StorageHasher};
|
pub use subxt_metadata::StorageHasher;
|
||||||
|
use subxt_metadata::{PalletMetadata, StorageEntryMetadata};
|
||||||
|
|
||||||
/// Return the root of a given [`Address`]: hash the pallet name and entry name
|
/// Return the root of a given [`Address`]: hash the pallet name and entry name
|
||||||
/// and append those bytes to the output.
|
/// and append those bytes to the output.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
use subxt::{OnlineClient, SubstrateConfig};
|
use subxt::{OnlineClient, SubstrateConfig};
|
||||||
|
use subxt_core::config::substrate::SubstrateHeader;
|
||||||
use subxt_core::config::{Config, DefaultExtrinsicParams};
|
use subxt_core::config::{Config, DefaultExtrinsicParams};
|
||||||
use subxt_signer::sr25519::dev;
|
use subxt_signer::sr25519::dev;
|
||||||
|
|
||||||
@@ -20,10 +21,25 @@ impl Config for MetadataConfig {
|
|||||||
|
|
||||||
// Present in metadata but this PoC needs to add
|
// Present in metadata but this PoC needs to add
|
||||||
// fn specific per name of type to impl the hashing fn.
|
// fn specific per name of type to impl the hashing fn.
|
||||||
type Hasher = <SubstrateConfig as Config>::Hasher;
|
// type Hasher = <SubstrateConfig as Config>::Hasher;
|
||||||
|
//
|
||||||
|
// TODO: Eventually extend this to a DynamicHasher object instead.
|
||||||
|
// Similar logic already exists for StorageHasher.
|
||||||
|
type Hasher = polkadot::custom_types::Hashing;
|
||||||
|
|
||||||
// Present in metadata but this PoC needs to impl the header
|
// Present in metadata but this PoC needs to impl the header
|
||||||
// trait to make use of this.
|
// trait to make use of this.
|
||||||
type Header = <SubstrateConfig as Config>::Header;
|
// type Header = <SubstrateConfig as Config>::Header;
|
||||||
|
|
||||||
|
// The metadata header type must implement `Deserialize`, which
|
||||||
|
// must be manually implemented for the Digest logs of the header.
|
||||||
|
// An alternative is to extract the header number and use the
|
||||||
|
// generated hasher to expose the same information, this is not
|
||||||
|
// as robust and codgen can be used instead.
|
||||||
|
// type Header = polkadot::custom_types::Header;
|
||||||
|
type Header =
|
||||||
|
SubstrateHeader<polkadot::custom_types::HeaderNumber, polkadot::custom_types::Hashing>;
|
||||||
|
|
||||||
// Same story, present in md but needs subxt::tx::Signer<T>.
|
// Same story, present in md but needs subxt::tx::Signer<T>.
|
||||||
// type Signature = polkadot::custom_types::Signature;
|
// type Signature = polkadot::custom_types::Signature;
|
||||||
type Signature = <SubstrateConfig as Config>::Signature;
|
type Signature = <SubstrateConfig as Config>::Signature;
|
||||||
|
|||||||
Reference in New Issue
Block a user