Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions client/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ substrate-test-runtime = { version = "2.0.0", path = "../../test-utils/runtime"
sp-state-machine = { version = "0.9.0", path = "../../primitives/state-machine" }
sp-runtime = { version = "3.0.0", path = "../../primitives/runtime" }
sp-tracing = { version = "3.0.0", path = "../../primitives/tracing" }
sp-maybe-compressed-blob = { version = "3.0.0", path = "../../primitives/maybe-compressed-blob" }
sc-tracing = { version = "3.0.0", path = "../tracing" }
tracing = "0.1.25"
tracing-subscriber = "0.2.18"
Expand Down
31 changes: 31 additions & 0 deletions client/executor/src/wasm_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,4 +526,35 @@ mod tests {
let version = decode_version(&old_runtime_version.encode()).unwrap();
assert_eq!(3, version.transaction_version);
}

#[test]
fn embed_runtime_version_works() {
let wasm = sp_maybe_compressed_blob::decompress(
substrate_test_runtime::wasm_binary_unwrap(),
sp_maybe_compressed_blob::CODE_BLOB_BOMB_LIMIT,
).expect("Decompressing works");

let runtime_version = RuntimeVersion {
spec_name: "test_replace".into(),
impl_name: "test_replace".into(),
authoring_version: 100,
spec_version: 100,
impl_version: 100,
apis: sp_api::create_apis_vec!([(<dyn Core::<Block>>::ID, 3)]),
transaction_version: 100,
};

let embedded = sp_version::embed::to_wasm(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: not a fan of this naming. Precisely how it looks at the call site.

&wasm,
runtime_version.clone(),
).expect("Embedding works");

let blob = RuntimeBlob::new(&embedded).expect("Embedded blob is valid");
let read_version = read_embedded_version(&blob)
.ok()
.flatten()
.expect("Reading embedded version works");

assert_eq!(runtime_version, read_version);
}
}
4 changes: 4 additions & 0 deletions primitives/version/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ codec = { package = "parity-scale-codec", version = "2.0.0", default-features =
sp-std = { version = "3.0.0", default-features = false, path = "../std" }
sp-runtime = { version = "3.0.0", default-features = false, path = "../runtime" }
sp-version-proc-macro = { version = "3.0.0", default-features = false, path = "proc-macro" }
parity-wasm = { version = "0.42.2", optional = true }
thiserror = { version = "1.0.21", optional = true }

[features]
default = ["std"]
Expand All @@ -30,4 +32,6 @@ std = [
"codec/std",
"sp-std/std",
"sp-runtime/std",
"parity-wasm",
"thiserror",
]
53 changes: 53 additions & 0 deletions primitives/version/src/embed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// This file is part of Substrate.

// Copyright (C) 2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Provides functionality to embed a [`RuntimeVersion`](crate::RuntimeVersion) as custom section
//! into a WASM file.

use codec::Encode;
use parity_wasm::elements::{Module, deserialize_buffer, serialize};

#[derive(Clone, Copy, Eq, PartialEq, Debug, thiserror::Error)]
pub enum Error {
#[error("Deserializing wasm failed")]
Deserialize,
#[error("Serializing wasm failed")]
Serialize,
}

/// Embed the given `version` to the given `wasm` blob.
///
/// If there was already a runtime version embedded, this will be overwritten.
///
/// Returns the new WASM blob.
pub fn to_wasm(wasm: &[u8], mut version: crate::RuntimeVersion) -> Result<Vec<u8>, Error> {
let mut module: Module = deserialize_buffer(wasm).map_err(|_| Error::Deserialize)?;

let apis = version.apis
.iter()
.map(Encode::encode)
.map(|v| v.into_iter())
.flatten()
.collect::<Vec<u8>>();

module.set_custom_section("runtime_apis", apis);

version.apis.to_mut().clear();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: I find this .clear a bit clumsy. It would've been great if we "taken" the version.apis via mem::take.

module.set_custom_section("runtime_version", version.encode());

serialize(module).map_err(|_| Error::Serialize)
}
3 changes: 3 additions & 0 deletions primitives/version/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pub use sp_std;
#[cfg(feature = "std")]
use sp_runtime::{traits::Block as BlockT, generic::BlockId};

#[cfg(feature = "std")]
pub mod embed;

/// An attribute that accepts a version declaration of a runtime and generates a custom wasm section
/// with the equivalent contents.
///
Expand Down