-
Notifications
You must be signed in to change notification settings - Fork 248
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
Add support for generating metadata from runtime wasm files #1720
Changes from 9 commits
d3abf9f
a5497f4
4f2517c
5e71ec8
aaad9b8
dfc352b
e8580b2
86c01fb
599145d
fab5d26
ce03cb1
e1453e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -116,6 +116,8 @@ which = "5.0.0" | |
strip-ansi-escapes = "0.2.0" | ||
proptest = "1.5.0" | ||
hex-literal = "0.4.1" | ||
sc-executor = "0.40.0" | ||
sc-executor-common = "0.35.0" | ||
Comment on lines
+119
to
+120
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very much a Nit, but these are substrate crates too so could be below with the rest :) |
||
|
||
# Light client support: | ||
smoldot = { version = "0.16.0", default-features = false } | ||
|
@@ -140,6 +142,9 @@ sp-core = { version = "31.0.0", default-features = false } | |
sp-crypto-hashing = { version = "0.1.0", default-features = false } | ||
sp-runtime = "34.0.0" | ||
sp-keyring = "34.0.0" | ||
sp-maybe-compressed-blob = "11.0.0" | ||
sp-state-machine = "0.43.0" | ||
sp-io = "38.0.0" | ||
|
||
# Subxt workspace crates: | ||
subxt = { version = "0.37.0", path = "subxt", default-features = false } | ||
|
@@ -167,6 +172,7 @@ base64 = { version = "0.22.1", default-features = false } | |
scrypt = { version = "0.11.0", default-features = false } | ||
crypto_secretbox = { version = "0.1.1", default-features = false } | ||
|
||
|
||
[profile.dev.package.smoldot-light] | ||
opt-level = 2 | ||
[profile.test.package.smoldot-light] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,9 @@ use subxt_codegen::{ | |
}; | ||
use syn::{parse_macro_input, punctuated::Punctuated}; | ||
|
||
#[cfg(feature = "runtime-path")] | ||
mod wasm_loader; | ||
|
||
#[derive(Clone, Debug)] | ||
struct OuterAttribute(syn::Attribute); | ||
|
||
|
@@ -60,6 +63,9 @@ struct RuntimeMetadataArgs { | |
no_default_substitutions: bool, | ||
#[darling(default)] | ||
unstable_metadata: darling::util::Flag, | ||
#[cfg(feature = "runtime-path")] | ||
#[darling(default)] | ||
runtime_path: Option<String>, | ||
} | ||
|
||
#[derive(Debug, FromMeta)] | ||
|
@@ -206,6 +212,22 @@ fn validate_type_path(path: &syn::Path, metadata: &Metadata) { | |
fn fetch_metadata(args: &RuntimeMetadataArgs) -> Result<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-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!( | ||
"Exclusively one of 'runtime_metadata_path', 'runtime_metadata_insecure_url' or `runtime_path` must be provided" | ||
); | ||
}; | ||
let root = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "." -> current_dir? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think so, I've just taken the default value from 'runtime_metada_path' branch tbh |
||
let root_path = std::path::Path::new(&root); | ||
let path = root_path.join(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, | ||
|
@@ -239,14 +261,9 @@ fn fetch_metadata(args: &RuntimeMetadataArgs) -> Result<subxt_codegen::Metadata, | |
.and_then(|b| subxt_codegen::Metadata::decode(&mut &*b).map_err(Into::into)) | ||
.map_err(|e| e.into_compile_error())? | ||
} | ||
(None, None) => { | ||
abort_call_site!( | ||
"One of 'runtime_metadata_path' or 'runtime_metadata_insecure_url' must be provided" | ||
) | ||
} | ||
(Some(_), Some(_)) => { | ||
_ => { | ||
pkhry marked this conversation as resolved.
Show resolved
Hide resolved
|
||
abort_call_site!( | ||
"Only one of 'runtime_metadata_path' or 'runtime_metadata_insecure_url' can be provided" | ||
"Exclusively one of 'runtime_metadata_path' or 'runtime_metadata_insecure_url' must be provided" | ||
) | ||
} | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// 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; | ||
use sc_executor::{WasmExecutionMethod, WasmExecutor}; | ||
use sc_executor_common::runtime_blob::RuntimeBlob; | ||
use sp_maybe_compressed_blob::CODE_BLOB_BOMB_LIMIT; | ||
use subxt_codegen::{fetch_metadata::fetch_metadata_from_file_blocking, CodegenError, Metadata}; | ||
|
||
/// 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 = fetch_metadata_from_file_blocking(wasm_file_path) | ||
.map_err(Into::<CodegenError>::into) | ||
.and_then(maybe_decompress)?; | ||
call_and_decode(wasm_file) | ||
} | ||
|
||
fn call_and_decode(wasm_file: Vec<u8>) -> WasmMetadataResult<Metadata> { | ||
let mut ext: 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()))?; | ||
let metadata_encoded = executor | ||
.uncached_call(runtime_blob, &mut ext, true, "Metadata_metadata", &[]) | ||
.map_err(|_| CodegenError::Wasm("method \"Metadata_metadata\" doesnt exist".to_owned()))?; | ||
|
||
let metadata = <Vec<u8>>::decode(&mut &metadata_encoded[..]).map_err(CodegenError::Decode)?; | ||
|
||
decode(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) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#[subxt::subxt(runtime_path = "../../../../artifacts/westend_runtime.wasm")] | ||
mod runtime {} | ||
|
||
#[subxt::subxt(runtime_path = "../../../../artifacts/westend_runtime.compact.compressed.wasm")] | ||
mod runtime_compressed {} | ||
|
||
fn main() { | ||
use runtime; | ||
use runtime_compressed; | ||
|
||
let _ = runtime::system::events::CodeUpdated; | ||
let _ = runtime_compressed::system::events::CodeUpdated; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice call, to add a feature-flag for these wasm deps in substrate