fix: Resolve cargo clippy errors and add CI workflow plan

## Changes

### Clippy Fixes
- Fixed deprecated `cargo_bin` usage in 27 test files (added #![allow(deprecated)])
- Fixed uninlined_format_args in zombienet-sdk-tests
- Fixed subxt API changes in revive/rpc/tests.rs (fetch signature, StorageValue)
- Fixed dead_code warnings in validator-pool and identity-kyc mocks
- Fixed field name `i` -> `_i` in tasks example

### CI Infrastructure
- Added .claude/WORKFLOW_PLAN.md for tracking CI fix progress
- Updated lychee.toml and taplo.toml configs

### Files Modified
- 27 test files with deprecated cargo_bin fix
- bizinikiwi/pezframe/revive/rpc/src/tests.rs (subxt API)
- pezkuwi/pezpallets/validator-pool/src/{mock,tests}.rs
- pezcumulus/teyrchains/pezpallets/identity-kyc/src/mock.rs
- bizinikiwi/pezframe/examples/tasks/src/tests.rs

## Status
- cargo clippy: PASSING
- Next: cargo fmt, zepter, workspace checks
This commit is contained in:
2025-12-22 16:36:14 +03:00
parent 8acf59c6aa
commit 65b7f5e640
1393 changed files with 17834 additions and 179151 deletions
-316
View File
@@ -1,316 +0,0 @@
// 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.
//! Subxt macro for generating Substrate runtime interfaces.
use codec::Decode;
use darling::{FromMeta, ast::NestedMeta};
use proc_macro::TokenStream;
use proc_macro_error2::{abort_call_site, proc_macro_error};
use quote::ToTokens;
use scale_typegen::typegen::{
settings::substitutes::path_segments,
validation::{registry_contains_type_path, similar_type_paths_in_registry},
};
use pezkuwi_subxt_codegen::{CodegenBuilder, CodegenError, Metadata};
use syn::{parse_macro_input, punctuated::Punctuated};
#[cfg(feature = "runtime-wasm-path")]
mod wasm_loader;
#[derive(Clone, Debug)]
struct OuterAttribute(syn::Attribute);
impl syn::parse::Parse for OuterAttribute {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Ok(Self(input.call(syn::Attribute::parse_outer)?[0].clone()))
}
}
#[derive(Debug, FromMeta)]
struct RuntimeMetadataArgs {
#[darling(default)]
runtime_metadata_path: Option<String>,
#[darling(default)]
runtime_metadata_insecure_url: Option<String>,
#[darling(default)]
derive_for_all_types: Option<Punctuated<syn::Path, syn::Token![,]>>,
#[darling(default)]
attributes_for_all_types: Option<Punctuated<OuterAttribute, syn::Token![,]>>,
#[darling(multiple)]
derive_for_type: Vec<DeriveForType>,
#[darling(multiple)]
attributes_for_type: Vec<AttributesForType>,
#[darling(multiple)]
substitute_type: Vec<SubstituteType>,
#[darling(default, rename = "crate")]
crate_path: Option<syn::Path>,
#[darling(default)]
generate_docs: darling::util::Flag,
#[darling(default)]
runtime_types_only: bool,
#[darling(default)]
no_default_derives: bool,
#[darling(default)]
no_default_substitutions: bool,
#[darling(default)]
unstable_metadata: darling::util::Flag,
#[cfg(feature = "runtime-wasm-path")]
#[darling(default)]
runtime_path: Option<String>,
}
#[derive(Debug, FromMeta)]
struct DeriveForType {
path: syn::TypePath,
derive: Punctuated<syn::Path, syn::Token![,]>,
#[darling(default)]
recursive: bool,
}
#[derive(Debug, FromMeta)]
struct AttributesForType {
path: syn::TypePath,
attributes: Punctuated<OuterAttribute, syn::Token![,]>,
#[darling(default)]
recursive: bool,
}
#[derive(Debug, FromMeta)]
struct SubstituteType {
path: syn::Path,
with: syn::Path,
}
// Note: docs for this are in the subxt library; don't add further docs here as they will be appended.
#[allow(missing_docs)]
#[proc_macro_attribute]
#[proc_macro_error]
pub fn subxt(args: TokenStream, input: TokenStream) -> TokenStream {
match subxt_inner(args, parse_macro_input!(input as syn::ItemMod)) {
Ok(e) => e,
Err(e) => e,
}
}
// Note: just an additional function to make early returns easier.
fn subxt_inner(args: TokenStream, item_mod: syn::ItemMod) -> Result<TokenStream, TokenStream> {
let attr_args = NestedMeta::parse_meta_list(args.into())
.map_err(|e| TokenStream::from(darling::Error::from(e).write_errors()))?;
let args = RuntimeMetadataArgs::from_list(&attr_args)
.map_err(|e| TokenStream::from(e.write_errors()))?;
// Fetch metadata first, because we need it to validate some of the chosen codegen options.
let metadata = {
let mut metadata = fetch_metadata(&args)?;
// Run this first to ensure type paths are unique (which may result in 1,2,3 suffixes being added
// to type paths), so that when we validate derives/substitutions below, they are allowed for such
// types. See <https://github.com/paritytech/subxt/issues/2011>.
scale_typegen::utils::ensure_unique_type_paths(metadata.types_mut())
.expect("ensure_unique_type_paths should not fail; please report an issue.");
metadata
};
let mut codegen = CodegenBuilder::new();
// Use the item module that the macro is on:
codegen.set_target_module(item_mod);
// Use the provided crate path:
if let Some(crate_path) = args.crate_path {
codegen.set_subxt_crate_path(crate_path)
}
// Respect the boolean flags:
if args.runtime_types_only {
codegen.runtime_types_only();
}
if args.no_default_derives {
codegen.disable_default_derives();
}
if args.no_default_substitutions {
codegen.disable_default_substitutes();
}
if !args.generate_docs.is_present() {
codegen.no_docs()
}
// Configure derives:
codegen.set_additional_global_derives(
args.derive_for_all_types
.unwrap_or_default()
.into_iter()
.collect(),
);
for d in args.derive_for_type {
validate_type_path(&d.path.path, &metadata);
codegen.add_derives_for_type(d.path, d.derive.into_iter(), d.recursive);
}
// Configure attributes:
codegen.set_additional_global_attributes(
args.attributes_for_all_types
.unwrap_or_default()
.into_iter()
.map(|a| a.0)
.collect(),
);
for d in args.attributes_for_type {
validate_type_path(&d.path.path, &metadata);
codegen.add_attributes_for_type(d.path, d.attributes.into_iter().map(|a| a.0), d.recursive)
}
// Insert type substitutions:
for sub in args.substitute_type.into_iter() {
validate_type_path(&sub.path, &metadata);
codegen.set_type_substitute(sub.path, sub.with);
}
let code = codegen
.generate(metadata)
.map_err(|e| e.into_compile_error())?;
Ok(code.into())
}
/// Checks that a type is present in the type registry. If it is not found, abort with a
/// helpful error message, showing the user alternative types, that have the same name, but are at different locations in the metadata.
fn validate_type_path(path: &syn::Path, metadata: &Metadata) {
let path_segments = path_segments(path);
let ident = &path
.segments
.last()
.expect("Empty path should be filtered out before already")
.ident;
if !registry_contains_type_path(metadata.types(), &path_segments) {
let alternatives = similar_type_paths_in_registry(metadata.types(), path);
let alternatives: String = if alternatives.is_empty() {
format!("There is no Type with name `{ident}` in the provided metadata.")
} else {
let mut s = "A type with the same name is present at: ".to_owned();
for p in alternatives {
s.push('\n');
s.push_str(&pretty_path(&p));
}
s
};
abort_call_site!(
"Type `{}` does not exist at path `{}`\n\n{}",
ident.to_string(),
pretty_path(path),
alternatives
);
}
fn pretty_path(path: &syn::Path) -> String {
path.to_token_stream().to_string().replace(' ', "")
}
}
/// Resolves a path, handling the $OUT_DIR placeholder if present.
/// If $OUT_DIR is present in the path, it's replaced with the actual OUT_DIR environment variable.
/// Otherwise, the path is resolved relative to CARGO_MANIFEST_DIR.
fn resolve_path(path_str: &str) -> std::path::PathBuf {
if path_str.contains("$OUT_DIR") {
let out_dir = std::env::var("OUT_DIR").unwrap_or_else(|_| {
abort_call_site!("$OUT_DIR is used in path but OUT_DIR environment variable is not set")
});
std::path::Path::new(&path_str.replace("$OUT_DIR", &out_dir)).into()
} else {
let root = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into());
let root_path = std::path::Path::new(&root);
root_path.join(path_str)
}
}
/// Fetches metadata in a blocking manner, from a url or file path.
fn fetch_metadata(args: &RuntimeMetadataArgs) -> Result<pezkuwi_subxt_codegen::Metadata, TokenStream> {
// Do we want to fetch unstable metadata? This only works if fetching from a URL.
let unstable_metadata = args.unstable_metadata.is_present();
#[cfg(feature = "runtime-wasm-path")]
if let Some(path) = &args.runtime_path {
if args.runtime_metadata_insecure_url.is_some() || args.runtime_metadata_path.is_some() {
abort_call_site!(
"Only one of 'runtime_metadata_path', 'runtime_metadata_insecure_url' or `runtime_path` must be provided"
);
};
let path = resolve_path(path);
let metadata = wasm_loader::from_wasm_file(&path).map_err(|e| e.into_compile_error())?;
return Ok(metadata);
};
let metadata = match (
&args.runtime_metadata_path,
&args.runtime_metadata_insecure_url,
) {
(Some(rest_of_path), None) => {
if unstable_metadata {
abort_call_site!(
"The 'unstable_metadata' attribute requires `runtime_metadata_insecure_url`"
)
}
let path = resolve_path(rest_of_path);
pezkuwi_subxt_utils_fetchmetadata::from_file_blocking(&path)
.and_then(|b| pezkuwi_subxt_codegen::Metadata::decode(&mut &*b).map_err(Into::into))
.map_err(|e| CodegenError::Other(e.to_string()).into_compile_error())?
}
#[cfg(feature = "runtime-metadata-insecure-url")]
(None, Some(url_string)) => {
use pezkuwi_subxt_utils_fetchmetadata::{MetadataVersion, Url, from_url_blocking};
let url = Url::parse(url_string).unwrap_or_else(|_| {
abort_call_site!("Cannot download metadata; invalid url: {}", url_string)
});
let version = match unstable_metadata {
true => MetadataVersion::Unstable,
false => MetadataVersion::Latest,
};
from_url_blocking(url, version, None)
.map_err(|e| CodegenError::Other(e.to_string()))
.and_then(|b| pezkuwi_subxt_codegen::Metadata::decode(&mut &*b).map_err(Into::into))
.map_err(|e| e.into_compile_error())?
}
#[cfg(not(feature = "runtime-metadata-insecure-url"))]
(None, Some(_)) => {
abort_call_site!(
"'runtime_metadata_insecure_url' requires the 'runtime-metadata-insecure-url' feature to be enabled"
)
}
#[cfg(feature = "runtime-wasm-path")]
(None, None) => {
abort_call_site!(
"At least one of 'runtime_metadata_path', 'runtime_metadata_insecure_url' or 'runtime_path` can be provided"
)
}
#[cfg(not(feature = "runtime-wasm-path"))]
(None, None) => {
abort_call_site!(
"At least one of 'runtime_metadata_path', 'runtime_metadata_insecure_url' can be provided"
)
}
#[cfg(feature = "runtime-wasm-path")]
_ => {
abort_call_site!(
"Only one of 'runtime_metadata_path', 'runtime_metadata_insecure_url' or 'runtime_path` can be provided"
)
}
#[cfg(not(feature = "runtime-wasm-path"))]
_ => {
abort_call_site!(
"Only one of 'runtime_metadata_path' or 'runtime_metadata_insecure_url' can be provided"
)
}
};
Ok(metadata)
}
-153
View File
@@ -1,153 +0,0 @@
// Copyright 2024 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
use std::{borrow::Cow, path::Path};
use codec::{Decode, Encode};
use sc_executor::{WasmExecutionMethod, WasmExecutor};
use sc_executor_common::runtime_blob::RuntimeBlob;
use sp_maybe_compressed_blob::{self, CODE_BLOB_BOMB_LIMIT};
use pezkuwi_subxt_codegen::{CodegenError, Metadata};
use pezkuwi_subxt_metadata::SUPPORTED_METADATA_VERSIONS;
/// Result type shorthand
pub type WasmMetadataResult<A> = Result<A, CodegenError>;
/// Uses wasm artifact produced by compiling the runtime to generate metadata
pub fn from_wasm_file(wasm_file_path: &Path) -> WasmMetadataResult<Metadata> {
let wasm_file = pezkuwi_subxt_utils_fetchmetadata::from_file_blocking(wasm_file_path)
.map_err(|e| CodegenError::Other(e.to_string()))
.and_then(maybe_decompress)?;
call_and_decode(wasm_file)
}
fn call_and_decode(wasm_file: Vec<u8>) -> WasmMetadataResult<Metadata> {
let mut executor = Executor::new(&wasm_file)?;
if let Ok(versions) = executor.versions() {
let version = versions
.into_iter()
.max()
.expect("This is checked earlier and can't fail.");
executor.load_metadata_at_version(version)
} else {
executor.load_legacy_metadata()
}
}
fn decode(encoded_metadata: Vec<u8>) -> WasmMetadataResult<Metadata> {
Metadata::decode(&mut encoded_metadata.as_ref()).map_err(Into::into)
}
fn maybe_decompress(file_contents: Vec<u8>) -> WasmMetadataResult<Vec<u8>> {
sp_maybe_compressed_blob::decompress(file_contents.as_ref(), CODE_BLOB_BOMB_LIMIT)
.map_err(|e| CodegenError::Wasm(e.to_string()))
.map(Cow::into_owned)
}
struct Executor {
runtime_blob: RuntimeBlob,
executor: WasmExecutor<sp_io::SubstrateHostFunctions>,
externalities: sp_state_machine::BasicExternalities,
}
impl Executor {
fn new(wasm_file: &[u8]) -> WasmMetadataResult<Self> {
let externalities: sp_state_machine::BasicExternalities = Default::default();
let executor: WasmExecutor<sp_io::SubstrateHostFunctions> = WasmExecutor::builder()
.with_execution_method(WasmExecutionMethod::default())
.with_offchain_heap_alloc_strategy(sc_executor::HeapAllocStrategy::Dynamic {
maximum_pages: Some(64),
})
.with_max_runtime_instances(1)
.with_runtime_cache_size(1)
.build();
let runtime_blob =
RuntimeBlob::new(wasm_file).map_err(|e| CodegenError::Wasm(e.to_string()))?;
Ok(Self {
runtime_blob,
executor,
externalities,
})
}
fn versions(&mut self) -> WasmMetadataResult<Vec<u32>> {
let version = self
.executor
.uncached_call(
self.runtime_blob.clone(),
&mut self.externalities,
true,
"Metadata_metadata_versions",
&[],
)
.map_err(|_| {
CodegenError::Wasm("method \"Metadata_metadata_versions\" doesnt exist".to_owned())
})?;
let versions = <Vec<u32>>::decode(&mut &version[..])
.map_err(CodegenError::Decode)
.map(|x| {
x.into_iter()
.filter(|version| SUPPORTED_METADATA_VERSIONS.contains(version))
.collect::<Vec<u32>>()
})?;
if versions.is_empty() {
return Err(CodegenError::Other(
"No supported metadata versions were returned".to_owned(),
));
}
Ok(versions)
}
fn load_legacy_metadata(&mut self) -> WasmMetadataResult<Metadata> {
let encoded_metadata = self
.executor
.uncached_call(
self.runtime_blob.clone(),
&mut self.externalities,
true,
"Metadata_metadata",
&[],
)
.map_err(|e| {
CodegenError::Wasm(format!(
"Failed to call \"Metadata_metadata\" on WASM runtime. Cause: {e}"
))
})?;
let encoded_metadata =
<Vec<u8>>::decode(&mut &encoded_metadata[..]).map_err(CodegenError::Decode)?;
decode(encoded_metadata)
}
fn load_metadata_at_version(&mut self, version: u32) -> WasmMetadataResult<Metadata> {
let encoded_metadata = self
.executor
.uncached_call(
self.runtime_blob.clone(),
&mut self.externalities,
true,
"Metadata_metadata_at_version",
&version.encode(),
)
.map_err(|e| {
CodegenError::Wasm(format!(
"Failed to call \"Metadata_metadata_at_version\" on WASM runtime. Cause: {e}"
))
})?;
let Some(encoded_metadata) =
<Option<Vec<u8>>>::decode(&mut &encoded_metadata[..]).map_err(CodegenError::Decode)?
else {
return Err(CodegenError::Other(
format!("Received empty metadata at version: v{version}").to_owned(),
));
};
decode(encoded_metadata)
}
}