Refactor NativeExecutor to support multiple Wasm execution methods (#3677)

* executor: Move definitions of externals out of wasm_executor module.

* executor: Create WasmRuntime trait.

This will be used to decouple the runtime cache from wasmi execution.

* executor: Remove WasmExecutor and move methods to wasmi_execution.

These will now be crate-internal functions and there is no need
for the struct.

* executor: Set default default_heap_pages in NativeExecutor.

* cli: CLI configuration for Wasm execution method.

* executor: Remove wasmi-specific code from wasm_runtime.

* Respond to review comments.
This commit is contained in:
Jim Posen
2019-10-08 12:57:12 +02:00
committed by GitHub
parent 2c77262c8f
commit 6cebbbf8b2
22 changed files with 1359 additions and 1237 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ mod tests {
);
fn executor() -> executor::NativeExecutor<Executor> {
executor::NativeExecutor::new(None)
executor::NativeExecutor::new(executor::WasmExecutionMethod::Interpreted, None)
}
fn construct_block(
+2 -2
View File
@@ -49,7 +49,7 @@
//! use substrate_client::{Client, in_mem::Backend, LocalCallExecutor};
//! use primitives::Blake2Hasher;
//! use sr_primitives::{StorageOverlay, ChildrenStorageOverlay};
//! use executor::NativeExecutor;
//! use executor::{NativeExecutor, WasmExecutionMethod};
//!
//! // In this example, we're using the `Block` and `RuntimeApi` types from the
//! // `substrate-test-runtime-client` crate. These types are automatically generated when
@@ -62,7 +62,7 @@
//! backend.clone(),
//! LocalCallExecutor::new(
//! backend.clone(),
//! NativeExecutor::<LocalExecutor>::new(None),
//! NativeExecutor::<LocalExecutor>::new(WasmExecutionMethod::Interpreted, None),
//! None,
//! ),
//! // This parameter provides the storage for the chain genesis.
@@ -304,7 +304,7 @@ mod tests {
use consensus::BlockOrigin;
use primitives::offchain::NeverOffchainExt;
use test_client::{self, runtime::{Header, Digest, Block}, ClientExt, TestClient};
use executor::NativeExecutor;
use executor::{NativeExecutor, WasmExecutionMethod};
use crate::backend::{Backend, NewBlockState};
use crate::in_mem::Backend as InMemBackend;
use super::*;
@@ -399,6 +399,10 @@ mod tests {
}
}
fn local_executor() -> NativeExecutor<test_client::LocalExecutor> {
NativeExecutor::new(WasmExecutionMethod::Interpreted, None)
}
#[test]
fn execution_proof_is_generated_and_checked() {
fn execute(remote_client: &TestClient, at: u64, method: &'static str) -> (Vec<u8>, Vec<u8>) {
@@ -413,8 +417,7 @@ mod tests {
).unwrap();
// check remote execution proof locally
let local_executor = NativeExecutor::<test_client::LocalExecutor>::new(None);
let local_result = check_execution_proof(&local_executor, &RemoteCallRequest {
let local_result = check_execution_proof(&local_executor(), &RemoteCallRequest {
block: test_client::runtime::Hash::default(),
header: remote_header,
method: method.into(),
@@ -437,9 +440,8 @@ mod tests {
).unwrap();
// check remote execution proof locally
let local_executor = NativeExecutor::<test_client::LocalExecutor>::new(None);
let execution_result = check_execution_proof_with_make_header(
&local_executor,
&local_executor(),
&RemoteCallRequest {
block: test_client::runtime::Hash::default(),
header: remote_header,
+25 -15
View File
@@ -503,7 +503,7 @@ pub mod tests {
use parking_lot::Mutex;
use codec::Decode;
use crate::client::tests::prepare_client_with_key_changes;
use executor::{self, NativeExecutor};
use executor::{NativeExecutor, WasmExecutionMethod};
use crate::error::Error as ClientError;
use test_client::{
self, ClientExt, blockchain::HeaderBackend, AccountKeyring,
@@ -563,12 +563,16 @@ pub mod tests {
}
type TestChecker = LightDataChecker<
executor::NativeExecutor<test_client::LocalExecutor>,
NativeExecutor<test_client::LocalExecutor>,
Blake2Hasher,
Block,
DummyStorage,
>;
fn local_executor() -> NativeExecutor<test_client::LocalExecutor> {
NativeExecutor::new(WasmExecutionMethod::Interpreted, None)
}
fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec<Vec<u8>>, u32) {
// prepare remote client
let remote_client = test_client::new();
@@ -596,8 +600,10 @@ pub mod tests {
None,
crate::backend::NewBlockState::Final,
).unwrap();
let local_executor = NativeExecutor::<test_client::LocalExecutor>::new(None);
let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor);
let local_checker = LightDataChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
local_executor()
);
(local_checker, remote_block_header, remote_read_proof, heap_pages)
}
@@ -636,8 +642,10 @@ pub mod tests {
None,
crate::backend::NewBlockState::Final,
).unwrap();
let local_executor = NativeExecutor::<test_client::LocalExecutor>::new(None);
let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor);
let local_checker = LightDataChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
local_executor(),
);
(local_checker, remote_block_header, remote_read_proof, child_value)
}
@@ -662,8 +670,10 @@ pub mod tests {
if insert_cht {
local_storage.insert_cht_root(1, local_cht_root);
}
let local_executor = NativeExecutor::<test_client::LocalExecutor>::new(None);
let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor);
let local_checker = LightDataChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
local_executor(),
);
(local_checker, local_cht_root, remote_block_header, remote_header_proof)
}
@@ -744,7 +754,7 @@ pub mod tests {
let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes();
let local_checker = TestChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
NativeExecutor::<test_client::LocalExecutor>::new(None)
local_executor(),
);
let local_checker = &local_checker as &dyn FetchChecker<Block>;
let max = remote_client.info().chain.best_number;
@@ -813,7 +823,7 @@ pub mod tests {
local_storage.changes_tries_cht_roots.insert(0, local_cht_root);
let local_checker = TestChecker::new(
Arc::new(DummyBlockchain::new(local_storage)),
NativeExecutor::<test_client::LocalExecutor>::new(None)
local_executor(),
);
// check proof on local client
@@ -842,7 +852,7 @@ pub mod tests {
let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes();
let local_checker = TestChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
NativeExecutor::<test_client::LocalExecutor>::new(None)
local_executor(),
);
let local_checker = &local_checker as &dyn FetchChecker<Block>;
let max = remote_client.info().chain.best_number;
@@ -924,7 +934,7 @@ pub mod tests {
// fails when changes trie CHT is missing from the local db
let local_checker = TestChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
NativeExecutor::<test_client::LocalExecutor>::new(None)
local_executor(),
);
assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots,
remote_proof.roots_proof.clone()).is_err());
@@ -934,7 +944,7 @@ pub mod tests {
local_storage.changes_tries_cht_roots.insert(0, local_cht_root);
let local_checker = TestChecker::new(
Arc::new(DummyBlockchain::new(local_storage)),
NativeExecutor::<test_client::LocalExecutor>::new(None)
local_executor(),
);
assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, vec![]).is_err());
}
@@ -948,7 +958,7 @@ pub mod tests {
let local_checker = TestChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
NativeExecutor::<test_client::LocalExecutor>::new(None)
local_executor(),
);
let body_request = RemoteBodyRequest {
@@ -971,7 +981,7 @@ pub mod tests {
let local_checker = TestChecker::new(
Arc::new(DummyBlockchain::new(DummyStorage::new())),
NativeExecutor::<test_client::LocalExecutor>::new(None)
local_executor(),
);
let body_request = RemoteBodyRequest {