mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 08:51:04 +00:00
Initial rebrand from paritytech/subxt to pezkuwichain/pezkuwi-subxt
- Renamed all subxt crates to pezkuwi-subxt - Updated internal references - Configured for Pezkuwi ecosystem
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
// 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 clap::Parser as ClapParser;
|
||||
use codec::Decode;
|
||||
use color_eyre::eyre::WrapErr;
|
||||
use jsonrpsee::client_transport::ws::Url;
|
||||
use pezkuwi_subxt_metadata::Metadata;
|
||||
use pezkuwi_subxt_utils_fetchmetadata::MetadataVersion;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::utils::validate_url_security;
|
||||
|
||||
/// 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<Url>,
|
||||
/// 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,
|
||||
/// Allow insecure URLs e.g. URLs starting with ws:// or http:// without SSL encryption
|
||||
#[clap(long, short)]
|
||||
allow_insecure: bool,
|
||||
}
|
||||
|
||||
pub async fn run(opts: Opts, output: &mut impl std::io::Write) -> color_eyre::Result<()> {
|
||||
for url in opts.nodes.iter() {
|
||||
validate_url_security(Some(url), opts.allow_insecure)?;
|
||||
}
|
||||
|
||||
match opts.pallet {
|
||||
Some(pallet) =>
|
||||
handle_pallet_metadata(opts.nodes.as_slice(), pallet.as_str(), opts.version, output)
|
||||
.await,
|
||||
None => handle_full_metadata(opts.nodes.as_slice(), opts.version, output).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_pallet_metadata(
|
||||
nodes: &[Url],
|
||||
name: &str,
|
||||
version: MetadataVersion,
|
||||
output: &mut impl std::io::Write,
|
||||
) -> 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.clone(), version).await?;
|
||||
|
||||
match metadata.pallet_by_name(name) {
|
||||
Some(pallet_metadata) => {
|
||||
let hash = pallet_metadata.hash();
|
||||
let hex_hash = hex::encode(hash);
|
||||
writeln!(output, "Node {node:?} has pallet metadata hash {hex_hash:?}")?;
|
||||
|
||||
compatibility.pallet_present.entry(hex_hash).or_default().push(node.to_string());
|
||||
},
|
||||
None => {
|
||||
compatibility.pallet_not_found.push(node.to_string());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(
|
||||
output,
|
||||
"\nCompatible nodes by pallet\n{}",
|
||||
serde_json::to_string_pretty(&compatibility)
|
||||
.context("Failed to parse compatibility map")?
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_full_metadata(
|
||||
nodes: &[Url],
|
||||
version: MetadataVersion,
|
||||
output: &mut impl std::io::Write,
|
||||
) -> color_eyre::Result<()> {
|
||||
let mut compatibility_map: HashMap<String, Vec<String>> = HashMap::new();
|
||||
for node in nodes.iter() {
|
||||
let metadata = fetch_runtime_metadata(node.clone(), version).await?;
|
||||
let hash = metadata.hasher().hash();
|
||||
let hex_hash = hex::encode(hash);
|
||||
writeln!(output, "Node {node:?} has metadata hash {hex_hash:?}",)?;
|
||||
|
||||
compatibility_map.entry(hex_hash).or_default().push(node.to_string());
|
||||
}
|
||||
|
||||
writeln!(
|
||||
output,
|
||||
"\nCompatible nodes\n{}",
|
||||
serde_json::to_string_pretty(&compatibility_map)
|
||||
.context("Failed to parse compatibility map")?
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn fetch_runtime_metadata(
|
||||
url: Url,
|
||||
version: MetadataVersion,
|
||||
) -> color_eyre::Result<Metadata> {
|
||||
let bytes = pezkuwi_subxt_utils_fetchmetadata::from_url(url, version, None).await?;
|
||||
let metadata = Metadata::decode(&mut &bytes[..])?;
|
||||
Ok(metadata)
|
||||
}
|
||||
Reference in New Issue
Block a user