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

Load latest metadata version from Wasm blobs. #1859

Merged
merged 3 commits into from
Nov 12, 2024
Merged
Changes from 1 commit
Commits
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
47 changes: 40 additions & 7 deletions macro/src/wasm_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::{borrow::Cow, path::Path};

use codec::Decode;
use codec::{Decode, Encode};
use polkadot_sdk::{
sc_executor::{self, WasmExecutionMethod, WasmExecutor},
sc_executor_common::runtime_blob::RuntimeBlob,
Expand Down Expand Up @@ -39,17 +39,50 @@ fn call_and_decode(wasm_file: Vec<u8>) -> WasmMetadataResult<Metadata> {

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)?;
let version = executor
.uncached_call(
runtime_blob.clone(),
&mut ext,
true,
"Metadata_metadata_versions",
&[],
)
.map_err(|_| {
CodegenError::Wasm("method \"Metadata_metadata_versions\" doesnt exist".to_owned())
})?;
let mut versions = <Vec<u32>>::decode(&mut &version[..]).map_err(CodegenError::Decode)?;

decode(metadata)
// Highest version will always be the last one in the vec
versions.sort();

let version = versions
.last()
.ok_or(CodegenError::Other(
"No metadata versions were returned".to_owned(),
))
.map(|v| v.encode())?;

let encoded_metadata = executor
.uncached_call(
runtime_blob,
&mut ext,
false,
"Metadata_metadata_at_version",
&version,
)
.map_err(|e| {
dbg!(e);
CodegenError::Wasm("method \"Metadata_metadata_at_version\" doesnt exist".to_owned())
})?;

decode(encoded_metadata)
}

fn decode(encoded_metadata: Vec<u8>) -> WasmMetadataResult<Metadata> {
Metadata::decode(&mut encoded_metadata.as_ref()).map_err(Into::into)
// We slice the first byte from the metadata because it's wrapped inside an option and we know that its always `Some`
let metadata = <Vec<u8>>::decode(&mut &encoded_metadata[1..]).map_err(CodegenError::Decode)?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: Would this panic on empty encoded_metadata?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, probably, will change

Choose a reason for hiding this comment

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

I think that the following code would work 😄

let metadata = <Option<Vec<u8>>>::decode(&mut &encoded_metadata[..]).map_err(CodegenError::Decode)?;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

refactored a bit to also fail on None

Metadata::decode(&mut metadata.as_ref()).map_err(Into::into)
}

fn maybe_decompress(file_contents: Vec<u8>) -> WasmMetadataResult<Vec<u8>> {
Expand Down
Loading