Add function for embedding the runtime version in a wasm blob (#9277)

* Add function for embedding the runtime version in a wasm blob

This function can be used to add the custom section to a wasm blob with
the runtime version in it.

* Review nitpick
This commit is contained in:
Bastian Köcher
2021-07-06 12:41:27 +02:00
committed by GitHub
parent 279ff4b6e6
commit f781dcaf2c
6 changed files with 98 additions and 0 deletions
+3
View File
@@ -7478,6 +7478,7 @@ dependencies = [
"sp-core",
"sp-externalities",
"sp-io",
"sp-maybe-compressed-blob",
"sp-panic-handler",
"sp-runtime",
"sp-runtime-interface",
@@ -9444,10 +9445,12 @@ version = "3.0.0"
dependencies = [
"impl-serde",
"parity-scale-codec",
"parity-wasm 0.42.2",
"serde",
"sp-runtime",
"sp-std",
"sp-version-proc-macro",
"thiserror",
]
[[package]]
+1
View File
@@ -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"
@@ -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::embed_runtime_version(
&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
View File
@@ -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"]
@@ -30,4 +32,6 @@ std = [
"codec/std",
"sp-std/std",
"sp-runtime/std",
"parity-wasm",
"thiserror",
]
+56
View File
@@ -0,0 +1,56 @@
// 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 embed_runtime_version(
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();
module.set_custom_section("runtime_version", version.encode());
serialize(module).map_err(|_| Error::Serialize)
}
+3
View File
@@ -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.
///