diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index 7caa98e8dc..535a77a056 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -2832,6 +2832,7 @@ dependencies = [
"sr-version 0.1.0",
"substrate-client 0.1.0",
"substrate-primitives 0.1.0",
+ "substrate-state-machine 0.1.0",
"substrate-test-client 0.1.0",
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/substrate/core/client/src/call_executor.rs b/substrate/core/client/src/call_executor.rs
index 4c274fc436..03cec8885a 100644
--- a/substrate/core/client/src/call_executor.rs
+++ b/substrate/core/client/src/call_executor.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
-use std::{sync::Arc, cmp::Ord, panic::UnwindSafe};
+use std::{sync::Arc, cmp::Ord, panic::UnwindSafe, result};
use codec::{Encode, Decode};
use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::Block as BlockT;
@@ -61,7 +61,7 @@ where
Result, Self::Error>
) -> Result, Self::Error>,
R: Encode + Decode + PartialEq,
- NC: FnOnce() -> R + UnwindSafe,
+ NC: FnOnce() -> result::Result + UnwindSafe,
>(
&self,
at: &BlockId,
@@ -89,7 +89,7 @@ where
Result, Self::Error>
) -> Result, Self::Error>,
R: Encode + Decode + PartialEq,
- NC: FnOnce() -> R + UnwindSafe,
+ NC: FnOnce() -> result::Result + UnwindSafe,
>(&self,
state: &S,
overlay: &mut OverlayedChanges,
@@ -168,7 +168,7 @@ where
let mut changes = OverlayedChanges::default();
let state = self.backend.state_at(*id)?;
let return_data = state_machine::execute_using_consensus_failure_handler::<
- _, _, _, _, _, _, fn() -> NeverNativeValue
+ _, _, _, _, _, NeverNativeValue, fn() -> _
>(
&state,
self.backend.changes_trie_storage(),
@@ -192,7 +192,7 @@ where
Result, Self::Error>
) -> Result, Self::Error>,
R: Encode + Decode + PartialEq,
- NC: FnOnce() -> R + UnwindSafe,
+ NC: FnOnce() -> result::Result + UnwindSafe,
>(
&self,
at: &BlockId,
@@ -208,7 +208,7 @@ where
if method != "Core_initialise_block" && initialised_block.map(|id| id != *at).unwrap_or(true) {
let header = prepare_environment_block()?;
state_machine::execute_using_consensus_failure_handler::<
- _, _, _, _, _, R, fn() -> R,
+ _, _, _, _, _, R, fn() -> _,
>(
&state,
self.backend.changes_trie_storage(),
@@ -254,7 +254,7 @@ where
Result, Self::Error>
) -> Result, Self::Error>,
R: Encode + Decode + PartialEq,
- NC: FnOnce() -> R + UnwindSafe,
+ NC: FnOnce() -> result::Result + UnwindSafe,
>(&self,
state: &S,
changes: &mut OverlayedChanges,
diff --git a/substrate/core/client/src/client.rs b/substrate/core/client/src/client.rs
index e8c46156f7..2313c4733d 100644
--- a/substrate/core/client/src/client.rs
+++ b/substrate/core/client/src/client.rs
@@ -16,7 +16,7 @@
//! Substrate Client
-use std::{marker::PhantomData, collections::{HashSet, BTreeMap}, sync::Arc, panic::UnwindSafe};
+use std::{marker::PhantomData, collections::{HashSet, BTreeMap}, sync::Arc, panic::UnwindSafe, result};
use crate::error::Error;
use futures::sync::mpsc;
use parking_lot::{Mutex, RwLock};
@@ -804,7 +804,7 @@ impl Client where
match transaction.state()? {
Some(transaction_state) => {
let mut overlay = Default::default();
- let (_, storage_update, changes_update) = self.executor.call_at_state::<_, _, NeverNativeValue, fn() -> NeverNativeValue>(
+ let (_, storage_update, changes_update) = self.executor.call_at_state::<_, _, NeverNativeValue, fn() -> _>(
transaction_state,
&mut overlay,
"Core_execute_block",
@@ -1244,7 +1244,9 @@ impl CallRuntimeAt for Client where
E: CallExecutor + Clone + Send + Sync,
Block: BlockT
{
- fn call_api_at R + UnwindSafe>(
+ fn call_api_at<
+ R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe
+ >(
&self,
at: &BlockId,
function: &'static str,
diff --git a/substrate/core/client/src/error.rs b/substrate/core/client/src/error.rs
index f8ac292c25..bfc073f634 100644
--- a/substrate/core/client/src/error.rs
+++ b/substrate/core/client/src/error.rs
@@ -116,6 +116,12 @@ error_chain! {
display("Error decoding call result of {}", method)
}
+ /// Error converting a parameter between runtime and node.
+ RuntimeParamConversion(param: &'static str) {
+ description("Error converting parameter between runtime and node")
+ display("Error converting `{}` between runtime and node", param)
+ }
+
/// Changes tries are not supported.
ChangesTriesNotSupported {
description("changes tries are not supported"),
diff --git a/substrate/core/client/src/light/call_executor.rs b/substrate/core/client/src/light/call_executor.rs
index 05fd9dffed..601cb0732f 100644
--- a/substrate/core/client/src/light/call_executor.rs
+++ b/substrate/core/client/src/light/call_executor.rs
@@ -17,7 +17,7 @@
//! Light client call exector. Executes methods on remote full nodes, fetching
//! execution proof and checking it locally.
-use std::{collections::HashSet, sync::Arc, panic::UnwindSafe};
+use std::{collections::HashSet, sync::Arc, panic::UnwindSafe, result, marker::PhantomData};
use futures::{IntoFuture, Future};
use codec::{Encode, Decode};
@@ -52,7 +52,7 @@ pub struct RemoteOrLocalCallExecutor, B, R, L> {
backend: Arc,
remote: R,
local: L,
- _block: ::std::marker::PhantomData,
+ _block: PhantomData,
}
impl Clone for RemoteCallExecutor {
@@ -133,7 +133,7 @@ where
Result, Self::Error>
) -> Result, Self::Error>,
R: Encode + Decode + PartialEq,
- NC: FnOnce() -> R,
+ NC: FnOnce() -> result::Result,
>(&self,
_state: &S,
_changes: &mut OverlayedChanges,
@@ -214,7 +214,7 @@ impl CallExecutor for
Result, Self::Error>
) -> Result, Self::Error>,
R: Encode + Decode + PartialEq,
- NC: FnOnce() -> R + UnwindSafe,
+ NC: FnOnce() -> result::Result + UnwindSafe,
>(
&self,
at: &BlockId,
@@ -285,7 +285,7 @@ impl CallExecutor for
Result, Self::Error>
) -> Result, Self::Error>,
R: Encode + Decode + PartialEq,
- NC: FnOnce() -> R + UnwindSafe,
+ NC: FnOnce() -> result::Result + UnwindSafe,
>(&self,
state: &S,
changes: &mut OverlayedChanges,
diff --git a/substrate/core/client/src/runtime_api.rs b/substrate/core/client/src/runtime_api.rs
index fbe5d1378b..72371bc95f 100644
--- a/substrate/core/client/src/runtime_api.rs
+++ b/substrate/core/client/src/runtime_api.rs
@@ -77,7 +77,7 @@ pub trait ApiExt {
pub trait CallRuntimeAt {
/// Calls the given api function with the given encoded arguments at the given block
/// and returns the encoded result.
- fn call_api_at R + UnwindSafe>(
+ fn call_api_at result::Result + UnwindSafe>(
&self,
at: &BlockId,
function: &'static str,
diff --git a/substrate/core/executor/src/error.rs b/substrate/core/executor/src/error.rs
index c5a6160ac1..98993519f4 100644
--- a/substrate/core/executor/src/error.rs
+++ b/substrate/core/executor/src/error.rs
@@ -23,8 +23,10 @@
use state_machine;
use serializer;
use wasmi;
-use error_chain::{error_chain, error_chain_processing, impl_error_chain_processed,
- impl_extract_backtrace, impl_error_chain_kind};
+use error_chain::{
+ error_chain, error_chain_processing, impl_error_chain_processed,
+ impl_extract_backtrace, impl_error_chain_kind
+};
error_chain! {
foreign_links {
diff --git a/substrate/core/executor/src/native_executor.rs b/substrate/core/executor/src/native_executor.rs
index 753c2227f6..cd1ab3bca2 100644
--- a/substrate/core/executor/src/native_executor.rs
+++ b/substrate/core/executor/src/native_executor.rs
@@ -14,8 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
-use std::borrow::BorrowMut;
-use std::cell::{RefMut, RefCell};
+use std::{borrow::BorrowMut, result, cell::{RefMut, RefCell}};
use crate::error::{Error, ErrorKind, Result};
use state_machine::{CodeExecutor, Externalities};
use crate::wasm_executor::WasmExecutor;
@@ -109,7 +108,7 @@ fn safe_call(f: F) -> Result
///
/// If the inner closure panics, it will be caught and return an error.
pub fn with_native_environment(ext: &mut Externalities, f: F) -> Result
-where F: UnwindSafe + FnOnce() -> U
+ where F: UnwindSafe + FnOnce() -> U
{
::runtime_io::with_externalities(ext, move || safe_call(f))
}
@@ -186,7 +185,7 @@ impl CodeExecutor for NativeExecutor,
R:Decode + Encode + PartialEq,
- NC: FnOnce() -> R + UnwindSafe
+ NC: FnOnce() -> result::Result + UnwindSafe
>(
&self,
ext: &mut E,
@@ -242,7 +241,8 @@ impl CodeExecutor for NativeExecutor".into(), |v| format!("{}", v))
);
(
- with_native_environment(ext, move || (call)()).map(NativeOrEncoded::Native),
+ with_native_environment(ext, move || (call)())
+ .and_then(|r| r.map(NativeOrEncoded::Native).map_err(Into::into)),
true
)
}
diff --git a/substrate/core/sr-api-macros/Cargo.toml b/substrate/core/sr-api-macros/Cargo.toml
index 7cc414a732..1856d3702c 100644
--- a/substrate/core/sr-api-macros/Cargo.toml
+++ b/substrate/core/sr-api-macros/Cargo.toml
@@ -15,6 +15,7 @@ blake2-rfc = "0.2"
[dev-dependencies]
substrate-client = { path = "../client" }
substrate-test-client = { path = "../test-client" }
+substrate-state-machine = { path = "../state-machine" }
sr-primitives = { path = "../sr-primitives" }
sr-version = { path = "../sr-version" }
substrate-primitives = { path = "../primitives" }
diff --git a/substrate/core/sr-api-macros/benches/bench.rs b/substrate/core/sr-api-macros/benches/bench.rs
index 54f8c8a3d1..0b829052e6 100644
--- a/substrate/core/sr-api-macros/benches/bench.rs
+++ b/substrate/core/sr-api-macros/benches/bench.rs
@@ -1,4 +1,4 @@
-// Copyright 2018 Parity Technologies (UK) Ltd.
+// Copyright 2018 - 2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
diff --git a/substrate/core/sr-api-macros/src/decl_runtime_apis.rs b/substrate/core/sr-api-macros/src/decl_runtime_apis.rs
index 54f8d81bef..13498003c2 100644
--- a/substrate/core/sr-api-macros/src/decl_runtime_apis.rs
+++ b/substrate/core/sr-api-macros/src/decl_runtime_apis.rs
@@ -17,7 +17,7 @@
use utils::{
generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait,
fold_fn_decl_for_client_side, unwrap_or_error, extract_parameter_names_types_and_borrows,
- generate_native_call_generator_fn_name
+ generate_native_call_generator_fn_name, return_type_extract_type,
};
use proc_macro;
@@ -157,12 +157,15 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result {
// Auxilariy function that is used to convert between types that use different block types.
// The function expects that both a convertable by encoding the one and decoding the other.
result.push(quote!(
+ #[cfg(any(feature = "std", test))]
fn convert_between_block_types
- (input: &I) -> R
+ (
+ input: &I, error_desc: &'static str,
+ ) -> ::std::result::Result
{
::decode(
&mut crate_::runtime_api::Encode::encode(input)[..]
- ).unwrap()
+ ).ok_or_else(|| error_desc)
}
));
@@ -172,20 +175,30 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result {
let trait_fn_name = &fn_.ident;
let fn_name = generate_native_call_generator_fn_name(&fn_.ident);
let output = return_type_replace_block_with_node_block(fn_.decl.output.clone());
+ let output_ty = return_type_extract_type(&output);
+ let output = quote!( ::std::result::Result<#output_ty, &'static str> );
// Every type that is using the `Block` generic parameter, we need to encode/decode,
// to make it compatible between the runtime/node.
let conversions = params.iter().filter(|v| type_is_using_block(&v.1)).map(|(n, t, _)| {
+ let name_str = format!(
+ "Could not convert parameter `{}` between node and runtime!", quote!(#n)
+ );
quote!(
- let #n: #t = convert_between_block_types(n);
+ let #n: #t = convert_between_block_types(n, #name_str)?;
)
});
// Same as for the input types, we need to check if we also need to convert the output,
// before returning it.
let output_conversion = if return_type_is_using_block(&fn_.decl.output) {
- quote!( convert_between_block_types(&res) )
+ quote!(
+ convert_between_block_types(
+ &res,
+ "Could not convert return value from runtime to node!"
+ )
+ )
} else {
- quote!( res )
+ quote!( Ok(res) )
};
let input_names = params.iter().map(|v| &v.0);
@@ -240,7 +253,7 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result {
#(, #impl_generics_params)*
>(
#( #fn_inputs ),*
- ) -> impl FnOnce() #output + 'a #where_clause {
+ ) -> impl FnOnce() -> #output + 'a #where_clause {
move || {
#( #conversions )*
let res = ApiImpl::#trait_fn_name(#( #input_borrows #input_names ),*);
diff --git a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs
index 6663cae85f..2909b07413 100644
--- a/substrate/core/sr-api-macros/src/impl_runtime_apis.rs
+++ b/substrate/core/sr-api-macros/src/impl_runtime_apis.rs
@@ -330,7 +330,7 @@ fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result> RuntimeApiImpl {
fn call_api_at<
R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq,
- NC: FnOnce() -> R + ::std::panic::UnwindSafe,
+ NC: FnOnce() -> ::std::result::Result + ::std::panic::UnwindSafe,
>(
&self,
at: block_id,
diff --git a/substrate/core/sr-api-macros/src/lib.rs b/substrate/core/sr-api-macros/src/lib.rs
index 3dfc26c442..52e96a57cc 100644
--- a/substrate/core/sr-api-macros/src/lib.rs
+++ b/substrate/core/sr-api-macros/src/lib.rs
@@ -16,7 +16,7 @@
//! Macros for declaring and implementing runtime apis.
-#![recursion_limit = "256"]
+#![recursion_limit = "512"]
extern crate proc_macro;
extern crate proc_macro2;
extern crate quote;
diff --git a/substrate/core/sr-api-macros/src/utils.rs b/substrate/core/sr-api-macros/src/utils.rs
index e35ed52084..9df59b30a7 100644
--- a/substrate/core/sr-api-macros/src/utils.rs
+++ b/substrate/core/sr-api-macros/src/utils.rs
@@ -58,6 +58,14 @@ pub fn generate_runtime_mod_name_for_trait(trait_: &Ident) -> Ident {
Ident::new(&format!("runtime_decl_for_{}", trait_.to_string()), Span::call_site())
}
+/// Get the type of a `syn::ReturnType`.
+pub fn return_type_extract_type(rt: &syn::ReturnType) -> Type {
+ match rt {
+ syn::ReturnType::Default => parse_quote!( () ),
+ syn::ReturnType::Type(_, ref ty) => *ty.clone(),
+ }
+}
+
/// Fold the given `FnDecl` to make it usable on the client side.
pub fn fold_fn_decl_for_client_side(
mut input: FnDecl,
@@ -70,14 +78,8 @@ pub fn fold_fn_decl_for_client_side(
// Wrap the output in a `Result`
input.output = {
- let generate_result = |ty: &Type| {
- parse_quote!( -> ::std::result::Result<#ty, #crate_::error::Error> )
- };
-
- match &input.output {
- syn::ReturnType::Default => generate_result(&parse_quote!( () )),
- syn::ReturnType::Type(_, ref ty) => generate_result(&ty),
- }
+ let ty = return_type_extract_type(&input.output);
+ parse_quote!( -> ::std::result::Result<#ty, #crate_::error::Error> )
};
input
diff --git a/substrate/core/sr-api-macros/tests/runtime_calls.rs b/substrate/core/sr-api-macros/tests/runtime_calls.rs
new file mode 100644
index 0000000000..d1d05eb48a
--- /dev/null
+++ b/substrate/core/sr-api-macros/tests/runtime_calls.rs
@@ -0,0 +1,60 @@
+// Copyright 2019 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate. If not, see .
+
+extern crate substrate_client;
+extern crate substrate_test_client as test_client;
+extern crate sr_primitives as runtime_primitives;
+extern crate substrate_state_machine as state_machine;
+
+use test_client::runtime::{TestAPI, DecodeFails};
+use runtime_primitives::{generic::BlockId, traits::ProvideRuntimeApi};
+use state_machine::ExecutionStrategy;
+
+fn calling_function_with_strat(strat: ExecutionStrategy) {
+ let client = test_client::new_with_api_execution_strat(strat);
+ let runtime_api = client.runtime_api();
+ let block_id = BlockId::Number(client.info().unwrap().chain.best_number);
+
+ assert_eq!(runtime_api.benchmark_add_one(&block_id, &1).unwrap(), 2);
+}
+
+#[test]
+fn calling_native_runtime_function() {
+ calling_function_with_strat(ExecutionStrategy::NativeWhenPossible);
+}
+
+#[test]
+fn calling_wasm_runtime_function() {
+ calling_function_with_strat(ExecutionStrategy::AlwaysWasm);
+}
+
+#[test]
+#[should_panic(expected = "Could not convert parameter `param` between node and runtime!")]
+fn calling_native_runtime_function_with_non_decodable_parameter() {
+ let client = test_client::new_with_api_execution_strat(ExecutionStrategy::NativeWhenPossible);
+ let runtime_api = client.runtime_api();
+ let block_id = BlockId::Number(client.info().unwrap().chain.best_number);
+ runtime_api.fail_convert_parameter(&block_id, DecodeFails::new()).unwrap();
+}
+
+#[test]
+#[should_panic(expected = "Could not convert return value from runtime to node!")]
+fn calling_native_runtime_function_with_non_decodable_return_value() {
+ let client = test_client::new_with_api_execution_strat(ExecutionStrategy::NativeWhenPossible);
+ let runtime_api = client.runtime_api();
+ let block_id = BlockId::Number(client.info().unwrap().chain.best_number);
+ runtime_api.fail_convert_return_value(&block_id).unwrap();
+}
diff --git a/substrate/core/state-machine/src/lib.rs b/substrate/core/state-machine/src/lib.rs
index 69d257c8a9..c2427fb0d3 100644
--- a/substrate/core/state-machine/src/lib.rs
+++ b/substrate/core/state-machine/src/lib.rs
@@ -18,7 +18,7 @@
#![warn(missing_docs)]
-use std::{fmt, panic::UnwindSafe};
+use std::{fmt, panic::UnwindSafe, result};
use log::warn;
use hash_db::Hasher;
use heapsize::HeapSizeOf;
@@ -45,7 +45,8 @@ pub use changes_trie::{
InMemoryStorage as InMemoryChangesTrieStorage,
key_changes, key_changes_proof, key_changes_proof_check,
prune as prune_changes_tries,
- oldest_non_pruned_trie as oldest_non_pruned_changes_trie};
+ oldest_non_pruned_trie as oldest_non_pruned_changes_trie
+};
pub use overlayed_changes::OverlayedChanges;
pub use proving_backend::{create_proof_check_backend, create_proof_check_backend_storage};
pub use trie_backend_essence::{TrieBackendStorage, Storage};
@@ -156,7 +157,9 @@ pub trait CodeExecutor: Sized + Send + Sync {
/// Call a given method in the runtime. Returns a tuple of the result (either the output data
/// or an execution error) together with a `bool`, which is true if native execution was used.
- fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> R + UnwindSafe>(
+ fn call<
+ E: Externalities, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe
+ >(
&self,
ext: &mut E,
method: &str,
@@ -248,7 +251,7 @@ where
{
// We are not giving a native call and thus we are sure that the result can never be a native
// value.
- execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> NeverNativeValue>(
+ execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> _>(
backend,
changes_trie_storage,
overlay,
@@ -286,7 +289,7 @@ where
/// Note: changes to code will be in place if this call is made again. For running partial
/// blocks (e.g. a transaction at a time), ensure a different method is used.
pub fn execute_using_consensus_failure_handler<
- H, B, T, Exec, Handler, R: Decode + Encode + PartialEq, NC: FnOnce() -> R + UnwindSafe
+ H, B, T, Exec, Handler, R: Decode + Encode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe
>(
backend: &B,
changes_trie_storage: Option<&T>,
@@ -443,7 +446,7 @@ where
{
let proving_backend = proving_backend::ProvingBackend::new(trie_backend);
let (result, _, _) = execute_using_consensus_failure_handler::
- , _, _, NeverNativeValue, fn() -> NeverNativeValue>
+ , _, _, NeverNativeValue, fn() -> _>
(
&proving_backend,
None,
@@ -491,7 +494,7 @@ where
H::Out: Ord + HeapSizeOf,
{
execute_using_consensus_failure_handler::
- , _, _, NeverNativeValue, fn() -> NeverNativeValue>
+ , _, _, NeverNativeValue, fn() -> _>
(
trie_backend,
None,
@@ -621,7 +624,7 @@ mod tests {
impl CodeExecutor for DummyCodeExecutor {
type Error = u8;
- fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> R>(
+ fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result>(
&self,
ext: &mut E,
_method: &str,
@@ -684,7 +687,7 @@ mod tests {
#[test]
fn dual_execution_strategy_detects_consensus_failure() {
let mut consensus_failed = false;
- assert!(execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> NeverNativeValue>(
+ assert!(execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> _>(
&trie_backend::tests::test_trie(),
Some(&InMemoryChangesTrieStorage::new()),
&mut Default::default(),
diff --git a/substrate/core/test-client/src/lib.rs b/substrate/core/test-client/src/lib.rs
index af22cb2be7..eec5770fc1 100644
--- a/substrate/core/test-client/src/lib.rs
+++ b/substrate/core/test-client/src/lib.rs
@@ -38,6 +38,8 @@ use runtime_primitives::StorageMap;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Hash as HashT};
use runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
use keyring::Keyring;
+use state_machine::ExecutionStrategy;
+use client::LocalCallExecutor;
mod local_executor {
#![allow(missing_docs)]
@@ -69,6 +71,23 @@ pub fn new() -> client::Client client::Client {
+ let backend = Arc::new(Backend::new());
+ let executor = NativeExecutor::new();
+ let executor = LocalCallExecutor::new(backend.clone(), executor);
+
+ client::Client::new(
+ backend,
+ executor,
+ genesis_storage(false),
+ ExecutionStrategy::NativeWhenPossible,
+ api_execution_strategy
+ ).expect("Creates new client")
+}
+
/// Creates new test client instance that suports changes trie creation.
pub fn new_with_changes_trie()
-> client::Client
diff --git a/substrate/core/test-runtime/src/lib.rs b/substrate/core/test-runtime/src/lib.rs
index a19c966969..d804468a64 100644
--- a/substrate/core/test-runtime/src/lib.rs
+++ b/substrate/core/test-runtime/src/lib.rs
@@ -24,12 +24,13 @@ extern crate srml_support as runtime_support;
#[cfg(feature = "std")] pub mod genesismap;
pub mod system;
-use rstd::prelude::*;
-use parity_codec::{Encode, Decode};
+use rstd::{prelude::*, marker::PhantomData};
+use parity_codec::{Encode, Decode, Input};
use parity_codec_derive::{Encode, Decode};
-use substrate_client::{runtime_api as client_api, block_builder::api as block_builder_api,
- decl_runtime_apis, impl_runtime_apis,
+use substrate_client::{
+ runtime_api as client_api, block_builder::api as block_builder_api, decl_runtime_apis,
+ impl_runtime_apis,
};
use runtime_primitives::{
ApplyResult, Ed25519Signature, transaction_validity::TransactionValidity,
@@ -164,14 +165,47 @@ pub fn changes_trie_config() -> primitives::ChangesTrieConfiguration {
}
}
+/// A type that can not be decoded.
+#[derive(PartialEq)]
+pub struct DecodeFails {
+ _phantom: PhantomData,
+}
+
+impl Encode for DecodeFails {
+ fn encode(&self) -> Vec {
+ Vec::new()
+ }
+}
+
+impl DecodeFails {
+ /// Create a new instance.
+ pub fn new() -> DecodeFails {
+ DecodeFails {
+ _phantom: Default::default(),
+ }
+ }
+}
+
+impl Decode for DecodeFails {
+ fn decode(_: &mut I) -> Option {
+ // decoding always fails
+ None
+ }
+}
+
decl_runtime_apis! {
pub trait TestAPI {
+ /// Return the balance of the given account id.
fn balance_of(id: AccountId) -> u64;
/// A benchmkark function that adds one to the given value and returns the result.
fn benchmark_add_one(val: &u64) -> u64;
/// A benchmark function that adds one to each value in the given vector and returns the
/// result.
fn benchmark_vector_add_one(vec: &Vec) -> Vec;
+ /// A function that always fails to convert a parameter between runtime and node.
+ fn fail_convert_parameter(param: DecodeFails);
+ /// A function that always fails to convert its return value between runtime and node.
+ fn fail_convert_return_value() -> DecodeFails;
}
}
@@ -252,6 +286,12 @@ impl_runtime_apis! {
vec.iter_mut().for_each(|v| *v += 1);
vec
}
+
+ fn fail_convert_parameter(_: DecodeFails) {}
+
+ fn fail_convert_return_value() -> DecodeFails {
+ DecodeFails::new()
+ }
}
impl consensus_aura::AuraApi for Runtime {
diff --git a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm
index 24b6ef4ef6..ec7eee0ddd 100644
Binary files a/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ
diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs
index f769b284e2..d98a8f32cc 100644
--- a/substrate/node/executor/src/lib.rs
+++ b/substrate/node/executor/src/lib.rs
@@ -118,7 +118,7 @@ mod tests {
twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32]
]);
- let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_initialise_block",
&vec![].and(&from_block_number(1u64)),
@@ -126,7 +126,7 @@ mod tests {
None,
).0;
assert!(r.is_ok());
- let v = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let v = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"BlockBuilder_apply_extrinsic",
&vec![].and(&xt()),
@@ -151,7 +151,7 @@ mod tests {
twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32]
]);
- let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_initialise_block",
&vec![].and(&from_block_number(1u64)),
@@ -159,7 +159,7 @@ mod tests {
None,
).0;
assert!(r.is_ok());
- let v = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let v = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"BlockBuilder_apply_extrinsic",
&vec![].and(&xt()),
@@ -184,7 +184,7 @@ mod tests {
twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32]
]);
- let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_initialise_block",
&vec![].and(&from_block_number(1u64)),
@@ -192,7 +192,7 @@ mod tests {
None,
).0;
assert!(r.is_ok());
- let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"BlockBuilder_apply_extrinsic",
&vec![].and(&xt()),
@@ -221,7 +221,7 @@ mod tests {
twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32]
]);
- let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_initialise_block",
&vec![].and(&from_block_number(1u64)),
@@ -229,7 +229,7 @@ mod tests {
None,
).0;
assert!(r.is_ok());
- let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ let r = executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"BlockBuilder_apply_extrinsic",
&vec![].and(&xt()),
@@ -422,7 +422,7 @@ mod tests {
fn full_native_block_import_works() {
let mut t = new_test_ext(COMPACT_CODE, false);
- executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&block1(false).0,
@@ -477,7 +477,7 @@ mod tests {
]);
});
- executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ executor().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&block2().0,
@@ -729,7 +729,7 @@ mod tests {
fn native_big_block_import_succeeds() {
let mut t = new_test_ext(COMPACT_CODE, false);
- Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ Executor::new().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&block1big().0,
@@ -743,7 +743,7 @@ mod tests {
let mut t = new_test_ext(COMPACT_CODE, false);
assert!(
- Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ Executor::new().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&block1big().0,
@@ -805,7 +805,7 @@ mod tests {
#[test]
fn full_native_block_import_works_with_changes_trie() {
let mut t = new_test_ext(COMPACT_CODE, true);
- Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>(
+ Executor::new().call::<_, NeverNativeValue, fn() -> _>(
&mut t,
"Core_execute_block",
&block1(true).0,
diff --git a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm
index 2d410ff28c..151d49c6a3 100644
Binary files a/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm and b/substrate/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm differ