Statically register host WASM functions (#10394)

* Statically register host WASM functions

* Fix `substrate-test-client` compilation

* Move `ExtendedHostFunctions` to `sp-wasm-interface`

* Fix `sp-runtime-interface` tests' compilation

* Fix `sc-executor-wasmtime` tests' compilation

* Use `runtime_interface` macro in `test-runner`

* Fix `sc-executor` tests' compilation

* Reformatting/`rustfmt`

* Add an extra comment regarding the `H` generic arg in `create_runtime`

* Even more `rustfmt`

* Depend on `wasmtime` without default features in `sp-wasm-interface`

* Bump version of `sp-wasm-interface` to 4.0.1

* Bump `sp-wasm-interface` in `Cargo.lock` too

* Bump all of the `sp-wasm-interface` requirements to 4.0.1

Maybe this will appease cargo-unleash?

* Revert "Bump all of the `sp-wasm-interface` requirements to 4.0.1"

This reverts commit 0f7ccf8e0f371542861121b145ab87af6541ac30.

* Make `cargo-unleash` happy (maybe)

* Use `cargo-unleash` to bump the crates' versions

* Align to review comments
This commit is contained in:
Koute
2021-12-14 17:26:40 +09:00
committed by GitHub
parent 23c5b6755b
commit 7711f5266e
36 changed files with 742 additions and 570 deletions
+19 -18
View File
@@ -37,7 +37,7 @@ use std::{
sync::Arc,
};
use sp_wasm_interface::Function;
use sp_wasm_interface::HostFunctions;
/// Specification of different methods of executing the runtime Wasm code.
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
@@ -199,14 +199,14 @@ impl RuntimeCache {
///
/// `wasm_method` - Type of WASM backend to use.
///
/// `host_functions` - The host functions that should be registered for the Wasm runtime.
///
/// `allow_missing_func_imports` - Ignore missing function imports.
///
/// `max_runtime_instances` - The size of the instances cache.
///
/// `f` - Function to execute.
///
/// `H` - A compile-time list of host functions to expose to the runtime.
///
/// # Returns result of `f` wrapped in an additional result.
/// In case of failure one of two errors can be returned:
///
@@ -214,17 +214,17 @@ impl RuntimeCache {
///
/// `Error::InvalidMemoryReference` is returned if no memory export with the
/// identifier `memory` can be found in the runtime.
pub fn with_instance<'c, R, F>(
pub fn with_instance<'c, H, R, F>(
&self,
runtime_code: &'c RuntimeCode<'c>,
ext: &mut dyn Externalities,
wasm_method: WasmExecutionMethod,
default_heap_pages: u64,
host_functions: &[&'static dyn Function],
allow_missing_func_imports: bool,
f: F,
) -> Result<Result<R, Error>, Error>
where
H: HostFunctions,
F: FnOnce(
&Arc<dyn WasmModule>,
&mut dyn WasmInstance,
@@ -247,12 +247,11 @@ impl RuntimeCache {
let time = std::time::Instant::now();
let result = create_versioned_wasm_runtime(
let result = create_versioned_wasm_runtime::<H>(
&code,
ext,
wasm_method,
heap_pages,
host_functions.into(),
allow_missing_func_imports,
self.max_runtime_instances,
self.cache_path.as_deref(),
@@ -288,14 +287,16 @@ impl RuntimeCache {
}
/// Create a wasm runtime with the given `code`.
pub fn create_wasm_runtime_with_code(
pub fn create_wasm_runtime_with_code<H>(
wasm_method: WasmExecutionMethod,
heap_pages: u64,
blob: RuntimeBlob,
host_functions: Vec<&'static dyn Function>,
allow_missing_func_imports: bool,
cache_path: Option<&Path>,
) -> Result<Arc<dyn WasmModule>, WasmError> {
) -> Result<Arc<dyn WasmModule>, WasmError>
where
H: HostFunctions,
{
match wasm_method {
WasmExecutionMethod::Interpreted => {
// Wasmi doesn't have any need in a cache directory.
@@ -307,13 +308,13 @@ pub fn create_wasm_runtime_with_code(
sc_executor_wasmi::create_runtime(
blob,
heap_pages,
host_functions,
H::host_functions(),
allow_missing_func_imports,
)
.map(|runtime| -> Arc<dyn WasmModule> { Arc::new(runtime) })
},
#[cfg(feature = "wasmtime")]
WasmExecutionMethod::Compiled => sc_executor_wasmtime::create_runtime(
WasmExecutionMethod::Compiled => sc_executor_wasmtime::create_runtime::<H>(
blob,
sc_executor_wasmtime::Config {
heap_pages,
@@ -327,7 +328,6 @@ pub fn create_wasm_runtime_with_code(
parallel_compilation: true,
},
},
host_functions,
)
.map(|runtime| -> Arc<dyn WasmModule> { Arc::new(runtime) }),
}
@@ -392,16 +392,18 @@ pub fn read_embedded_version(blob: &RuntimeBlob) -> Result<Option<RuntimeVersion
}
}
fn create_versioned_wasm_runtime(
fn create_versioned_wasm_runtime<H>(
code: &[u8],
ext: &mut dyn Externalities,
wasm_method: WasmExecutionMethod,
heap_pages: u64,
host_functions: Vec<&'static dyn Function>,
allow_missing_func_imports: bool,
max_instances: usize,
cache_path: Option<&Path>,
) -> Result<VersionedRuntime, WasmError> {
) -> Result<VersionedRuntime, WasmError>
where
H: HostFunctions,
{
// The incoming code may be actually compressed. We decompress it here and then work with
// the uncompressed code from now on.
let blob = sc_executor_common::runtime_blob::RuntimeBlob::uncompress_if_needed(&code)?;
@@ -411,11 +413,10 @@ fn create_versioned_wasm_runtime(
// runtime.
let mut version: Option<_> = read_embedded_version(&blob)?;
let runtime = create_wasm_runtime_with_code(
let runtime = create_wasm_runtime_with_code::<H>(
wasm_method,
heap_pages,
blob,
host_functions,
allow_missing_func_imports,
cache_path,
)?;