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

Commit

Permalink
tests and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
NikVolf committed Sep 16, 2020
1 parent ff8a73c commit 2a682e8
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 27 deletions.
31 changes: 21 additions & 10 deletions client/executor/runtime-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,29 +312,40 @@ sp_core::wasm_export_functions! {

fn test_fork() {
let data = vec![1u8, 2u8];
let data_new = sp_io::tasks::spawn(incrementer, data).join();
let data_new = sp_io::tasks::spawn(tasks::incrementer, data).join();

assert_eq!(data_new, vec![2u8, 3u8]);
}

fn test_nested_fork() {
let data = vec![7u8, 13u8];
let data_new = sp_io::tasks::spawn(parallel_incrementer, data).join();
let data_new = sp_io::tasks::spawn(tasks::parallel_incrementer, data).join();

assert_eq!(data_new, vec![10u8, 16u8]);
}
}

#[cfg(not(feature = "std"))]
fn incrementer(data: Vec<u8>) -> Vec<u8> {
data.into_iter().map(|v| v + 1).collect()
fn test_panic_in_fork_panics_on_join() {
let data_new = sp_io::tasks::spawn(tasks::panicker, vec![]).join();
}
}

#[cfg(not(feature = "std"))]
fn parallel_incrementer(data: Vec<u8>) -> Vec<u8> {
let first = data.into_iter().map(|v| v + 2).collect::<Vec<_>>();
let second = sp_io::tasks::spawn(incrementer, first).join();
second
mod tasks {
use sp_std::prelude::*;

pub fn incrementer(data: Vec<u8>) -> Vec<u8> {
data.into_iter().map(|v| v + 1).collect()
}

pub fn panicker(_: Vec<u8>) -> Vec<u8> {
panic!()
}

pub fn parallel_incrementer(data: Vec<u8>) -> Vec<u8> {
let first = data.into_iter().map(|v| v + 2).collect::<Vec<_>>();
let second = sp_io::tasks::spawn(incrementer, first).join();
second
}
}

#[cfg(not(feature = "std"))]
Expand Down
18 changes: 18 additions & 0 deletions client/executor/src/integration_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,3 +788,21 @@ fn nested_forking_should_work(wasm_method: WasmExecutionMethod) {
).unwrap();
}

#[test_case(WasmExecutionMethod::Interpreted)]
#[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))]
fn panic_in_fork_panics_on_join(wasm_method: WasmExecutionMethod) {

let mut ext = TestExternalities::default();
let mut ext = ext.ext();

if let Err(e) = call_in_wasm(
"test_panic_in_fork_panics_on_join",
&[],
wasm_method,
&mut ext,
) {
assert!(format!("{}", e).contains("Runtime panicked: No signal from forked execution"));
} else {
panic!("wasm call should be error")
}
}
2 changes: 1 addition & 1 deletion client/executor/src/native_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl sp_io::RuntimeSpawn for RuntimeInstanceSpawn {

// FIXME: Should be refactored to shared "instance factory".
// Instantiating wasm here every time is suboptimal at the moment, shared
// pool of istances should be used.
// pool of instances should be used.
let instance = module.new_instance().expect("Failed to create new instance for fork");

instance.call(
Expand Down
29 changes: 13 additions & 16 deletions primitives/io/src/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
//! Runtime tasks.
//!
//! Contains runtime-usable functions for spawning parallel purely computational tasks.
//!

#[cfg(feature = "std")]
mod inner {
Expand Down Expand Up @@ -79,19 +78,19 @@ mod inner {
#[cfg(not(feature = "std"))]
mod inner {

use core::mem;
use sp_std::{vec::Vec, prelude::Box};


/// Dynamic dispatch of wasm blob.
/// Dispatch wrapper for wasm blob.
///
/// Arguments are expected to be scale encoded in vector at address `payload_ptr` with length of
/// `payload_len`.
/// Serves as trampoline to call any rust function with (Vec<u8>) -> Vec<u8> compiled
/// into the runtime.
///
/// Arguments: function pointer (u32), input (Vec<u8>).
/// Function item should be provided with `func_ref`. Argument for the call
/// will be generated from bytes at `payload_ptr` with `payload_len`.
///
/// Function at pointer is expected to have signature of `(Vec<u8>) -> Vec<u8>`. Since this dynamic dispatch
/// function and the invoked function are compiled with the same compiler, there should be no problem with
/// ABI incompatibility.
/// NOTE: Since this dynamic dispatch function and the invoked function are compiled with
/// the same compiler, there should be no problem with ABI incompatibility.
extern "C" fn dispatch_wrapper(func_ref: u32, payload_ptr: u32, payload_len: u32) -> u64 {
let payload_len = payload_len as usize;
let output = unsafe {
Expand All @@ -107,13 +106,11 @@ mod inner {
pub fn spawn(entry_point: fn(Vec<u8>) -> Vec<u8>, payload: Vec<u8>) -> DataJoinHandle {
let func_ptr: usize = unsafe { core::mem::transmute(entry_point) };

let handle = unsafe {
crate::runtime_tasks::spawn(
dispatch_wrapper as usize as _,
func_ptr as u32,
payload,
)
};
let handle = crate::runtime_tasks::spawn(
dispatch_wrapper as usize as _,
func_ptr as u32,
payload,
);
DataJoinHandle { handle }
}

Expand Down

0 comments on commit 2a682e8

Please sign in to comment.