Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata: Retain a subset of metadata pallets #879

Merged
merged 32 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4dbbd16
Update cargo.lock to use scale-info v2.4.0
lexnv Mar 23, 2023
99934de
metadata: Retain only a subset of the metadata
lexnv Mar 23, 2023
3f0f55f
codegen: Generate top level Event
lexnv Mar 24, 2023
704c512
metadata: Only retain DispatchError
lexnv Mar 24, 2023
d49c801
metadata: Export just the retain method
lexnv Mar 24, 2023
5ebab47
cli: Retain pallets
lexnv Mar 24, 2023
47e9163
metadata: Do not include extrinsic metadata
lexnv Mar 24, 2023
19eec1f
retain: Fix clippy
lexnv Mar 24, 2023
725a2e5
test-runtime: Generate per pallet metadata and rs file
lexnv Mar 27, 2023
8515b1e
ui-tests: Check per metadata generated files
lexnv Mar 27, 2023
a8d368b
Revert "test-runtime: Generate per pallet metadata and rs file"
lexnv Mar 27, 2023
64c316b
Merge remote-tracking branch 'origin/master' into lexnv/stirp_metadata
lexnv Mar 27, 2023
36bfe9e
ui-tests: Adjust path to metadata file
lexnv Mar 27, 2023
e90920c
ui-tests: Change drop order to keep `PalletMetadata` around
lexnv Mar 27, 2023
396cc7c
Update metadata/src/retain.rs
lexnv Mar 28, 2023
cc1809f
Address feedback
lexnv Mar 28, 2023
5a3c81d
retain: Keep extrinsic type
lexnv Mar 27, 2023
4a71546
cli: Introduce `MetadataSource`
lexnv Mar 28, 2023
a663236
cli: Use `MetadataSource` helper
lexnv Mar 28, 2023
d8b9824
cli: Use `FileOrUrl` flatten command argument
lexnv Mar 29, 2023
01ff1b5
retain: Do not include generic type params in retained metadata
lexnv Mar 29, 2023
e28bb8a
Adjust subxt to scale-info v2.5.0
lexnv Mar 29, 2023
2dee176
Update scaleinfo to v2.5.0
lexnv Mar 29, 2023
13cbbd6
Remove deprecated fn
lexnv Mar 29, 2023
115fbfb
testing: Fix clippy
lexnv Mar 29, 2023
6284f4a
benches: Use inner fields of scale info
lexnv Mar 29, 2023
314cb7b
Merge branch 'master' into lexnv/stirp_metadata
jsdw Apr 3, 2023
c62309f
Merge branch 'master' into lexnv/stirp_metadata
jsdw Apr 4, 2023
72e828d
address nits, and strip RuntimeCall type instead of trying to filter …
jsdw Apr 4, 2023
17d1976
fix UI test
jsdw Apr 4, 2023
e6e3016
move utils out of commands folder and fix clippy etc
jsdw Apr 4, 2023
98e3684
address nits
jsdw Apr 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 5 additions & 26 deletions cli/src/commands/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,19 @@
// see LICENSE for license details.

use clap::Parser as ClapParser;
use color_eyre::eyre;
use jsonrpsee::client_transport::ws::Uri;
use std::{fs, io::Read, path::PathBuf};
use subxt_codegen::{DerivesRegistry, TypeSubstitutes};

use super::utils::FileOrUrl;

/// Generate runtime API client code from metadata.
///
/// # Example (with code formatting)
///
/// `subxt codegen | rustfmt --edition=2018 --emit=stdout`
#[derive(Debug, ClapParser)]
pub struct Opts {
/// The url of the substrate node to query for metadata for codegen.
#[clap(name = "url", long, value_parser)]
url: Option<Uri>,
/// The path to the encoded metadata file.
#[clap(short, long, value_parser)]
file: Option<PathBuf>,
#[command(flatten)]
file_or_url: FileOrUrl,
/// Additional derives
#[clap(long = "derive")]
derives: Vec<String>,
Expand Down Expand Up @@ -52,23 +47,7 @@ fn derive_for_type_parser(src: &str) -> Result<(String, String), String> {
}

pub async fn run(opts: Opts) -> color_eyre::Result<()> {
let bytes = if let Some(file) = opts.file.as_ref() {
if opts.url.is_some() {
eyre::bail!("specify one of `--url` or `--file` but not both")
};

let mut file = fs::File::open(file)?;
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)?;
bytes
} else {
let url = opts.url.unwrap_or_else(|| {
"http://localhost:9933"
.parse::<Uri>()
.expect("default url is valid")
});
subxt_codegen::utils::fetch_metadata_bytes(&url).await?
};
let bytes = opts.file_or_url.fetch().await?;

codegen(
&bytes,
Expand Down
45 changes: 29 additions & 16 deletions cli/src/commands/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,58 @@

use clap::Parser as ClapParser;
use color_eyre::eyre;
use frame_metadata::RuntimeMetadataPrefixed;
use jsonrpsee::client_transport::ws::Uri;
use scale::Decode;
use frame_metadata::{RuntimeMetadata, RuntimeMetadataPrefixed};
use scale::{Decode, Encode};
use std::io::{self, Write};
use subxt_codegen::utils::fetch_metadata_hex;
use subxt_metadata::retain_metadata_pallets;

use super::utils::FileOrUrl;

/// Download metadata from a substrate node, for use with `subxt` codegen.
#[derive(Debug, ClapParser)]
pub struct Opts {
/// The url of the substrate node to query for metadata.
#[clap(
name = "url",
long,
value_parser,
default_value = "http://localhost:9933"
)]
url: Uri,
#[command(flatten)]
file_or_url: FileOrUrl,
/// The format of the metadata to display: `json`, `hex` or `bytes`.
#[clap(long, short, default_value = "bytes")]
format: String,
/// Generate a subset of the metadata that contains only the
/// types needed to represent the provided pallets.
#[clap(long, use_value_delimiter = true, value_parser)]
pallets: Option<Vec<String>>,
}

pub async fn run(opts: Opts) -> color_eyre::Result<()> {
let hex_data = fetch_metadata_hex(&opts.url).await?;
let bytes = opts.file_or_url.fetch().await?;
let mut metadata = <RuntimeMetadataPrefixed as Decode>::decode(&mut &bytes[..])?;

if let Some(pallets) = opts.pallets {
let metadata_v14 = match &mut metadata.1 {
RuntimeMetadata::V14(metadata_v14) => metadata_v14,
_ => {
return Err(eyre::eyre!(
"Unsupported metadata version {:?}, expected V14.",
metadata.1
))
}
};

retain_metadata_pallets(metadata_v14, |pallet| pallets.contains(&pallet.name));
}

match opts.format.as_str() {
"json" => {
let bytes = hex::decode(hex_data.trim_start_matches("0x"))?;
let metadata = <RuntimeMetadataPrefixed as Decode>::decode(&mut &bytes[..])?;
let json = serde_json::to_string_pretty(&metadata)?;
println!("{json}");
Ok(())
}
"hex" => {
let hex_data = format!("0x{:?}", hex::encode(metadata.encode()));
println!("{hex_data}");
Ok(())
}
"bytes" => {
let bytes = hex::decode(hex_data.trim_start_matches("0x"))?;
let bytes = metadata.encode();
Ok(io::stdout().write_all(&bytes)?)
}
_ => Err(eyre::eyre!(
Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
pub mod codegen;
pub mod compatibility;
pub mod metadata;
mod utils;
pub mod version;
43 changes: 43 additions & 0 deletions cli/src/commands/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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::Args;
use std::{fs, io::Read, path::PathBuf};

use color_eyre::eyre;
use subxt_codegen::utils::Uri;

/// The source of the metadata.
#[derive(Debug, Args)]
pub struct FileOrUrl {
/// The url of the substrate node to query for metadata for codegen.
#[clap(name = "url", long, value_parser)]
url: Option<Uri>,
/// The path to the encoded metadata file.
#[clap(short, long, value_parser)]
file: Option<PathBuf>,
}

impl FileOrUrl {
/// Fetch the metadata bytes.
pub async fn fetch(&self) -> color_eyre::Result<Vec<u8>> {
if let Some(path) = &self.file {
if self.url.is_some() {
eyre::bail!("specify one of `--url` or `--file` but not both")
};

let mut file = fs::File::open(path)?;
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)?;
return Ok(bytes);
}

let url = self.url.clone().unwrap_or_else(|| {
jsdw marked this conversation as resolved.
Show resolved Hide resolved
"http://localhost:9933"
.parse::<Uri>()
.expect("default url is valid")
});
Ok(subxt_codegen::utils::fetch_metadata_bytes(&url).await?)
}
}
4 changes: 2 additions & 2 deletions codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ heck = "0.4.1"
proc-macro2 = "1.0.54"
quote = "1.0.8"
syn = "1.0.109"
scale-info = "2.4.0"
scale-info = "2.5.0"
subxt-metadata = { version = "0.27.1", path = "../metadata" }
jsonrpsee = { version = "0.16.0", features = ["async-client", "client-ws-transport", "http-client"] }
hex = "0.4.3"
Expand All @@ -29,5 +29,5 @@ thiserror = "1.0.40"

[dev-dependencies]
bitvec = { version = "1.0.0", default-features = false, features = ["alloc"] }
scale-info = { version = "2.4.0", features = ["bit-vec"] }
scale-info = { version = "2.5.0", features = ["bit-vec"] }
pretty_assertions = "1.0.0"
8 changes: 4 additions & 4 deletions codegen/src/api/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub fn generate_calls(

let mut struct_defs = super::generate_structs_from_variants(
type_gen,
call.ty.id(),
call.ty.id,
|name| name.to_upper_camel_case().into(),
"Call",
crate_path,
Expand All @@ -61,7 +61,7 @@ pub fn generate_calls(
.unzip(),
CompositeDefFields::NoFields => Default::default(),
CompositeDefFields::Unnamed(_) => {
return Err(CodegenError::InvalidCallVariant(call.ty.id()))
return Err(CodegenError::InvalidCallVariant(call.ty.id))
}
};

Expand Down Expand Up @@ -106,8 +106,8 @@ pub fn generate_calls(
.into_iter()
.unzip();

let call_ty = type_gen.resolve_type(call.ty.id());
let docs = call_ty.docs();
let call_ty = type_gen.resolve_type(call.ty.id);
let docs = call_ty.docs;
let docs = should_gen_docs
.then_some(quote! { #( #[doc = #docs ] )* })
.unwrap_or_default();
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/api/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn generate_constants(
return Err(CodegenError::MissingConstantMetadata(constant_name.into(), pallet_name.into()));
};

let return_ty = type_gen.resolve_type_path(constant.ty.id());
let return_ty = type_gen.resolve_type_path(constant.ty.id);
let docs = &constant.docs;
let docs = should_gen_docs
.then_some(quote! { #( #[doc = #docs ] )* })
Expand Down
8 changes: 4 additions & 4 deletions codegen/src/api/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn generate_events(

let struct_defs = super::generate_structs_from_variants(
type_gen,
event.ty.id(),
event.ty.id,
|name| name.into(),
"Event",
crate_path,
Expand All @@ -74,9 +74,9 @@ pub fn generate_events(
}
}
});
let event_type = type_gen.resolve_type_path(event.ty.id());
let event_ty = type_gen.resolve_type(event.ty.id());
let docs = event_ty.docs();
let event_type = type_gen.resolve_type_path(event.ty.id);
let event_ty = type_gen.resolve_type(event.ty.id);
let docs = event_ty.docs;
let docs = should_gen_docs
.then_some(quote! { #( #[doc = #docs ] )* })
.unwrap_or_default();
Expand Down
Loading