mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 04:37:57 +00:00
Codegen for custom values in metadata (#1117)
* work in progress * add custom types access * nit * custom values client * adjust light client * adjust doc comments * adjust book for custom values in code gen * format and check docs * work in progress * add custom types access * nit * custom values client * adjust light client * codegen and validation * adjust docs * use ignore in docs in book * change iter implementation * use validation hash and other codegen changes * add ui test for custom values codegen * allow 'latest' metadata to be returned from the fallback code (#1127) * nits * fix validation check * fix comments * nits --------- Co-authored-by: James Wilson <james@jsdw.me>
This commit is contained in:
+63
-21
@@ -20,13 +20,14 @@ mod from_into;
|
||||
mod utils;
|
||||
|
||||
use scale_info::{form::PortableForm, PortableRegistry, Variant};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use utils::ordered_map::OrderedMap;
|
||||
use utils::variant_index::VariantIndex;
|
||||
|
||||
type ArcStr = Arc<str>;
|
||||
|
||||
use crate::utils::validation::{get_custom_value_hash, HASH_LEN};
|
||||
pub use from_into::TryFromError;
|
||||
pub use utils::validation::MetadataHasher;
|
||||
|
||||
@@ -52,7 +53,7 @@ pub struct Metadata {
|
||||
/// Details about each of the runtime API traits.
|
||||
apis: OrderedMap<ArcStr, RuntimeApiMetadataInner>,
|
||||
/// Allows users to add custom types to the metadata. A map that associates a string key to a `CustomValueMetadata`.
|
||||
custom: CustomMetadata,
|
||||
custom: frame_metadata::v15::CustomMetadata<PortableForm>,
|
||||
}
|
||||
|
||||
impl Metadata {
|
||||
@@ -135,8 +136,11 @@ impl Metadata {
|
||||
}
|
||||
|
||||
/// Returns custom user defined types
|
||||
pub fn custom(&self) -> &CustomMetadata {
|
||||
&self.custom
|
||||
pub fn custom(&self) -> CustomMetadata<'_> {
|
||||
CustomMetadata {
|
||||
types: self.types(),
|
||||
inner: &self.custom,
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtain a unique hash representing this metadata or specific parts of it.
|
||||
@@ -154,7 +158,7 @@ impl Metadata {
|
||||
}
|
||||
|
||||
/// Get type hash for a type in the registry
|
||||
pub fn type_hash(&self, id: u32) -> Option<[u8; 32]> {
|
||||
pub fn type_hash(&self, id: u32) -> Option<[u8; HASH_LEN]> {
|
||||
self.types.resolve(id)?;
|
||||
Some(crate::utils::validation::get_type_hash(
|
||||
&self.types,
|
||||
@@ -265,22 +269,22 @@ impl<'a> PalletMetadata<'a> {
|
||||
}
|
||||
|
||||
/// Return a hash for the storage entry, or None if it was not found.
|
||||
pub fn storage_hash(&self, entry_name: &str) -> Option<[u8; 32]> {
|
||||
pub fn storage_hash(&self, entry_name: &str) -> Option<[u8; HASH_LEN]> {
|
||||
crate::utils::validation::get_storage_hash(self, entry_name)
|
||||
}
|
||||
|
||||
/// Return a hash for the constant, or None if it was not found.
|
||||
pub fn constant_hash(&self, constant_name: &str) -> Option<[u8; 32]> {
|
||||
pub fn constant_hash(&self, constant_name: &str) -> Option<[u8; HASH_LEN]> {
|
||||
crate::utils::validation::get_constant_hash(self, constant_name)
|
||||
}
|
||||
|
||||
/// Return a hash for the call, or None if it was not found.
|
||||
pub fn call_hash(&self, call_name: &str) -> Option<[u8; 32]> {
|
||||
pub fn call_hash(&self, call_name: &str) -> Option<[u8; HASH_LEN]> {
|
||||
crate::utils::validation::get_call_hash(self, call_name)
|
||||
}
|
||||
|
||||
/// Return a hash for the entire pallet.
|
||||
pub fn hash(&self) -> [u8; 32] {
|
||||
pub fn hash(&self) -> [u8; HASH_LEN] {
|
||||
crate::utils::validation::get_pallet_hash(*self)
|
||||
}
|
||||
}
|
||||
@@ -577,12 +581,12 @@ impl<'a> RuntimeApiMetadata<'a> {
|
||||
self.inner.methods.get_by_key(name)
|
||||
}
|
||||
/// Return a hash for the constant, or None if it was not found.
|
||||
pub fn method_hash(&self, method_name: &str) -> Option<[u8; 32]> {
|
||||
pub fn method_hash(&self, method_name: &str) -> Option<[u8; HASH_LEN]> {
|
||||
crate::utils::validation::get_runtime_api_hash(self, method_name)
|
||||
}
|
||||
|
||||
/// Return a hash for the runtime API trait.
|
||||
pub fn hash(&self) -> [u8; 32] {
|
||||
pub fn hash(&self) -> [u8; HASH_LEN] {
|
||||
crate::utils::validation::get_runtime_trait_hash(*self)
|
||||
}
|
||||
}
|
||||
@@ -640,36 +644,74 @@ pub struct RuntimeApiMethodParamMetadata {
|
||||
|
||||
/// Metadata of custom types with custom values, basically the same as `frame_metadata::v15::CustomMetadata<PortableForm>>`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CustomMetadata {
|
||||
map: BTreeMap<String, frame_metadata::v15::CustomValueMetadata<PortableForm>>,
|
||||
pub struct CustomMetadata<'a> {
|
||||
types: &'a PortableRegistry,
|
||||
inner: &'a frame_metadata::v15::CustomMetadata<PortableForm>,
|
||||
}
|
||||
|
||||
impl CustomMetadata {
|
||||
/// Get a certain [CustomMetadataValue] by its name.
|
||||
pub fn get(&self, name: &str) -> Option<CustomMetadataValue<'_>> {
|
||||
self.map.get(name).map(|e| CustomMetadataValue {
|
||||
impl<'a> CustomMetadata<'a> {
|
||||
/// Get a certain [CustomValueMetadata] by its name.
|
||||
pub fn get(&self, name: &str) -> Option<CustomValueMetadata<'a>> {
|
||||
self.inner
|
||||
.map
|
||||
.get_key_value(name)
|
||||
.map(|(name, e)| CustomValueMetadata {
|
||||
types: self.types,
|
||||
type_id: e.ty.id,
|
||||
data: &e.value,
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
/// Iterates over names (keys) and associated custom values
|
||||
pub fn iter(&self) -> impl Iterator<Item = CustomValueMetadata> {
|
||||
self.inner.map.iter().map(|(name, e)| CustomValueMetadata {
|
||||
types: self.types,
|
||||
type_id: e.ty.id,
|
||||
data: &e.value,
|
||||
name: name.as_ref(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Access the underlying type registry.
|
||||
pub fn types(&self) -> &PortableRegistry {
|
||||
self.types
|
||||
}
|
||||
}
|
||||
|
||||
/// Basically the same as `frame_metadata::v15::CustomValueMetadata<PortableForm>>`, but borrowed.
|
||||
pub struct CustomMetadataValue<'a> {
|
||||
pub struct CustomValueMetadata<'a> {
|
||||
types: &'a PortableRegistry,
|
||||
type_id: u32,
|
||||
data: &'a [u8],
|
||||
name: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> CustomMetadataValue<'a> {
|
||||
/// the scale encoded value
|
||||
impl<'a> CustomValueMetadata<'a> {
|
||||
/// The scale encoded value
|
||||
pub fn bytes(&self) -> &'a [u8] {
|
||||
self.data
|
||||
}
|
||||
|
||||
/// the type id in the TypeRegistry
|
||||
/// The type id in the TypeRegistry
|
||||
pub fn type_id(&self) -> u32 {
|
||||
self.type_id
|
||||
}
|
||||
|
||||
/// The name under which the custom value is registered.
|
||||
pub fn name(&self) -> &str {
|
||||
self.name
|
||||
}
|
||||
|
||||
/// Calculates the hash for the CustomValueMetadata.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `self.type_id` is not registered in the provided type registry
|
||||
pub fn hash(&self) -> [u8; HASH_LEN] {
|
||||
let mut cache = HashMap::new();
|
||||
get_custom_value_hash(self, &mut cache)
|
||||
}
|
||||
}
|
||||
|
||||
// Support decoding metadata from the "wire" format directly into this.
|
||||
|
||||
Reference in New Issue
Block a user