mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 21:01:05 +00:00
8203679cbd
* v0.50.0: Integrate frame-decode, redo storage APIs and break up Error. (#2100) * WIP integrating new frame-decode and working out new storage APIS * WIP: first pass adding new storage things to subxt-core * Second pass over Address type and start impl in Subxt * WIP new storage APIs * WIP New storage APIs roughly completed, lots of errors still * Remove PlainorMap enum; plain and map values now use same struct to simplify usage * Begin 'fixing' errors * WIP splitting errors and tidying payload/address traits * Get subxt-core compiling * Small fixes in subxt-core and remove metadata mod * subxt-core: cargo check --all-targets passes * Fix test * WIP starting to update subxt from subxt-core changes * WIP splitting up subxt errors into smaller variants * WIP errors: add DispatchError errors * Port new Storage APIs to subxt-core * cargo check -p subxt passes * Quick-fix errors in subxt-cli (explore subcommand) * fmt * Finish fixing codegen up and start fixing examples * get Subxt examples compiling and bytes_at for constants * Add some arcs to limit lifetimes in subxt/subxt-core storage APIs * A little Arcing to allow more method chaining in Storage APIs, aligning with Subxt * Update codegen test * cargo check --all-targets passing * cargo check --features 'unstable-light-client' passing * clippy * Remove unused dep in subxt * use published frame-decode * fix wasm-example * Add new tx extension to fix daily tests * Remove unused subxt_core::dynamic::DecodedValue type * Update book to match changes * Update docs to fix more broken bits * Add missing docs * fmt * allow larger result errs for now * Add missing alloc imports in subxt-core * Fix doc tests and fix bug getting constant info * Fix V14 -> Metadata transform for storage & constants * Fix parachain example * Fix FFI example * BlockLength decodes t ostruct, not u128 * use fetch/iter shorthands rather than entry in most storage tests * Fix some integration tests * Fix Runtime codegen tests * Expose the dynamic custom_value selecter and use in a UI test * Update codegen metadata * Tidy CLI storage query and support (str,str) as a storage address * Add (str,str) as valid constant address too * Show string tuple in constants example * Via the magic of traits, avoid needing any clones of queries/addresses and accept references to them * clippy * [v0.50] update scale-info-legacy and frame-decode to latest (#2119) * bump scale-info-legacy and frame-decode to latest * Remove something we don't need in this PR * Fully remove unused for now dep * [v0.50] Convert historic metadata to subxt::Metadata (#2120) * First pass converting historic metadatas to our subxt::Metadata type * use published frame-decode * fmt and rename legacy metadata macro * Enable legacy feature where needed in subxt_metadata so it compiles on its own * Use cargo hack more in CI and fix subxt-metadata features * Add tests for metadata conversion (need to optimise; some too expensive right now * Address performance and equality issues in metadata conversion testing * fmt * fmt all * clippy * Fix a doc link * Test codegen and fixes to make it work * Remove local frame-decode patch * bump frame-decode to latest * [v0.50.0] Allow visiting extrinsic fields in subxt_historic (#2124) * Allow visiting extrinsic fields * fmt * Don't use local scale-decode dep * Clippy and tidy * Extend 'subxt codegen' CLI to work with legacy metadatas * Simplify historic extrinsics example now that AccountId32s have paths/names * clippy * clippy * clippy.. * Allow visiting storage values, too, and clean up extrinsic visiting a little by narrowing lifetime * Try to fix flaky test * Add custom value decode to extrinsics example * Remove useless else branch ra thought I needed * Simplify examples * Prep to release v0.0.5 (#2126)
214 lines
7.8 KiB
Rust
214 lines
7.8 KiB
Rust
// Copyright 2019-2025 Parity Technologies (UK) Ltd.
|
|
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
|
// see LICENSE for license details.
|
|
|
|
use super::TryFromError;
|
|
|
|
use crate::utils::variant_index::VariantIndex;
|
|
use crate::{
|
|
ConstantMetadata, ExtrinsicMetadata, Metadata, OuterEnumsMetadata, PalletMetadataInner,
|
|
RuntimeApiMetadataInner, RuntimeApiMethodMetadataInner, StorageEntryMetadata, StorageMetadata,
|
|
TransactionExtensionMetadataInner, ViewFunctionMetadataInner, utils::ordered_map::OrderedMap,
|
|
};
|
|
use frame_decode::runtime_apis::RuntimeApiTypeInfo;
|
|
use frame_decode::storage::StorageTypeInfo;
|
|
use frame_decode::view_functions::ViewFunctionTypeInfo;
|
|
use frame_metadata::{v15, v16};
|
|
use hashbrown::HashMap;
|
|
use scale_info::form::PortableForm;
|
|
|
|
impl TryFrom<v16::RuntimeMetadataV16> for Metadata {
|
|
type Error = TryFromError;
|
|
fn try_from(m: v16::RuntimeMetadataV16) -> Result<Self, TryFromError> {
|
|
let types = &m.types;
|
|
|
|
let mut pallets = OrderedMap::new();
|
|
let mut pallets_by_index = HashMap::new();
|
|
for (pos, p) in m.pallets.iter().enumerate() {
|
|
let name = p.name.clone();
|
|
|
|
let storage = match &p.storage {
|
|
None => None,
|
|
Some(s) => Some(StorageMetadata {
|
|
prefix: s.prefix.clone(),
|
|
entries: s
|
|
.entries
|
|
.iter()
|
|
.map(|s| {
|
|
let entry_name = s.name.clone();
|
|
let storage_info = m
|
|
.storage_info(&name, &entry_name)
|
|
.map_err(|e| e.into_owned())?
|
|
.into_owned();
|
|
let storage_entry = StorageEntryMetadata {
|
|
name: entry_name.clone(),
|
|
info: storage_info,
|
|
docs: s.docs.clone(),
|
|
};
|
|
|
|
Ok::<_, TryFromError>((entry_name, storage_entry))
|
|
})
|
|
.collect::<Result<_, TryFromError>>()?,
|
|
}),
|
|
};
|
|
|
|
let view_functions = p
|
|
.view_functions
|
|
.iter()
|
|
.map(|vf| {
|
|
let view_function_metadata = ViewFunctionMetadataInner {
|
|
name: vf.name.clone(),
|
|
info: m
|
|
.view_function_info(&name, &vf.name)
|
|
.map_err(|e| e.into_owned())?
|
|
.into_owned(),
|
|
docs: vf.docs.clone(),
|
|
};
|
|
Ok((vf.name.clone(), view_function_metadata))
|
|
})
|
|
.collect::<Result<_, TryFromError>>()?;
|
|
|
|
let constants = p.constants.iter().map(|c| {
|
|
let name = c.name.clone();
|
|
(name, from_constant_metadata(c.clone()))
|
|
});
|
|
|
|
let call_variant_index = VariantIndex::build(p.calls.as_ref().map(|c| c.ty.id), types);
|
|
let error_variant_index = VariantIndex::build(p.error.as_ref().map(|e| e.ty.id), types);
|
|
let event_variant_index = VariantIndex::build(p.event.as_ref().map(|e| e.ty.id), types);
|
|
|
|
let associated_types = p
|
|
.associated_types
|
|
.iter()
|
|
.map(|t| (t.name.clone(), t.ty.id))
|
|
.collect();
|
|
|
|
pallets_by_index.insert(p.index, pos);
|
|
pallets.push_insert(
|
|
name.clone(),
|
|
PalletMetadataInner {
|
|
name,
|
|
call_index: p.index,
|
|
event_index: p.index,
|
|
error_index: p.index,
|
|
storage,
|
|
call_ty: p.calls.as_ref().map(|c| c.ty.id),
|
|
call_variant_index,
|
|
event_ty: p.event.as_ref().map(|e| e.ty.id),
|
|
event_variant_index,
|
|
error_ty: p.error.as_ref().map(|e| e.ty.id),
|
|
error_variant_index,
|
|
constants: constants.collect(),
|
|
view_functions,
|
|
associated_types,
|
|
docs: p.docs.clone(),
|
|
},
|
|
);
|
|
}
|
|
|
|
let apis = m
|
|
.apis
|
|
.iter()
|
|
.map(|api| {
|
|
let trait_name = api.name.clone();
|
|
let methods = api
|
|
.methods
|
|
.iter()
|
|
.map(|method| {
|
|
let method_name = method.name.clone();
|
|
let method_info = RuntimeApiMethodMetadataInner {
|
|
info: m
|
|
.runtime_api_info(&trait_name, &method.name)
|
|
.map_err(|e| e.into_owned())?
|
|
.into_owned(),
|
|
name: method.name.clone(),
|
|
docs: method.docs.clone(),
|
|
};
|
|
Ok((method_name, method_info))
|
|
})
|
|
.collect::<Result<_, TryFromError>>()?;
|
|
|
|
let runtime_api_metadata = RuntimeApiMetadataInner {
|
|
name: trait_name.clone(),
|
|
methods,
|
|
docs: api.docs.clone(),
|
|
};
|
|
Ok((trait_name, runtime_api_metadata))
|
|
})
|
|
.collect::<Result<_, TryFromError>>()?;
|
|
|
|
let custom_map = m
|
|
.custom
|
|
.map
|
|
.into_iter()
|
|
.map(|(key, val)| {
|
|
let custom_val = v15::CustomValueMetadata {
|
|
ty: val.ty,
|
|
value: val.value,
|
|
};
|
|
(key, custom_val)
|
|
})
|
|
.collect();
|
|
|
|
let dispatch_error_ty = types
|
|
.types
|
|
.iter()
|
|
.find(|ty| ty.ty.path.segments == ["sp_runtime", "DispatchError"])
|
|
.map(|ty| ty.id);
|
|
|
|
Ok(Metadata {
|
|
types: m.types,
|
|
pallets,
|
|
pallets_by_call_index: pallets_by_index.clone(),
|
|
pallets_by_error_index: pallets_by_index.clone(),
|
|
pallets_by_event_index: pallets_by_index,
|
|
extrinsic: from_extrinsic_metadata(m.extrinsic),
|
|
dispatch_error_ty,
|
|
apis,
|
|
outer_enums: OuterEnumsMetadata {
|
|
call_enum_ty: m.outer_enums.call_enum_ty.id,
|
|
event_enum_ty: m.outer_enums.event_enum_ty.id,
|
|
error_enum_ty: m.outer_enums.error_enum_ty.id,
|
|
},
|
|
custom: v15::CustomMetadata { map: custom_map },
|
|
})
|
|
}
|
|
}
|
|
|
|
fn from_transaction_extension_metadata(
|
|
value: v16::TransactionExtensionMetadata<PortableForm>,
|
|
) -> TransactionExtensionMetadataInner {
|
|
TransactionExtensionMetadataInner {
|
|
identifier: value.identifier,
|
|
extra_ty: value.ty.id,
|
|
additional_ty: value.implicit.id,
|
|
}
|
|
}
|
|
|
|
fn from_extrinsic_metadata(value: v16::ExtrinsicMetadata<PortableForm>) -> ExtrinsicMetadata {
|
|
ExtrinsicMetadata {
|
|
supported_versions: value.versions,
|
|
transaction_extensions_by_version: value
|
|
.transaction_extensions_by_version
|
|
.into_iter()
|
|
.map(|(version, idxs)| (version, idxs.into_iter().map(|idx| idx.0).collect()))
|
|
.collect(),
|
|
transaction_extensions: value
|
|
.transaction_extensions
|
|
.into_iter()
|
|
.map(from_transaction_extension_metadata)
|
|
.collect(),
|
|
address_ty: value.address_ty.id,
|
|
signature_ty: value.signature_ty.id,
|
|
}
|
|
}
|
|
|
|
fn from_constant_metadata(s: v16::PalletConstantMetadata<PortableForm>) -> ConstantMetadata {
|
|
ConstantMetadata {
|
|
name: s.name,
|
|
ty: s.ty.id,
|
|
value: s.value,
|
|
docs: s.docs,
|
|
}
|
|
}
|