mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Update to latest frame-metadata changes
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Generated
+11
-1
@@ -1830,6 +1830,16 @@ dependencies = [
|
||||
"scale-info",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "frame-metadata"
|
||||
version = "16.0.0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"parity-scale-codec",
|
||||
"scale-info",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "frame-metadata"
|
||||
version = "16.0.0"
|
||||
@@ -5103,7 +5113,7 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a616fa51350b35326682a472ee8e6ba742fdacb18babac38ecd46b3e05ead869"
|
||||
dependencies = [
|
||||
"frame-metadata 16.0.0",
|
||||
"frame-metadata 16.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-scale-codec",
|
||||
"scale-info",
|
||||
]
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ darling = "0.20.10"
|
||||
derive-where = "1.2.7"
|
||||
either = { version = "1.13.0", default-features = false }
|
||||
finito = { version = "0.1.0", default-features = false }
|
||||
frame-metadata = { version = "16.0.0", default-features = false }
|
||||
frame-metadata = { path = "/home/lexnv/workspace/frame-metadata/frame-metadata", features = ["current", "decode", "unstable"] }
|
||||
futures = { version = "0.3.30", default-features = false, features = ["std"] }
|
||||
getrandom = { version = "0.2", default-features = false }
|
||||
hashbrown = "0.14.5"
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ serde = { workspace = true, features = ["derive"] }
|
||||
color-eyre = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
hex = { workspace = true }
|
||||
frame-metadata = { workspace = true }
|
||||
frame-metadata = { workspace = true, features = ["current", "decode", "unstable"] }
|
||||
codec = { package = "parity-scale-codec", workspace = true }
|
||||
scale-info = { workspace = true }
|
||||
scale-value = { workspace = true }
|
||||
|
||||
@@ -41,6 +41,7 @@ pub struct Opts {
|
||||
}
|
||||
|
||||
pub async fn run(opts: Opts, output: &mut impl Write) -> color_eyre::Result<()> {
|
||||
println!("opts {:?}", opts);
|
||||
validate_url_security(opts.file_or_url.url.as_ref(), opts.allow_insecure)?;
|
||||
let bytes = opts.file_or_url.fetch().await?;
|
||||
let mut metadata = RuntimeMetadataPrefixed::decode(&mut &bytes[..])?;
|
||||
|
||||
+3
-1
@@ -122,7 +122,9 @@ impl FileOrUrl {
|
||||
// Default if neither is provided; fetch from local url
|
||||
(None, None, version) => {
|
||||
let url = Url::parse("ws://localhost:9944").expect("Valid URL; qed");
|
||||
Ok(fetch_metadata_from_url(url, version.unwrap_or_default()).await?)
|
||||
let version = version.unwrap_or_default();
|
||||
// println!("Fetching metadata from {url} with version {version:?}");
|
||||
Ok(fetch_metadata_from_url(url, version).await?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
use std::any::Any;
|
||||
|
||||
use super::CodegenError;
|
||||
use heck::{ToSnakeCase as _, ToUpperCamelCase as _};
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{format_ident, quote};
|
||||
use scale_typegen::typegen::ir::ToTokensWithSettings;
|
||||
use scale_typegen::{typegen::ir::type_ir::CompositeIRKind, TypeGenerator};
|
||||
use subxt_metadata::{AssociatedTypeMetadata, PalletMetadata};
|
||||
|
||||
/// The name of the system pallet.
|
||||
const PALLET_SYSTEM: &str = "System";
|
||||
/// The name of the system pallet block type.
|
||||
const PALLET_SYSTEM_BLOCK: &str = "Block";
|
||||
|
||||
fn handle_block_type(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata,
|
||||
ty: &AssociatedTypeMetadata,
|
||||
crate_path: &syn::Path,
|
||||
) -> Option<TokenStream2> {
|
||||
// Only handle the system pallet block type.
|
||||
if pallet.name() != PALLET_SYSTEM || ty.name() != PALLET_SYSTEM_BLOCK {
|
||||
return None;
|
||||
}
|
||||
|
||||
// println!("System pallet, block type: {:?}", ty);
|
||||
|
||||
let resolved_ty = type_gen.resolve_type(ty.type_id()).ok()?;
|
||||
// First generic param is the header of the chain.
|
||||
let header = resolved_ty.type_params.get(0)?;
|
||||
|
||||
// Second generic param is the unchecked extrinsics.
|
||||
let extrinsics = resolved_ty.type_params.get(1)?;
|
||||
let extrinsics_ty = type_gen.resolve_type(extrinsics.ty?.id).ok()?;
|
||||
// Which contains the Address Type as first generic parameter.
|
||||
let account_id = extrinsics_ty.type_params.get(0)?;
|
||||
let resolved_account_id = type_gen.resolve_type_path(account_id.ty?.id).ok()?;
|
||||
let resolved_account_id = resolved_account_id.to_token_stream(type_gen.settings());
|
||||
|
||||
let ty_path = type_gen.resolve_type_path(ty.type_id()).ok()?;
|
||||
let ty = ty_path.to_token_stream(type_gen.settings());
|
||||
|
||||
Some(quote! {
|
||||
pub type Address = #resolved_account_id;
|
||||
// TODO: add the header type here.
|
||||
// pub type Header = <#crate_path::system::Block as #crate_path::Block>::Header;
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate associated types.
|
||||
pub fn generate_associated_types(
|
||||
type_gen: &TypeGenerator,
|
||||
pallet: &PalletMetadata,
|
||||
crate_path: &syn::Path,
|
||||
) -> Result<TokenStream2, CodegenError> {
|
||||
let associated_types = pallet.associated_types();
|
||||
|
||||
let collected = associated_types.iter().map(|ty| {
|
||||
let name = format_ident!("{}", ty.name());
|
||||
let docs = type_gen.docs_from_scale_info(&ty.docs());
|
||||
|
||||
let Ok(ty_path) = type_gen.resolve_type_path(ty.type_id()) else {
|
||||
// We don't have the information in the type generator to handle this type.
|
||||
return quote! {};
|
||||
};
|
||||
|
||||
let maybe_block_ty = handle_block_type(type_gen, pallet, ty, crate_path);
|
||||
let name_str = ty.name();
|
||||
let ty = ty_path.to_token_stream(type_gen.settings());
|
||||
|
||||
let mut maybe_impl = 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()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
quote! {
|
||||
#docs
|
||||
pub type #name = #ty;
|
||||
|
||||
// Types extracted from the generic parameters of the system pallet block type.
|
||||
#maybe_block_ty
|
||||
|
||||
// Implementation for the hasher type.
|
||||
#maybe_impl
|
||||
}
|
||||
});
|
||||
|
||||
Ok(quote! {
|
||||
#( #collected )*
|
||||
})
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
//! Generate code for submitting extrinsics and query storage of a Substrate runtime.
|
||||
|
||||
mod associated_types;
|
||||
mod calls;
|
||||
mod constants;
|
||||
mod custom_values;
|
||||
@@ -171,10 +172,21 @@ impl RuntimeGenerator {
|
||||
|
||||
let errors = errors::generate_error_type_alias(&type_gen, pallet)?;
|
||||
|
||||
let associated_types =
|
||||
associated_types::generate_associated_types(&type_gen, pallet, &crate_path)?;
|
||||
|
||||
Ok(quote! {
|
||||
pub mod #mod_name {
|
||||
use super::root_mod;
|
||||
use super::#types_mod_ident;
|
||||
|
||||
pub mod associated_types {
|
||||
use super::root_mod;
|
||||
use super::#types_mod_ident;
|
||||
|
||||
#associated_types
|
||||
}
|
||||
|
||||
#errors
|
||||
#calls
|
||||
#event
|
||||
|
||||
@@ -143,6 +143,8 @@ async fn fetch_metadata(
|
||||
Decode::decode(&mut &raw_bytes[..])?
|
||||
};
|
||||
|
||||
// println!(" Metadata version: {supported_versions:?}");
|
||||
|
||||
// Return the version the user wants if it's supported:
|
||||
let version = match version {
|
||||
MetadataVersion::Latest => *supported_versions
|
||||
@@ -172,6 +174,8 @@ async fn fetch_metadata(
|
||||
}
|
||||
};
|
||||
|
||||
// println!(" Metadata version: {version}");
|
||||
|
||||
let bytes = version.encode();
|
||||
let version: String = format!("0x{}", hex::encode(&bytes));
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ std = ["scale-info/std", "frame-metadata/std"]
|
||||
|
||||
[dependencies]
|
||||
scale-info = { workspace = true, default-features = false }
|
||||
frame-metadata = { workspace = true, default-features = false, features = ["current", "decode"] }
|
||||
frame-metadata = { workspace = true, default-features = false, features = ["current", "decode", "unstable"] }
|
||||
codec = { package = "parity-scale-codec", workspace = true, default-features = false, features = ["derive"] }
|
||||
sp-crypto-hashing = { workspace = true }
|
||||
hashbrown = { workspace = true }
|
||||
|
||||
@@ -8,6 +8,7 @@ use alloc::string::String;
|
||||
|
||||
mod v14;
|
||||
mod v15;
|
||||
mod v16;
|
||||
|
||||
/// An error emitted if something goes wrong converting [`frame_metadata`]
|
||||
/// types into [`crate::Metadata`].
|
||||
@@ -108,6 +109,7 @@ impl TryFrom<frame_metadata::RuntimeMetadataPrefixed> for crate::Metadata {
|
||||
}
|
||||
frame_metadata::RuntimeMetadata::V14(m) => m.try_into(),
|
||||
frame_metadata::RuntimeMetadata::V15(m) => m.try_into(),
|
||||
frame_metadata::RuntimeMetadata::V16(m) => m.try_into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
extern crate alloc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use super::TryFromError;
|
||||
|
||||
use crate::utils::variant_index::VariantIndex;
|
||||
@@ -66,6 +69,7 @@ mod from_v15 {
|
||||
error_variant_index,
|
||||
constants: constants.collect(),
|
||||
docs: p.docs,
|
||||
associated_types: Vec::new(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
// Copyright 2019-2023 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::{
|
||||
utils::ordered_map::OrderedMap, ArcStr, ConstantMetadata, ExtrinsicMetadata, Metadata,
|
||||
OuterEnumsMetadata, PalletMetadataInner, RuntimeApiMetadataInner, RuntimeApiMethodMetadata,
|
||||
RuntimeApiMethodParamMetadata, SignedExtensionMetadata, StorageEntryMetadata,
|
||||
StorageEntryModifier, StorageEntryType, StorageHasher, StorageMetadata,
|
||||
};
|
||||
use alloc::borrow::ToOwned;
|
||||
use frame_metadata::v16;
|
||||
use hashbrown::HashMap;
|
||||
use scale_info::form::PortableForm;
|
||||
|
||||
// Converting from V16 metadata into our Subxt repr.
|
||||
mod from_v16 {
|
||||
use frame_metadata::v15;
|
||||
|
||||
use crate::AssociatedTypeMetadata;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl TryFrom<v16::RuntimeMetadataV16> for Metadata {
|
||||
type Error = TryFromError;
|
||||
fn try_from(m: v16::RuntimeMetadataV16) -> Result<Self, TryFromError> {
|
||||
let mut pallets = OrderedMap::new();
|
||||
let mut pallets_by_index = HashMap::new();
|
||||
for (pos, p) in m.pallets.into_iter().enumerate() {
|
||||
let name: ArcStr = p.name.into();
|
||||
|
||||
let storage = p.storage.map(|s| StorageMetadata {
|
||||
prefix: s.prefix,
|
||||
entries: s
|
||||
.entries
|
||||
.into_iter()
|
||||
.map(|s| {
|
||||
let name: ArcStr = s.name.clone().into();
|
||||
(name.clone(), from_storage_entry_metadata(name, s))
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
let constants = p.constants.into_iter().map(|c| {
|
||||
let name: ArcStr = c.name.clone().into();
|
||||
(name.clone(), from_constant_metadata(name, c))
|
||||
});
|
||||
|
||||
let call_variant_index =
|
||||
VariantIndex::build(p.calls.as_ref().map(|c| c.ty.id), &m.types);
|
||||
let error_variant_index =
|
||||
VariantIndex::build(p.error.as_ref().map(|e| e.ty.id), &m.types);
|
||||
let event_variant_index =
|
||||
VariantIndex::build(p.event.as_ref().map(|e| e.ty.id), &m.types);
|
||||
|
||||
pallets_by_index.insert(p.index, pos);
|
||||
pallets.push_insert(
|
||||
name.clone(),
|
||||
PalletMetadataInner {
|
||||
name,
|
||||
index: p.index,
|
||||
storage,
|
||||
call_ty: p.calls.map(|c| c.ty.id),
|
||||
call_variant_index,
|
||||
event_ty: p.event.map(|e| e.ty.id),
|
||||
event_variant_index,
|
||||
error_ty: p.error.map(|e| e.ty.id),
|
||||
error_variant_index,
|
||||
constants: constants.collect(),
|
||||
docs: p.docs,
|
||||
associated_types: p
|
||||
.associated_types
|
||||
.into_iter()
|
||||
.map(from_associated_type_metadata)
|
||||
.collect(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let apis = m.apis.into_iter().map(|api| {
|
||||
let name: ArcStr = api.name.clone().into();
|
||||
(name.clone(), from_runtime_api_metadata(name, api))
|
||||
});
|
||||
|
||||
let dispatch_error_ty = m
|
||||
.types
|
||||
.types
|
||||
.iter()
|
||||
.find(|ty| ty.ty.path.segments == ["sp_runtime", "DispatchError"])
|
||||
.map(|ty| ty.id);
|
||||
|
||||
Ok(Metadata {
|
||||
types: m.types,
|
||||
pallets,
|
||||
pallets_by_index,
|
||||
extrinsic: from_extrinsic_metadata(m.extrinsic),
|
||||
runtime_ty: m.ty.id,
|
||||
dispatch_error_ty,
|
||||
apis: apis.collect(),
|
||||
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: Default::default(),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn from_signed_extension_metadata(
|
||||
value: v16::SignedExtensionMetadata<PortableForm>,
|
||||
) -> SignedExtensionMetadata {
|
||||
SignedExtensionMetadata {
|
||||
identifier: value.identifier,
|
||||
extra_ty: value.ty.id,
|
||||
additional_ty: value.additional_signed.id,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_extrinsic_metadata(value: v16::ExtrinsicMetadata<PortableForm>) -> ExtrinsicMetadata {
|
||||
ExtrinsicMetadata {
|
||||
version: value.version,
|
||||
signed_extensions: value
|
||||
.signed_extensions
|
||||
.into_iter()
|
||||
.map(from_signed_extension_metadata)
|
||||
.collect(),
|
||||
address_ty: value.address_ty.id,
|
||||
call_ty: value.call_ty.id,
|
||||
signature_ty: value.signature_ty.id,
|
||||
extra_ty: value.extra_ty.id,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_hasher(value: v16::StorageHasher) -> StorageHasher {
|
||||
match value {
|
||||
v16::StorageHasher::Blake2_128 => StorageHasher::Blake2_128,
|
||||
v16::StorageHasher::Blake2_256 => StorageHasher::Blake2_256,
|
||||
v16::StorageHasher::Blake2_128Concat => StorageHasher::Blake2_128Concat,
|
||||
v16::StorageHasher::Twox128 => StorageHasher::Twox128,
|
||||
v16::StorageHasher::Twox256 => StorageHasher::Twox256,
|
||||
v16::StorageHasher::Twox64Concat => StorageHasher::Twox64Concat,
|
||||
v16::StorageHasher::Identity => StorageHasher::Identity,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_entry_type(value: v16::StorageEntryType<PortableForm>) -> StorageEntryType {
|
||||
match value {
|
||||
v16::StorageEntryType::Plain(ty) => StorageEntryType::Plain(ty.id),
|
||||
v16::StorageEntryType::Map {
|
||||
hashers,
|
||||
key,
|
||||
value,
|
||||
} => StorageEntryType::Map {
|
||||
hashers: hashers.into_iter().map(from_storage_hasher).collect(),
|
||||
key_ty: key.id,
|
||||
value_ty: value.id,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_entry_modifier(value: v16::StorageEntryModifier) -> StorageEntryModifier {
|
||||
match value {
|
||||
v16::StorageEntryModifier::Optional => StorageEntryModifier::Optional,
|
||||
v16::StorageEntryModifier::Default => StorageEntryModifier::Default,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_associated_type_metadata(
|
||||
value: v16::PalletAssociatedTypeMetadata<PortableForm>,
|
||||
) -> AssociatedTypeMetadata {
|
||||
AssociatedTypeMetadata {
|
||||
name: value.name,
|
||||
ty: value.ty.id,
|
||||
docs: value.docs,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_entry_metadata(
|
||||
name: ArcStr,
|
||||
s: v16::StorageEntryMetadata<PortableForm>,
|
||||
) -> StorageEntryMetadata {
|
||||
StorageEntryMetadata {
|
||||
name,
|
||||
modifier: from_storage_entry_modifier(s.modifier),
|
||||
entry_type: from_storage_entry_type(s.ty),
|
||||
default: s.default,
|
||||
docs: s.docs,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_constant_metadata(
|
||||
name: ArcStr,
|
||||
s: v16::PalletConstantMetadata<PortableForm>,
|
||||
) -> ConstantMetadata {
|
||||
ConstantMetadata {
|
||||
name,
|
||||
ty: s.ty.id,
|
||||
value: s.value,
|
||||
docs: s.docs,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_runtime_api_metadata(
|
||||
name: ArcStr,
|
||||
s: v16::RuntimeApiMetadata<PortableForm>,
|
||||
) -> RuntimeApiMetadataInner {
|
||||
RuntimeApiMetadataInner {
|
||||
name,
|
||||
docs: s.docs,
|
||||
methods: s
|
||||
.methods
|
||||
.into_iter()
|
||||
.map(|m| {
|
||||
let name: ArcStr = m.name.clone().into();
|
||||
(name.clone(), from_runtime_api_method_metadata(name, m))
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_runtime_api_method_metadata(
|
||||
name: ArcStr,
|
||||
s: v16::RuntimeApiMethodMetadata<PortableForm>,
|
||||
) -> RuntimeApiMethodMetadata {
|
||||
RuntimeApiMethodMetadata {
|
||||
name,
|
||||
inputs: s
|
||||
.inputs
|
||||
.into_iter()
|
||||
.map(from_runtime_api_method_param_metadata)
|
||||
.collect(),
|
||||
output_ty: s.output.id,
|
||||
docs: s.docs,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_runtime_api_method_param_metadata(
|
||||
s: v16::RuntimeApiMethodParamMetadata<PortableForm>,
|
||||
) -> RuntimeApiMethodParamMetadata {
|
||||
RuntimeApiMethodParamMetadata {
|
||||
name: s.name,
|
||||
ty: s.ty.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Converting from our metadata repr to v16 metadata.
|
||||
mod into_v16 {
|
||||
use crate::AssociatedTypeMetadata;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl From<Metadata> for v16::RuntimeMetadataV16 {
|
||||
fn from(m: Metadata) -> Self {
|
||||
let pallets = m.pallets.into_values().into_iter().map(|p| {
|
||||
let storage = p.storage.map(|s| v16::PalletStorageMetadata {
|
||||
prefix: s.prefix,
|
||||
entries: s
|
||||
.entries
|
||||
.into_values()
|
||||
.into_iter()
|
||||
.map(from_storage_entry_metadata)
|
||||
.collect(),
|
||||
});
|
||||
|
||||
v16::PalletMetadata {
|
||||
name: (*p.name).to_owned(),
|
||||
calls: p.call_ty.map(|id| v16::PalletCallMetadata {
|
||||
ty: id.into(),
|
||||
deprecation_info: v16::DeprecationInfo::NotDeprecated,
|
||||
}),
|
||||
event: p.event_ty.map(|id| v16::PalletEventMetadata {
|
||||
ty: id.into(),
|
||||
deprecation_info: v16::DeprecationInfo::NotDeprecated,
|
||||
}),
|
||||
error: p.error_ty.map(|id| v16::PalletErrorMetadata {
|
||||
ty: id.into(),
|
||||
deprecation_info: v16::DeprecationInfo::NotDeprecated,
|
||||
}),
|
||||
storage,
|
||||
constants: p
|
||||
.constants
|
||||
.into_values()
|
||||
.into_iter()
|
||||
.map(from_constant_metadata)
|
||||
.collect(),
|
||||
index: p.index,
|
||||
docs: p.docs,
|
||||
associated_types: p
|
||||
.associated_types
|
||||
.into_iter()
|
||||
.map(from_associated_type_metadata)
|
||||
.collect(),
|
||||
deprecation_info: v16::DeprecationStatus::NotDeprecated,
|
||||
}
|
||||
});
|
||||
|
||||
v16::RuntimeMetadataV16 {
|
||||
types: m.types,
|
||||
pallets: pallets.collect(),
|
||||
ty: m.runtime_ty.into(),
|
||||
extrinsic: from_extrinsic_metadata(m.extrinsic),
|
||||
apis: m
|
||||
.apis
|
||||
.into_values()
|
||||
.into_iter()
|
||||
.map(from_runtime_api_metadata)
|
||||
.collect(),
|
||||
outer_enums: v16::OuterEnums {
|
||||
call_enum_ty: m.outer_enums.call_enum_ty.into(),
|
||||
event_enum_ty: m.outer_enums.event_enum_ty.into(),
|
||||
error_enum_ty: m.outer_enums.error_enum_ty.into(),
|
||||
},
|
||||
custom: v16::CustomMetadata {
|
||||
map: Default::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_associated_type_metadata(
|
||||
a: AssociatedTypeMetadata,
|
||||
) -> v16::PalletAssociatedTypeMetadata<PortableForm> {
|
||||
v16::PalletAssociatedTypeMetadata {
|
||||
name: a.name,
|
||||
ty: a.ty.into(),
|
||||
docs: a.docs,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_runtime_api_metadata(
|
||||
r: RuntimeApiMetadataInner,
|
||||
) -> v16::RuntimeApiMetadata<PortableForm> {
|
||||
v16::RuntimeApiMetadata {
|
||||
name: (*r.name).to_owned(),
|
||||
methods: r
|
||||
.methods
|
||||
.into_values()
|
||||
.into_iter()
|
||||
.map(from_runtime_api_method_metadata)
|
||||
.collect(),
|
||||
docs: r.docs,
|
||||
deprecation_info: v16::DeprecationStatus::NotDeprecated,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_runtime_api_method_metadata(
|
||||
m: RuntimeApiMethodMetadata,
|
||||
) -> v16::RuntimeApiMethodMetadata<PortableForm> {
|
||||
v16::RuntimeApiMethodMetadata {
|
||||
name: (*m.name).to_owned(),
|
||||
inputs: m
|
||||
.inputs
|
||||
.into_iter()
|
||||
.map(from_runtime_api_method_param_metadata)
|
||||
.collect(),
|
||||
output: m.output_ty.into(),
|
||||
docs: m.docs,
|
||||
deprecation_info: v16::DeprecationStatus::NotDeprecated,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_runtime_api_method_param_metadata(
|
||||
p: RuntimeApiMethodParamMetadata,
|
||||
) -> v16::RuntimeApiMethodParamMetadata<PortableForm> {
|
||||
v16::RuntimeApiMethodParamMetadata {
|
||||
name: p.name,
|
||||
ty: p.ty.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_extrinsic_metadata(e: ExtrinsicMetadata) -> v16::ExtrinsicMetadata<PortableForm> {
|
||||
v16::ExtrinsicMetadata {
|
||||
version: e.version,
|
||||
signed_extensions: e
|
||||
.signed_extensions
|
||||
.into_iter()
|
||||
.map(from_signed_extension_metadata)
|
||||
.collect(),
|
||||
address_ty: e.address_ty.into(),
|
||||
call_ty: e.call_ty.into(),
|
||||
signature_ty: e.signature_ty.into(),
|
||||
extra_ty: e.extra_ty.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_signed_extension_metadata(
|
||||
s: SignedExtensionMetadata,
|
||||
) -> v16::SignedExtensionMetadata<PortableForm> {
|
||||
v16::SignedExtensionMetadata {
|
||||
identifier: s.identifier,
|
||||
ty: s.extra_ty.into(),
|
||||
additional_signed: s.additional_ty.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_constant_metadata(c: ConstantMetadata) -> v16::PalletConstantMetadata<PortableForm> {
|
||||
v16::PalletConstantMetadata {
|
||||
name: (*c.name).to_owned(),
|
||||
ty: c.ty.into(),
|
||||
value: c.value,
|
||||
docs: c.docs,
|
||||
deprecation_info: v16::DeprecationStatus::NotDeprecated,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_entry_metadata(
|
||||
s: StorageEntryMetadata,
|
||||
) -> v16::StorageEntryMetadata<PortableForm> {
|
||||
v16::StorageEntryMetadata {
|
||||
docs: s.docs,
|
||||
default: s.default,
|
||||
name: (*s.name).to_owned(),
|
||||
ty: from_storage_entry_type(s.entry_type),
|
||||
modifier: from_storage_entry_modifier(s.modifier),
|
||||
deprecation_info: v16::DeprecationStatus::NotDeprecated,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_entry_modifier(s: StorageEntryModifier) -> v16::StorageEntryModifier {
|
||||
match s {
|
||||
StorageEntryModifier::Default => v16::StorageEntryModifier::Default,
|
||||
StorageEntryModifier::Optional => v16::StorageEntryModifier::Optional,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_entry_type(s: StorageEntryType) -> v16::StorageEntryType<PortableForm> {
|
||||
match s {
|
||||
StorageEntryType::Plain(ty) => v16::StorageEntryType::Plain(ty.into()),
|
||||
StorageEntryType::Map {
|
||||
hashers,
|
||||
key_ty,
|
||||
value_ty,
|
||||
} => v16::StorageEntryType::Map {
|
||||
hashers: hashers.into_iter().map(from_storage_hasher).collect(),
|
||||
key: key_ty.into(),
|
||||
value: value_ty.into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn from_storage_hasher(s: StorageHasher) -> v16::StorageHasher {
|
||||
match s {
|
||||
StorageHasher::Blake2_128 => v16::StorageHasher::Blake2_128,
|
||||
StorageHasher::Blake2_256 => v16::StorageHasher::Blake2_256,
|
||||
StorageHasher::Blake2_128Concat => v16::StorageHasher::Blake2_128Concat,
|
||||
StorageHasher::Twox128 => v16::StorageHasher::Twox128,
|
||||
StorageHasher::Twox256 => v16::StorageHasher::Twox256,
|
||||
StorageHasher::Twox64Concat => v16::StorageHasher::Twox64Concat,
|
||||
StorageHasher::Identity => v16::StorageHasher::Identity,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,6 +230,11 @@ impl<'a> PalletMetadata<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Return all of the associated types.
|
||||
pub fn associated_types(&self) -> &'a [AssociatedTypeMetadata] {
|
||||
&self.inner.associated_types
|
||||
}
|
||||
|
||||
/// Return all of the call variants, if a call type exists.
|
||||
pub fn call_variants(&self) -> Option<&'a [Variant<PortableForm>]> {
|
||||
VariantIndex::get(self.inner.call_ty, self.types)
|
||||
@@ -318,6 +323,36 @@ struct PalletMetadataInner {
|
||||
constants: OrderedMap<ArcStr, ConstantMetadata>,
|
||||
/// Pallet documentation.
|
||||
docs: Vec<String>,
|
||||
/// Pallet associated types.
|
||||
associated_types: Vec<AssociatedTypeMetadata>,
|
||||
}
|
||||
|
||||
/// Metadata for an associated type.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AssociatedTypeMetadata {
|
||||
/// Name of the associated type.
|
||||
name: String,
|
||||
/// Type of the associated type.
|
||||
ty: u32,
|
||||
/// Associated type documentation.
|
||||
docs: Vec<String>,
|
||||
}
|
||||
|
||||
impl AssociatedTypeMetadata {
|
||||
/// Name of the associated type.
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
/// Type id of the associated type.
|
||||
pub fn type_id(&self) -> u32 {
|
||||
self.ty
|
||||
}
|
||||
|
||||
/// Associated type documentation.
|
||||
pub fn docs(&self) -> &[String] {
|
||||
&self.docs
|
||||
}
|
||||
}
|
||||
|
||||
/// Metadata for the storage entries in a pallet.
|
||||
@@ -773,6 +808,7 @@ impl codec::Decode for Metadata {
|
||||
let metadata = match metadata.1 {
|
||||
frame_metadata::RuntimeMetadata::V14(md) => md.try_into(),
|
||||
frame_metadata::RuntimeMetadata::V15(md) => md.try_into(),
|
||||
frame_metadata::RuntimeMetadata::V16(md) => md.try_into(),
|
||||
_ => return Err("Cannot try_into() to Metadata: unsupported metadata version".into()),
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ use subxt_core::config::{Config, DefaultExtrinsicParams};
|
||||
use subxt_signer::sr25519::dev;
|
||||
|
||||
// Generate an interface that we can use from the node's metadata.
|
||||
#[subxt::subxt(runtime_metadata_insecure_url = "ws://localhost:9999")]
|
||||
#[subxt::subxt(
|
||||
runtime_metadata_insecure_url = "ws://localhost:9944",
|
||||
unstable_metadata
|
||||
)]
|
||||
pub mod polkadot {}
|
||||
|
||||
// Derives aren't strictly needed, they just make developer life easier.
|
||||
@@ -14,10 +17,10 @@ pub enum MetadataConfig {}
|
||||
|
||||
impl Config for MetadataConfig {
|
||||
// Extracted from metadata directly:
|
||||
type Hash = polkadot::custom_types::Hash;
|
||||
type AccountId = polkadot::custom_types::AccountId;
|
||||
type AssetId = polkadot::custom_types::AssetId;
|
||||
type Address = polkadot::custom_types::Address;
|
||||
type Hash = polkadot::system::associated_types::Hash;
|
||||
type AccountId = polkadot::system::associated_types::AccountId;
|
||||
type AssetId = polkadot::assets::associated_types::AssetId;
|
||||
type Address = polkadot::system::associated_types::Address;
|
||||
|
||||
// Present in metadata but this PoC needs to add
|
||||
// fn specific per name of type to impl the hashing fn.
|
||||
@@ -25,7 +28,7 @@ impl Config for MetadataConfig {
|
||||
//
|
||||
// TODO: Eventually extend this to a DynamicHasher object instead.
|
||||
// Similar logic already exists for StorageHasher.
|
||||
type Hasher = polkadot::custom_types::Hashing;
|
||||
type Hasher = polkadot::system::associated_types::Hashing;
|
||||
|
||||
// Present in metadata but this PoC needs to impl the header
|
||||
// trait to make use of this.
|
||||
@@ -37,13 +40,11 @@ impl Config for MetadataConfig {
|
||||
// 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>;
|
||||
type Header = SubstrateHeader<u32, polkadot::system::associated_types::Hashing>;
|
||||
|
||||
// Same story, present in md but needs subxt::tx::Signer<T>.
|
||||
// type Signature = polkadot::custom_types::Signature;
|
||||
type Signature = <SubstrateConfig as Config>::Signature;
|
||||
|
||||
// Not exposed in metadata, seems like heavily involved with
|
||||
// code functionality which cannot safely be expressed in the
|
||||
// metadata.
|
||||
@@ -53,7 +54,7 @@ impl Config for MetadataConfig {
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Create a new API client, configured to talk to nodes.
|
||||
let api = OnlineClient::<MetadataConfig>::from_insecure_url("ws://localhost:9999").await?;
|
||||
let api = OnlineClient::<MetadataConfig>::from_insecure_url("ws://localhost:9944").await?;
|
||||
|
||||
// Build a balance transfer extrinsic.
|
||||
let dest = dev::bob().public_key().into();
|
||||
|
||||
Reference in New Issue
Block a user