Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

wasm-builder: Enforce runtime_version wasm section #14228

Merged
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
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.

2 changes: 2 additions & 0 deletions client/executor/runtime-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fn main() {
.with_current_project()
.export_heap_base()
.import_memory()
.disable_runtime_version_section_check()
.build();
}

Expand All @@ -36,6 +37,7 @@ fn main() {
.import_memory()
.set_file_name("wasm_binary_with_tracing.rs")
.append_to_rust_flags(r#"--cfg feature="with-tracing""#)
.disable_runtime_version_section_check()
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fn main() {
.with_current_project()
.export_heap_base()
.import_memory()
.disable_runtime_version_section_check()
.build();
}
}
1 change: 1 addition & 0 deletions primitives/runtime-interface/test-wasm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fn main() {
.with_current_project()
.export_heap_base()
.import_memory()
.disable_runtime_version_section_check()
.build();
}
}
3 changes: 2 additions & 1 deletion utils/wasm-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ toml = "0.7.3"
walkdir = "2.3.2"
sp-maybe-compressed-blob = { version = "4.1.0-dev", path = "../../primitives/maybe-compressed-blob" }
filetime = "0.2.16"
wasm-opt = "0.112"
wasm-opt = "0.112"
parity-wasm = "0.45"
24 changes: 22 additions & 2 deletions utils/wasm-builder/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl WasmBuilderSelectProject {
file_name: None,
project_cargo_toml: get_manifest_dir().join("Cargo.toml"),
features_to_enable: Vec::new(),
check_for_runtime_version_section: true,
}
}

Expand All @@ -63,6 +64,7 @@ impl WasmBuilderSelectProject {
file_name: None,
project_cargo_toml: path,
features_to_enable: Vec::new(),
check_for_runtime_version_section: true,
})
} else {
Err("Project path must point to the `Cargo.toml` of the project")
Expand Down Expand Up @@ -93,6 +95,8 @@ pub struct WasmBuilder {
project_cargo_toml: PathBuf,
/// Features that should be enabled when building the wasm binary.
features_to_enable: Vec<String>,
/// Should the builder check that the `runtime_version` section exists in the wasm binary?
check_for_runtime_version_section: bool,
Copy link
Member

@davxy davxy May 26, 2023

Choose a reason for hiding this comment

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

Nit.
Since the default is now to check for runtime version and the default for a bool is false.
Maybe we can invert the logic here. That is, have this flag named disable_runtime_version_section_check.
Default would be false and we have a disable_runtime_version_section_check function setting this flag to true (the non default value)

}

impl WasmBuilder {
Expand Down Expand Up @@ -143,6 +147,17 @@ impl WasmBuilder {
self
}

/// Disable the check for the `runtime_version` wasm section.
///
/// By default the `wasm-builder` will ensure that the `runtime_version` section will
/// exists in the build wasm binary. This `runtime_version` section is used to get the
/// `RuntimeVersion` without needing to call into the wasm binary. However, for some
/// use cases (like tests) you may want to disable this check.
pub fn disable_runtime_version_section_check(mut self) -> Self {
self.check_for_runtime_version_section = false;
self
}

/// Build the WASM binary.
pub fn build(self) {
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!"));
Expand All @@ -165,6 +180,7 @@ impl WasmBuilder {
self.rust_flags.into_iter().map(|f| format!("{} ", f)).collect(),
self.features_to_enable,
self.file_name,
self.check_for_runtime_version_section,
);

// As last step we need to generate our `rerun-if-changed` stuff. If a build fails, we don't
Expand Down Expand Up @@ -215,7 +231,7 @@ fn generate_rerun_if_changed_instructions() {
/// The current project is determined by using the `CARGO_MANIFEST_DIR` environment variable.
///
/// `file_name` - The name + path of the file being generated. The file contains the
/// constant `WASM_BINARY`, which contains the built WASM binary.
/// constant `WASM_BINARY`, which contains the built wasm binary.
///
/// `project_cargo_toml` - The path to the `Cargo.toml` of the project that should be built.
///
Expand All @@ -224,14 +240,17 @@ fn generate_rerun_if_changed_instructions() {
/// `features_to_enable` - Features that should be enabled for the project.
///
/// `wasm_binary_name` - The optional wasm binary name that is extended with
///
/// `.compact.compressed.wasm`. If `None`, the project name will be used.
///
/// `check_for_runtime_version_section` - Should the wasm binary be checked for the
/// `runtime_version` section?
fn build_project(
file_name: PathBuf,
project_cargo_toml: PathBuf,
default_rustflags: String,
features_to_enable: Vec<String>,
wasm_binary_name: Option<String>,
check_for_runtime_version_section: bool,
) {
let cargo_cmd = match crate::prerequisites::check() {
Ok(cmd) => cmd,
Expand All @@ -247,6 +266,7 @@ fn build_project(
cargo_cmd,
features_to_enable,
wasm_binary_name,
check_for_runtime_version_section,
);

let (wasm_binary, wasm_binary_bloaty) = if let Some(wasm_binary) = wasm_binary {
Expand Down
29 changes: 29 additions & 0 deletions utils/wasm-builder/src/wasm_project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::{write_file_if_changed, CargoCommandVersioned, OFFLINE};

use build_helper::rerun_if_changed;
use cargo_metadata::{CargoOpt, Metadata, MetadataCommand};
use parity_wasm::elements::{deserialize_buffer, Module};
use std::{
borrow::ToOwned,
collections::HashSet,
Expand Down Expand Up @@ -116,6 +117,7 @@ pub(crate) fn create_and_compile(
cargo_cmd: CargoCommandVersioned,
features_to_enable: Vec<String>,
wasm_binary_name: Option<String>,
check_for_runtime_version_section: bool,
) -> (Option<WasmBinary>, WasmBinaryBloaty) {
let wasm_workspace_root = get_wasm_workspace_root();
let wasm_workspace = wasm_workspace_root.join("wbuild");
Expand All @@ -134,6 +136,10 @@ pub(crate) fn create_and_compile(
let (wasm_binary, wasm_binary_compressed, bloaty) =
compact_wasm_file(&project, profile, project_cargo_toml, wasm_binary_name);

if check_for_runtime_version_section {
ensure_runtime_version_wasm_section_exists(bloaty.wasm_binary_bloaty_path());
}

wasm_binary
.as_ref()
.map(|wasm_binary| copy_wasm_to_target_directory(project_cargo_toml, wasm_binary));
Expand All @@ -159,6 +165,29 @@ pub(crate) fn create_and_compile(
(final_wasm_binary, bloaty)
}

/// Ensures that the `runtime_version` wasm section exists in the given wasm file.
///
/// If the section can not be found, it will print an error and exit the builder.
fn ensure_runtime_version_wasm_section_exists(wasm: &Path) {
let wasm_blob = fs::read(wasm).expect("`{wasm}` was just written and should exist; qed");

let module: Module = match deserialize_buffer(&wasm_blob) {
Ok(m) => m,
Err(e) => {
println!("Failed to deserialize `{}`: {e:?}", wasm.display());
process::exit(1);
},
};

if !module.custom_sections().any(|cs| cs.name() == "runtime_version") {
println!(
"Couldn't find the `runtime_version` wasm section. \
Please ensure that you are using the `sp_version::runtime_version` attribute macro!"
);
process::exit(1);
}
}

/// Adjust the mtime of the bloaty and compressed/compact wasm files.
///
/// We add the bloaty and the compressed/compact wasm file to the `rerun-if-changed` files.
Expand Down