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

Make the codegen more accessible for running in WASM #1154

Merged
merged 29 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8e1b637
minor api changes
tadeohepperle Aug 25, 2023
dcc1f08
parsing instead of format_ident!
tadeohepperle Aug 29, 2023
d11c76e
fix self issue
tadeohepperle Aug 29, 2023
da83ec0
expose types on typegen
tadeohepperle Aug 31, 2023
0a91433
Merge branch 'master' into tadeo-hepperle-example-code-gen
tadeohepperle Sep 8, 2023
6204c6d
web wasm support via feature flag
tadeohepperle Sep 11, 2023
2fd6e5c
Merge branch 'master' into tadeo-hepperle-example-code-gen
tadeohepperle Sep 11, 2023
7dbae5d
fmt and clippy
tadeohepperle Sep 11, 2023
d196410
small adjustments
tadeohepperle Sep 12, 2023
5d9e817
remove exposing of types() in type generator
tadeohepperle Sep 12, 2023
6281fd2
adjust compile error
tadeohepperle Sep 12, 2023
3722035
remove little any flag
tadeohepperle Sep 12, 2023
9f7a279
Need access to the type registry from the typegen again
tadeohepperle Sep 12, 2023
7aa636a
Merge branch 'master' into tadeo-hepperle-example-code-gen
tadeohepperle Sep 15, 2023
a991381
Bump proc-macro2 from 1.0.66 to 1.0.67 (#1164)
dependabot[bot] Sep 18, 2023
260e386
Bump serde_json from 1.0.106 to 1.0.107 (#1166)
dependabot[bot] Sep 18, 2023
a1ea890
Bump trybuild from 1.0.84 to 1.0.85 (#1167)
dependabot[bot] Sep 18, 2023
ed22f43
Bump Swatinem/rust-cache from 2.6.2 to 2.7.0 (#1168)
dependabot[bot] Sep 18, 2023
9d6c404
Bump jsonrpsee from 0.20.0 to 0.20.1 (#1165)
dependabot[bot] Sep 18, 2023
721949b
Bump clap from 4.4.2 to 4.4.3 (#1163)
dependabot[bot] Sep 18, 2023
d073f54
fix double quote import introduced by merge
tadeohepperle Sep 19, 2023
1cdf564
clippy
tadeohepperle Sep 19, 2023
d16d5a7
Merge branch 'master' into tadeo-hepperle-example-code-gen
tadeohepperle Sep 19, 2023
8879c8f
put ensure_unique_types on metadata, revert toml changes
tadeohepperle Sep 20, 2023
05e1d09
fmt
tadeohepperle Sep 20, 2023
47bed78
solve frame_metadata import
tadeohepperle Sep 20, 2023
7f4fab9
tidy fetch-metadata and non_exhaustive on errors
jsdw Sep 20, 2023
16ad86d
remove the getrandom thing
tadeohepperle Sep 20, 2023
1fbe008
fix toml autoformatting
tadeohepperle Sep 20, 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
1 change: 1 addition & 0 deletions Cargo.lock

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

51 changes: 22 additions & 29 deletions cli/src/commands/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use scale_info::Variant;

use subxt_metadata::{
ConstantMetadata, Metadata, PalletMetadata, RuntimeApiMetadata, StorageEntryMetadata,
StorageEntryType,
};

/// Explore the differences between two nodes
Expand Down Expand Up @@ -220,40 +219,34 @@ impl StorageEntryDiff {
metadata_1: &Metadata,
metadata_2: &Metadata,
) -> Self {
let value_1_ty_id = match storage_entry_1.entry_type() {
StorageEntryType::Plain(value_ty) | StorageEntryType::Map { value_ty, .. } => value_ty,
};
let value_1_ty_id = storage_entry_1.entry_type().value_ty();
let value_1_hash = metadata_1
.type_hash(*value_1_ty_id)
.type_hash(value_1_ty_id)
.expect("type should be present");
let value_2_ty_id = match storage_entry_2.entry_type() {
StorageEntryType::Plain(value_ty) | StorageEntryType::Map { value_ty, .. } => value_ty,
};
let value_2_ty_id = storage_entry_2.entry_type().value_ty();
let value_2_hash = metadata_1
.type_hash(*value_2_ty_id)
.type_hash(value_2_ty_id)
.expect("type should be present");
let value_different = value_1_hash != value_2_hash;

let key_1_hash = match storage_entry_1.entry_type() {
StorageEntryType::Plain(_) => None,
StorageEntryType::Map { key_ty, .. } => Some(*key_ty),
}
.map(|key_ty| {
metadata_1
.type_hash(key_ty)
.expect("type should be present")
})
.unwrap_or_default();
let key_2_hash = match storage_entry_2.entry_type() {
StorageEntryType::Plain(_) => None,
StorageEntryType::Map { key_ty, .. } => Some(*key_ty),
}
.map(|key_ty| {
metadata_2
.type_hash(key_ty)
.expect("type should be present")
})
.unwrap_or_default();
let key_1_hash = storage_entry_1
.entry_type()
.key_ty()
.map(|key_ty| {
metadata_1
.type_hash(key_ty)
.expect("type should be present")
})
.unwrap_or_default();
let key_2_hash = storage_entry_2
.entry_type()
.key_ty()
.map(|key_ty| {
metadata_2
.type_hash(key_ty)
.expect("type should be present")
})
.unwrap_or_default();
let key_different = key_1_hash != key_2_hash;

StorageEntryDiff {
Expand Down
17 changes: 14 additions & 3 deletions codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,30 @@ documentation = "https://docs.rs/subxt-codegen"
homepage.workspace = true
description = "Generate an API for interacting with a substrate node from FRAME metadata"

[features]
default = ["fetch_metadata"]
fetch_metadata = ["dep:jsonrpsee", "dep:tokio", "dep:frame-metadata"]
niklasad1 marked this conversation as resolved.
Show resolved Hide resolved
web = ["getrandom/js"]
niklasad1 marked this conversation as resolved.
Show resolved Hide resolved

[dependencies]
codec = { package = "parity-scale-codec", workspace = true, features = ["derive"] }
frame-metadata = { workspace = true }
frame-metadata = { workspace = true, optional = true }
heck = { workspace = true }
proc-macro2 = { workspace = true }
quote = { workspace = true }
syn = { workspace = true }
scale-info = { workspace = true }
subxt-metadata = { workspace = true }
jsonrpsee = { workspace = true, features = ["async-client", "client-ws-transport-native-tls", "http-client"] }
jsonrpsee = { workspace = true, features = [
niklasad1 marked this conversation as resolved.
Show resolved Hide resolved
"async-client",
"client-ws-transport-native-tls",
"http-client",
], optional = true }
hex = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread"] }
tokio = { workspace = true, features = ["rt-multi-thread"], optional = true }
thiserror = { workspace = true }
getrandom = { workspace = true, optional = true }


[dev-dependencies]
bitvec = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions codegen/src/api/custom_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use heck::ToSnakeCase as _;
use subxt_metadata::{CustomValueMetadata, Metadata};

use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use quote::{quote, ToTokens};

/// Generate the custom values mod, if there are any custom values in the metadata. Else returns None.
Expand Down
8 changes: 6 additions & 2 deletions codegen/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ use crate::error::CodegenError;
use crate::{
ir,
types::{CompositeDef, CompositeDefFields, TypeGenerator, TypeSubstitutes},
utils::{fetch_metadata_bytes_blocking, MetadataVersion, Url},
CratePath,
};

#[cfg(feature = "fetch_metadata")]
use crate::utils::{fetch_metadata_bytes_blocking, MetadataVersion, Url};

use codec::Decode;
use heck::ToSnakeCase as _;
use proc_macro2::TokenStream as TokenStream2;
Expand Down Expand Up @@ -146,6 +149,7 @@ impl GenerateRuntimeApi {
/// # Warning
///
/// Not recommended to be used in production environments.
#[cfg(feature = "fetch_metadata")]
pub fn generate_from_url(self, url: Url) -> Result<TokenStream2, CodegenError> {
fn fetch_metadata(url: Url, version: MetadataVersion) -> Result<Metadata, CodegenError> {
let bytes = fetch_metadata_bytes_blocking(url, version)?;
Expand Down Expand Up @@ -233,7 +237,7 @@ impl RuntimeGenerator {
/// unique path, so that types with matching paths don't end up overwriting each other
/// in the codegen. We ignore any types with generics; Subxt actually endeavours to
/// de-duplicate those into single types with a generic.
fn ensure_unique_type_paths(metadata: &mut Metadata) {
pub fn ensure_unique_type_paths(metadata: &mut Metadata) {
jsdw marked this conversation as resolved.
Show resolved Hide resolved
let mut visited_path_counts = HashMap::<Vec<String>, usize>::new();
for ty in metadata.types_mut().types.iter_mut() {
// Ignore types without a path (ie prelude types).
Expand Down
6 changes: 2 additions & 4 deletions codegen/src/api/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,7 @@ fn generate_storage_entry_fns(
};

let snake_case_name = storage_entry.name().to_snake_case();
let storage_entry_ty = match storage_entry.entry_type() {
StorageEntryType::Plain(ty) => *ty,
StorageEntryType::Map { value_ty, .. } => *value_ty,
};
let storage_entry_ty = storage_entry.entry_type().value_ty();
let storage_entry_value_ty = type_gen.resolve_type_path(storage_entry_ty);
let docs = storage_entry.docs();
let docs = should_gen_docs
Expand Down Expand Up @@ -173,6 +170,7 @@ fn primitive_type_alias(type_path: &TypePath) -> TokenStream {
quote!(#type_path)
}

#[cfg(feature = "fetch_metadata")]
niklasad1 marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(test)]
mod tests {
use crate::RuntimeGenerator;
Expand Down
1 change: 1 addition & 0 deletions codegen/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ pub enum FetchMetadataError {
DecodeError(#[from] hex::FromHexError),
#[error("Cannot scale encode/decode value: {0}")]
CodecError(#[from] codec::Error),
#[cfg(feature = "fetch_metadata")]
#[error("Request error: {0}")]
RequestError(#[from] jsonrpsee::core::Error),
#[error("'{0}' not supported, supported URI schemes are http, https, ws or wss.")]
Expand Down
13 changes: 12 additions & 1 deletion codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,21 @@ mod error;
mod ir;
mod types;

#[cfg(feature = "fetch_metadata")]
pub mod utils;

#[cfg(all(feature = "web", feature = "fetch_metadata"))]
compile_error!("subxt-codegen: the features 'web' and 'fetch_metadata' cannot be used together.");

#[cfg(feature = "web")]
#[allow(unused_imports)]
pub use getrandom as _;

pub use self::{
api::{GenerateRuntimeApi, RuntimeGenerator},
error::{CodegenError, TypeSubstitutionError},
types::{CratePath, Derives, DerivesRegistry, Module, TypeGenerator, TypeSubstitutes},
types::{
CratePath, Derives, DerivesRegistry, Module, TypeDefGen, TypeDefParameters, TypeGenerator,
TypeSubstitutes,
},
};
5 changes: 5 additions & 0 deletions codegen/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ impl<'a> TypeGenerator<'a> {
self.derives.default_derives()
}

/// Returns the type registry.
pub fn types(&self) -> &PortableRegistry {
self.type_registry
}
jsdw marked this conversation as resolved.
Show resolved Hide resolved

/// Returns the derives to be applied to a generated type.
pub fn type_derives(&self, ty: &Type<PortableForm>) -> Result<Derives, CodegenError> {
let joined_path = ty.path.segments.join("::");
Expand Down
5 changes: 5 additions & 0 deletions codegen/src/types/type_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ impl TypeDefGen {
ty_docs,
})
}

/// are there unused type params?
pub fn has_unused_type_params(&self) -> bool {
self.type_params.has_unused_type_params()
}
}

impl quote::ToTokens for TypeDefGen {
Expand Down
5 changes: 5 additions & 0 deletions codegen/src/types/type_def_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ impl TypeDefParameters {
pub fn params(&self) -> &[TypeParameter] {
&self.params
}

/// Returns true if there are any unused type params
pub fn has_unused_type_params(&self) -> bool {
!self.unused.is_empty()
}
}

impl quote::ToTokens for TypeDefParameters {
Expand Down
4 changes: 3 additions & 1 deletion metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ homepage.workspace = true
description = "Command line utilities for checking metadata compatibility between nodes."

[dependencies]
codec = { package = "parity-scale-codec", workspace = true, features = ["derive"] }
codec = { package = "parity-scale-codec", workspace = true, features = [
"derive",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dq: I do like the prior formatting more since I find one-liners easier to follow. Did you find any good formatters for .toml or its just personal preference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I use the Even Better TOML VSCode extension for formatting. Let me revert it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tadeohepperle can you fix this as well?

] }
frame-metadata = { workspace = true }
scale-info = { workspace = true }
sp-core-hashing = { workspace = true }
Expand Down
17 changes: 17 additions & 0 deletions metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,23 @@ pub enum StorageEntryType {
},
}

impl StorageEntryType {
/// The type of the value.
pub fn value_ty(&self) -> u32 {
match self {
StorageEntryType::Map { value_ty, .. } | StorageEntryType::Plain(value_ty) => *value_ty,
}
}

/// The type of the key, can be a tuple with elements for each of the hashers. None for a Plain storage entry.
pub fn key_ty(&self) -> Option<u32> {
match self {
StorageEntryType::Map { key_ty, .. } => Some(*key_ty),
StorageEntryType::Plain(_) => None,
}
}
}

/// Hasher used by storage maps.
#[derive(Debug, Clone, Copy)]
pub enum StorageHasher {
Expand Down
Loading