From 81c400e9585833d9a2d80b43c156045f5e757f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 16 Oct 2019 21:00:31 +0200 Subject: [PATCH] Make `wasmi_execution` public to use it from tests (#3829) * Make `wasmi_execution` public to use it from tests * Make `WasmRuntime` accessible as well * Add `call_in_wasm` instead of making stuff public * Use `WasmRuntime` * Move test * More feedback --- substrate/core/executor/src/error.rs | 6 +++ substrate/core/executor/src/lib.rs | 48 +++++++++++++++++++++ substrate/core/executor/src/wasm_runtime.rs | 20 ++++++--- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/substrate/core/executor/src/error.rs b/substrate/core/executor/src/error.rs index 6b3c45ee49..e1221bea54 100644 --- a/substrate/core/executor/src/error.rs +++ b/substrate/core/executor/src/error.rs @@ -99,6 +99,12 @@ impl From for Error { } } +impl From for Error { + fn from(err: WasmError) -> Error { + Error::Other(err.to_string()) + } +} + /// Type for errors occurring during Wasm runtime construction. #[derive(Debug, derive_more::Display)] pub enum WasmError { diff --git a/substrate/core/executor/src/lib.rs b/substrate/core/executor/src/lib.rs index ccc78afdb4..582ebbca34 100644 --- a/substrate/core/executor/src/lib.rs +++ b/substrate/core/executor/src/lib.rs @@ -50,6 +50,33 @@ pub use primitives::traits::Externalities; pub use wasm_interface; pub use wasm_runtime::WasmExecutionMethod; +/// Call the given `function` in the given wasm `code`. +/// +/// The signature of `function` needs to follow the default Substrate function signature. +/// +/// - `call_data`: Will be given as input parameters to `function` +/// - `execution_method`: The execution method to use. +/// - `ext`: The externalities that should be set while executing the wasm function. +/// - `heap_pages`: The number of heap pages to allocate. +/// +/// Returns the `Vec` that contains the return value of the function. +pub fn call_in_wasm( + function: &str, + call_data: &[u8], + execution_method: WasmExecutionMethod, + ext: &mut E, + code: &[u8], + heap_pages: u64, +) -> error::Result> { + let mut instance = wasm_runtime::create_wasm_runtime_with_code( + ext, + execution_method, + heap_pages, + code, + )?; + instance.call(ext, function, call_data) +} + /// Provides runtime information. pub trait RuntimeInfo { /// Native runtime information. @@ -61,3 +88,24 @@ pub trait RuntimeInfo { ext: &mut E, ) -> Option; } + +#[cfg(test)] +mod tests { + use super::*; + use runtime_test::WASM_BINARY; + use runtime_io::TestExternalities; + + #[test] + fn call_in_interpreted_wasm_works() { + let mut ext = TestExternalities::default(); + let res = call_in_wasm( + "test_empty_return", + &[], + WasmExecutionMethod::Interpreted, + &mut ext, + &WASM_BINARY, + 8, + ).unwrap(); + assert_eq!(res, vec![0u8; 0]); + } +} diff --git a/substrate/core/executor/src/wasm_runtime.rs b/substrate/core/executor/src/wasm_runtime.rs index d88ae7b9ed..8d2291fe04 100644 --- a/substrate/core/executor/src/wasm_runtime.rs +++ b/substrate/core/executor/src/wasm_runtime.rs @@ -157,6 +157,20 @@ impl RuntimesCache { } } +/// Create a wasm runtime with the given `code`. +pub fn create_wasm_runtime_with_code( + ext: &mut E, + wasm_method: WasmExecutionMethod, + heap_pages: u64, + code: &[u8], +) -> Result, WasmError> { + match wasm_method { + WasmExecutionMethod::Interpreted => + wasmi_execution::create_instance(ext, code, heap_pages) + .map(|runtime| -> Box { Box::new(runtime) }), + } +} + fn create_wasm_runtime( ext: &mut E, wasm_method: WasmExecutionMethod, @@ -165,9 +179,5 @@ fn create_wasm_runtime( let code = ext .original_storage(well_known_keys::CODE) .ok_or(WasmError::CodeNotFound)?; - match wasm_method { - WasmExecutionMethod::Interpreted => - wasmi_execution::create_instance(ext, &code, heap_pages) - .map(|runtime| -> Box { Box::new(runtime) }), - } + create_wasm_runtime_with_code(ext, wasm_method, heap_pages, &code) }