Files
pezkuwi-subxt/metadata/src/from/v16.rs
T
James Wilson 8203679cbd Merge v0.50.x to master (#2127)
* 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)
2025-11-22 10:44:03 +00:00

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,
}
}