mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 18:11:10 +00:00
432e856c37
* Update frame-metadata to v15.1.0 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Enable V15 unstable metadata in frame-metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata: Move validation hashing to dedicated file Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Use sp-metadata-ir from substrate to work with metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Revert using sp-metadata-ir in favor of conversion to v15 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata: Convert v14 to v15 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata: Use v15 for validation Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Use v15 for codegen Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata/bench: Use v15 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust to v15 metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust testing Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Improve documentation Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * force CI Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * rpc: Fetch metadata at version Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * artifacts: Update polkadot.scale from commit 6dc9e84dde2 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Fetch V15 using the new API Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Add runtime API interface Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata: Hash runtime API metadata for validation Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata: Extract runtime API metadata wrapper from subxt::Metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * subxt: Adjust hashing cache to reflect root+item keys Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * rpc: Add raw state_call API method Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * runtime_api: Add payload with static and dynamic variants Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * subxt: Allow payloads to call into the runtime Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * examples: Add example to make a runtime API call both static and dynamic Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update polkadot.rs Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Simplify client fetching Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Address feedback and fallback to old API if needed Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * runtime_api: Make mutability conditional on input params Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Regenerate polkadot.rs Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata: Retain only pallets without runtime API info Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Retry via `Metadata_metadata` without conversion Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * payload: Remove `Decode` and change validation fn Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata: Retain runtime API types Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Runtime APIs documentation based on flag Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update examples/examples/custom_metadata_url.rs Co-authored-by: James Wilson <james@jsdw.me> * Update artifacts from polkadot-a6cfdb16e9 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update polkadot.rs with polkadot-a6cfdb16e9 Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Generate input structures for runtime API Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * runtime_api: Remove the static paylaod and use single impl Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * examples: Fetch account nonce Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * testing: Adjust build script to fetch latest metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * testing: Check account nonce from runtime API Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update cargo.lock Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Fix doc generation for runtime types Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Rename `inputs` runtime calls module to `types` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Generate Calls structs inside the types module Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * testing: Check Alice account nonce before submitting the tx Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * cli: Add metadata version option flag supporting v14 and unstable Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * cli: Specify version to fetch Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * subxt: Fallback to fetching latest stable metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * subxt: Add unstable-metadata feature to fetch the latest Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * RuntimeVersion with Latest and Version(u32) Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update polkadot.rs Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Adjust fetch_metadata to inspect version list Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * testing: Adjust metadata to metadata_legacy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * events: Adjust docs to use metadata_legacy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * have a pass over fetch_metadata * cargo fmt * Option<String> when fetch metadata via latest API * clippy * fmt * cli: Use the MetadataVersion from codegen Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * cli: Specify latest as default for MetadataVersion Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * cli: Remove version from metadata and use the one from file_or_url Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Fix clippy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * codegen: Decode metadata independently for different RPC calls Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: James Wilson <james@jsdw.me>
145 lines
4.6 KiB
Rust
145 lines
4.6 KiB
Rust
// 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 clap::Parser as ClapParser;
|
|
use codec::Decode;
|
|
use color_eyre::eyre::{self, WrapErr};
|
|
use frame_metadata::{
|
|
v15::RuntimeMetadataV15, RuntimeMetadata, RuntimeMetadataPrefixed, META_RESERVED,
|
|
};
|
|
use jsonrpsee::client_transport::ws::Uri;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::HashMap;
|
|
use subxt_codegen::utils::MetadataVersion;
|
|
use subxt_metadata::{get_metadata_hash, get_pallet_hash, metadata_v14_to_latest};
|
|
|
|
/// Verify metadata compatibility between substrate nodes.
|
|
#[derive(Debug, ClapParser)]
|
|
pub struct Opts {
|
|
/// Urls of the substrate nodes to verify for metadata compatibility.
|
|
#[clap(name = "nodes", long, use_value_delimiter = true, value_parser)]
|
|
nodes: Vec<Uri>,
|
|
/// Check the compatibility of metadata for a particular pallet.
|
|
///
|
|
/// ### Note
|
|
/// The validation will omit the full metadata check and focus instead on the pallet.
|
|
#[clap(long, value_parser)]
|
|
pallet: Option<String>,
|
|
/// Specify the metadata version.
|
|
///
|
|
/// - unstable:
|
|
///
|
|
/// Use the latest unstable metadata of the node.
|
|
///
|
|
/// - number
|
|
///
|
|
/// Use this specific metadata version.
|
|
///
|
|
/// Defaults to latest.
|
|
#[clap(long = "version", default_value = "latest")]
|
|
version: MetadataVersion,
|
|
}
|
|
|
|
pub async fn run(opts: Opts) -> color_eyre::Result<()> {
|
|
match opts.pallet {
|
|
Some(pallet) => {
|
|
handle_pallet_metadata(opts.nodes.as_slice(), pallet.as_str(), opts.version).await
|
|
}
|
|
None => handle_full_metadata(opts.nodes.as_slice(), opts.version).await,
|
|
}
|
|
}
|
|
|
|
async fn handle_pallet_metadata(
|
|
nodes: &[Uri],
|
|
name: &str,
|
|
version: MetadataVersion,
|
|
) -> color_eyre::Result<()> {
|
|
#[derive(Serialize, Deserialize, Default)]
|
|
#[serde(rename_all = "camelCase")]
|
|
struct CompatibilityPallet {
|
|
pallet_present: HashMap<String, Vec<String>>,
|
|
pallet_not_found: Vec<String>,
|
|
}
|
|
|
|
let mut compatibility: CompatibilityPallet = Default::default();
|
|
for node in nodes.iter() {
|
|
let metadata = fetch_runtime_metadata(node, version).await?;
|
|
|
|
match metadata.pallets.iter().find(|pallet| pallet.name == name) {
|
|
Some(pallet_metadata) => {
|
|
let hash = get_pallet_hash(&metadata.types, pallet_metadata);
|
|
let hex_hash = hex::encode(hash);
|
|
println!("Node {node:?} has pallet metadata hash {hex_hash:?}");
|
|
|
|
compatibility
|
|
.pallet_present
|
|
.entry(hex_hash)
|
|
.or_insert_with(Vec::new)
|
|
.push(node.to_string());
|
|
}
|
|
None => {
|
|
compatibility.pallet_not_found.push(node.to_string());
|
|
}
|
|
}
|
|
}
|
|
|
|
println!(
|
|
"\nCompatible nodes by pallet\n{}",
|
|
serde_json::to_string_pretty(&compatibility)
|
|
.context("Failed to parse compatibility map")?
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn handle_full_metadata(nodes: &[Uri], version: MetadataVersion) -> color_eyre::Result<()> {
|
|
let mut compatibility_map: HashMap<String, Vec<String>> = HashMap::new();
|
|
for node in nodes.iter() {
|
|
let metadata = fetch_runtime_metadata(node, version).await?;
|
|
let hash = get_metadata_hash(&metadata);
|
|
let hex_hash = hex::encode(hash);
|
|
println!("Node {node:?} has metadata hash {hex_hash:?}",);
|
|
|
|
compatibility_map
|
|
.entry(hex_hash)
|
|
.or_insert_with(Vec::new)
|
|
.push(node.to_string());
|
|
}
|
|
|
|
println!(
|
|
"\nCompatible nodes\n{}",
|
|
serde_json::to_string_pretty(&compatibility_map)
|
|
.context("Failed to parse compatibility map")?
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn fetch_runtime_metadata(
|
|
url: &Uri,
|
|
version: MetadataVersion,
|
|
) -> color_eyre::Result<RuntimeMetadataV15> {
|
|
let bytes = subxt_codegen::utils::fetch_metadata_bytes(url, version).await?;
|
|
|
|
let metadata = <RuntimeMetadataPrefixed as Decode>::decode(&mut &bytes[..])?;
|
|
if metadata.0 != META_RESERVED {
|
|
return Err(eyre::eyre!(
|
|
"Node {:?} has invalid metadata prefix: {:?} expected prefix: {:?}",
|
|
url,
|
|
metadata.0,
|
|
META_RESERVED
|
|
));
|
|
}
|
|
|
|
match metadata.1 {
|
|
RuntimeMetadata::V14(v14) => Ok(metadata_v14_to_latest(v14)),
|
|
RuntimeMetadata::V15(v15) => Ok(v15),
|
|
_ => Err(eyre::eyre!(
|
|
"Node {:?} with unsupported metadata version: {:?}",
|
|
url,
|
|
metadata.1
|
|
)),
|
|
}
|
|
}
|