mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 18:31:05 +00:00
Implement runtime version checks in set_code (#4548)
* Implement runtime version checks in `set_code` Check that the new runtime code given to `set_code` fullfills some requirements: - `spec_name` matches - `spec_version` does not decreases - `impl_version` does not decreases - Either `spec_version` and `impl_version` increase * Make tests almost work * Some fixes after master merge * Fix tests * Add missed file * Make depedency check happy? * Remove leftover `sc-executor` * AHHHHH * Reset debug stuff * Remove some 'static * More 'static * Some docs * Update `Cargo.lock`
This commit is contained in:
committed by
Gavin Wood
parent
437772be9e
commit
afc3318f21
@@ -57,6 +57,10 @@ pub enum Error {
|
||||
/// Runtime failed.
|
||||
#[display(fmt="Runtime error")]
|
||||
Runtime,
|
||||
/// Runtime panicked.
|
||||
#[display(fmt="Runtime panicked: {}", _0)]
|
||||
#[from(ignore)]
|
||||
RuntimePanicked(String),
|
||||
/// Invalid memory reference.
|
||||
#[display(fmt="Invalid memory reference")]
|
||||
InvalidMemoryReference,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
//! Definitions for a wasm runtime.
|
||||
|
||||
use crate::error::Error;
|
||||
use sp_core::traits::Externalities;
|
||||
use sp_wasm_interface::Function;
|
||||
|
||||
/// A trait that defines an abstract wasm runtime.
|
||||
@@ -34,6 +33,5 @@ pub trait WasmRuntime {
|
||||
fn host_functions(&self) -> &[&'static dyn Function];
|
||||
|
||||
/// Call a method in the Substrate runtime by name. Returns the encoded result on success.
|
||||
fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8])
|
||||
-> Result<Vec<u8>, Error>;
|
||||
fn call(&mut self, method: &str, data: &[u8]) -> Result<Vec<u8>, Error>;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ fn call_in_wasm<E: Externalities>(
|
||||
code: &[u8],
|
||||
heap_pages: u64,
|
||||
) -> crate::error::Result<Vec<u8>> {
|
||||
crate::call_in_wasm::<E, HostFunctions>(
|
||||
crate::call_in_wasm::<HostFunctions>(
|
||||
function,
|
||||
call_data,
|
||||
execution_method,
|
||||
|
||||
@@ -39,7 +39,7 @@ mod wasm_runtime;
|
||||
mod integration_tests;
|
||||
|
||||
pub use wasmi;
|
||||
pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch};
|
||||
pub use native_executor::{with_externalities_safe, NativeExecutor, NativeExecutionDispatch};
|
||||
pub use sp_version::{RuntimeVersion, NativeVersion};
|
||||
pub use codec::Codec;
|
||||
#[doc(hidden)]
|
||||
@@ -57,26 +57,55 @@ pub use sc_executor_common::{error, allocator, sandbox};
|
||||
/// - `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.
|
||||
/// If `None` is given, no externalities will be set.
|
||||
/// - `heap_pages`: The number of heap pages to allocate.
|
||||
///
|
||||
/// Returns the `Vec<u8>` that contains the return value of the function.
|
||||
pub fn call_in_wasm<E: Externalities, HF: sp_wasm_interface::HostFunctions>(
|
||||
pub fn call_in_wasm<HF: sp_wasm_interface::HostFunctions>(
|
||||
function: &str,
|
||||
call_data: &[u8],
|
||||
execution_method: WasmExecutionMethod,
|
||||
ext: &mut E,
|
||||
ext: &mut dyn Externalities,
|
||||
code: &[u8],
|
||||
heap_pages: u64,
|
||||
allow_missing_imports: bool,
|
||||
) -> error::Result<Vec<u8>> {
|
||||
let mut instance = wasm_runtime::create_wasm_runtime_with_code(
|
||||
call_in_wasm_with_host_functions(
|
||||
function,
|
||||
call_data,
|
||||
execution_method,
|
||||
ext,
|
||||
code,
|
||||
heap_pages,
|
||||
HF::host_functions(),
|
||||
allow_missing_imports,
|
||||
)
|
||||
}
|
||||
|
||||
/// Non-generic version of [`call_in_wasm`] that takes the `host_functions` as parameter.
|
||||
/// For more information please see [`call_in_wasm`].
|
||||
pub fn call_in_wasm_with_host_functions(
|
||||
function: &str,
|
||||
call_data: &[u8],
|
||||
execution_method: WasmExecutionMethod,
|
||||
ext: &mut dyn Externalities,
|
||||
code: &[u8],
|
||||
heap_pages: u64,
|
||||
host_functions: Vec<&'static dyn sp_wasm_interface::Function>,
|
||||
allow_missing_imports: bool,
|
||||
) -> error::Result<Vec<u8>> {
|
||||
let instance = wasm_runtime::create_wasm_runtime_with_code(
|
||||
execution_method,
|
||||
heap_pages,
|
||||
code,
|
||||
HF::host_functions(),
|
||||
host_functions,
|
||||
allow_missing_imports,
|
||||
)?;
|
||||
instance.call(ext, function, call_data)
|
||||
|
||||
// It is safe, as we delete the instance afterwards.
|
||||
let mut instance = std::panic::AssertUnwindSafe(instance);
|
||||
|
||||
with_externalities_safe(ext, move || instance.call(function, call_data)).and_then(|r| r)
|
||||
}
|
||||
|
||||
/// Provides runtime information.
|
||||
@@ -98,7 +127,7 @@ mod tests {
|
||||
fn call_in_interpreted_wasm_works() {
|
||||
let mut ext = TestExternalities::default();
|
||||
let mut ext = ext.ext();
|
||||
let res = call_in_wasm::<_, sp_io::SubstrateHostFunctions>(
|
||||
let res = call_in_wasm::<sp_io::SubstrateHostFunctions>(
|
||||
"test_empty_return",
|
||||
&[],
|
||||
WasmExecutionMethod::Interpreted,
|
||||
|
||||
@@ -22,7 +22,7 @@ use sp_version::{NativeVersion, RuntimeVersion};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_core::{NativeOrEncoded, traits::{CodeExecutor, Externalities}};
|
||||
use log::trace;
|
||||
use std::{result, cell::RefCell, panic::{UnwindSafe, AssertUnwindSafe}};
|
||||
use std::{result, cell::RefCell, panic::{UnwindSafe, AssertUnwindSafe}, sync::Arc};
|
||||
use sp_wasm_interface::{HostFunctions, Function};
|
||||
use sc_executor_common::wasm_runtime::WasmRuntime;
|
||||
|
||||
@@ -33,22 +33,29 @@ thread_local! {
|
||||
/// Default num of pages for the heap
|
||||
const DEFAULT_HEAP_PAGES: u64 = 1024;
|
||||
|
||||
pub(crate) fn safe_call<F, U>(f: F) -> Result<U>
|
||||
where F: UnwindSafe + FnOnce() -> U
|
||||
{
|
||||
// Substrate uses custom panic hook that terminates process on panic. Disable
|
||||
// termination for the native call.
|
||||
let _guard = sp_panic_handler::AbortGuard::force_unwind();
|
||||
std::panic::catch_unwind(f).map_err(|_| Error::Runtime)
|
||||
}
|
||||
|
||||
/// Set up the externalities and safe calling environment to execute calls to a native runtime.
|
||||
/// Set up the externalities and safe calling environment to execute runtime calls.
|
||||
///
|
||||
/// If the inner closure panics, it will be caught and return an error.
|
||||
pub fn with_native_environment<F, U>(ext: &mut dyn Externalities, f: F) -> Result<U>
|
||||
pub fn with_externalities_safe<F, U>(ext: &mut dyn Externalities, f: F) -> Result<U>
|
||||
where F: UnwindSafe + FnOnce() -> U
|
||||
{
|
||||
sp_externalities::set_and_run_with_externalities(ext, move || safe_call(f))
|
||||
sp_externalities::set_and_run_with_externalities(
|
||||
ext,
|
||||
move || {
|
||||
// Substrate uses custom panic hook that terminates process on panic. Disable
|
||||
// termination for the native call.
|
||||
let _guard = sp_panic_handler::AbortGuard::force_unwind();
|
||||
std::panic::catch_unwind(f).map_err(|e| {
|
||||
if let Some(err) = e.downcast_ref::<String>() {
|
||||
Error::RuntimePanicked(err.clone())
|
||||
} else if let Some(err) = e.downcast_ref::<&'static str>() {
|
||||
Error::RuntimePanicked(err.to_string())
|
||||
} else {
|
||||
Error::RuntimePanicked("Unknown panic".into())
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Delegate for dispatching a CodeExecutor call.
|
||||
@@ -80,7 +87,7 @@ pub struct NativeExecutor<D> {
|
||||
/// The number of 64KB pages to allocate for Wasm execution.
|
||||
default_heap_pages: u64,
|
||||
/// The host functions registered with this instance.
|
||||
host_functions: Vec<&'static dyn Function>,
|
||||
host_functions: Arc<Vec<&'static dyn Function>>,
|
||||
}
|
||||
|
||||
impl<D: NativeExecutionDispatch> NativeExecutor<D> {
|
||||
@@ -107,7 +114,7 @@ impl<D: NativeExecutionDispatch> NativeExecutor<D> {
|
||||
fallback_method,
|
||||
native_version: D::native_version(),
|
||||
default_heap_pages: default_heap_pages.unwrap_or(DEFAULT_HEAP_PAGES),
|
||||
host_functions,
|
||||
host_functions: Arc::new(host_functions),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +146,7 @@ impl<D: NativeExecutionDispatch> NativeExecutor<D> {
|
||||
ext,
|
||||
self.fallback_method,
|
||||
self.default_heap_pages,
|
||||
&self.host_functions,
|
||||
&*self.host_functions,
|
||||
)?;
|
||||
|
||||
let runtime = AssertUnwindSafe(runtime);
|
||||
@@ -181,7 +188,7 @@ impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: NativeExecutionDispatch> CodeExecutor for NativeExecutor<D> {
|
||||
impl<D: NativeExecutionDispatch + 'static> CodeExecutor for NativeExecutor<D> {
|
||||
type Error = Error;
|
||||
|
||||
fn call
|
||||
@@ -212,13 +219,15 @@ impl<D: NativeExecutionDispatch> CodeExecutor for NativeExecutor<D> {
|
||||
onchain_version,
|
||||
);
|
||||
|
||||
safe_call(
|
||||
move || runtime.call(&mut **ext, method, data).map(NativeOrEncoded::Encoded)
|
||||
with_externalities_safe(
|
||||
&mut **ext,
|
||||
move || runtime.call(method, data).map(NativeOrEncoded::Encoded)
|
||||
)
|
||||
}
|
||||
(false, _, _) => {
|
||||
safe_call(
|
||||
move || runtime.call(&mut **ext, method, data).map(NativeOrEncoded::Encoded)
|
||||
with_externalities_safe(
|
||||
&mut **ext,
|
||||
move || runtime.call(method, data).map(NativeOrEncoded::Encoded)
|
||||
)
|
||||
},
|
||||
(true, true, Some(call)) => {
|
||||
@@ -230,7 +239,7 @@ impl<D: NativeExecutionDispatch> CodeExecutor for NativeExecutor<D> {
|
||||
);
|
||||
|
||||
used_native = true;
|
||||
let res = with_native_environment(&mut **ext, move || (call)())
|
||||
let res = with_externalities_safe(&mut **ext, move || (call)())
|
||||
.and_then(|r| r
|
||||
.map(NativeOrEncoded::Native)
|
||||
.map_err(|s| Error::ApiError(s.to_string()))
|
||||
@@ -255,6 +264,27 @@ impl<D: NativeExecutionDispatch> CodeExecutor for NativeExecutor<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: NativeExecutionDispatch> sp_core::traits::CallInWasm for NativeExecutor<D> {
|
||||
fn call_in_wasm(
|
||||
&self,
|
||||
wasm_blob: &[u8],
|
||||
method: &str,
|
||||
call_data: &[u8],
|
||||
ext: &mut dyn Externalities,
|
||||
) -> std::result::Result<Vec<u8>, String> {
|
||||
crate::call_in_wasm_with_host_functions(
|
||||
method,
|
||||
call_data,
|
||||
self.fallback_method,
|
||||
ext,
|
||||
wasm_blob,
|
||||
self.default_heap_pages,
|
||||
(*self.host_functions).clone(),
|
||||
false,
|
||||
).map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements a `NativeExecutionDispatch` for provided parameters.
|
||||
///
|
||||
/// # Example
|
||||
@@ -318,7 +348,7 @@ macro_rules! native_executor_instance {
|
||||
method: &str,
|
||||
data: &[u8]
|
||||
) -> $crate::error::Result<Vec<u8>> {
|
||||
$crate::with_native_environment(ext, move || $dispatcher(method, data))?
|
||||
$crate::with_externalities_safe(ext, move || $dispatcher(method, data))?
|
||||
.ok_or_else(|| $crate::error::Error::MethodNotFound(method.to_owned()))
|
||||
}
|
||||
|
||||
|
||||
@@ -223,8 +223,9 @@ fn create_versioned_wasm_runtime<E: Externalities>(
|
||||
// The following unwind safety assertion is OK because if the method call panics, the
|
||||
// runtime will be dropped.
|
||||
let mut runtime = AssertUnwindSafe(runtime.as_mut());
|
||||
crate::native_executor::safe_call(
|
||||
move || runtime.call(&mut **ext, "Core_version", &[])
|
||||
crate::native_executor::with_externalities_safe(
|
||||
&mut **ext,
|
||||
move || runtime.call("Core_version", &[])
|
||||
).map_err(|_| WasmError::Instantiation("panic in call to get runtime version".into()))?
|
||||
};
|
||||
let encoded_version = version_result
|
||||
|
||||
@@ -13,4 +13,3 @@ sc-executor-common = { version = "0.8", path = "../common" }
|
||||
sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" }
|
||||
sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" }
|
||||
sp-core = { version = "2.0.0", path = "../../../primitives/core" }
|
||||
sp-externalities = { version = "0.8.0", path = "../../../primitives/externalities" }
|
||||
|
||||
@@ -27,7 +27,7 @@ use wasmi::{
|
||||
memory_units::Pages, RuntimeValue::{I32, I64, self},
|
||||
};
|
||||
use codec::{Encode, Decode};
|
||||
use sp_core::{sandbox as sandbox_primitives, traits::Externalities};
|
||||
use sp_core::sandbox as sandbox_primitives;
|
||||
use log::{error, trace};
|
||||
use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule};
|
||||
use sp_wasm_interface::{
|
||||
@@ -381,7 +381,6 @@ fn get_heap_base(module: &ModuleRef) -> Result<u32, Error> {
|
||||
|
||||
/// Call a given method in the given wasm-module runtime.
|
||||
fn call_in_wasm_module(
|
||||
ext: &mut dyn Externalities,
|
||||
module_instance: &ModuleRef,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
@@ -410,13 +409,10 @@ fn call_in_wasm_module(
|
||||
let offset = fec.allocate_memory(data.len() as u32)?;
|
||||
fec.write_memory(offset, data)?;
|
||||
|
||||
let result = sp_externalities::set_and_run_with_externalities(
|
||||
ext,
|
||||
|| module_instance.invoke_export(
|
||||
method,
|
||||
&[I32(u32::from(offset) as i32), I32(data.len() as i32)],
|
||||
&mut fec,
|
||||
),
|
||||
let result = module_instance.invoke_export(
|
||||
method,
|
||||
&[I32(u32::from(offset) as i32), I32(data.len() as i32)],
|
||||
&mut fec,
|
||||
);
|
||||
|
||||
match result {
|
||||
@@ -599,7 +595,6 @@ impl WasmRuntime for WasmiRuntime {
|
||||
|
||||
fn call(
|
||||
&mut self,
|
||||
ext: &mut dyn Externalities,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
@@ -612,7 +607,6 @@ impl WasmRuntime for WasmiRuntime {
|
||||
e
|
||||
})?;
|
||||
call_in_wasm_module(
|
||||
ext,
|
||||
&self.instance,
|
||||
method,
|
||||
data,
|
||||
|
||||
@@ -13,7 +13,6 @@ sc-executor-common = { version = "0.8", path = "../common" }
|
||||
sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" }
|
||||
sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" }
|
||||
sp-core = { version = "2.0.0", path = "../../../primitives/core" }
|
||||
sp-externalities = { version = "0.8.0", path = "../../../primitives/externalities" }
|
||||
|
||||
cranelift-codegen = "0.50"
|
||||
cranelift-entity = "0.50"
|
||||
|
||||
@@ -24,7 +24,6 @@ use sc_executor_common::{
|
||||
error::{Error, Result, WasmError},
|
||||
wasm_runtime::WasmRuntime,
|
||||
};
|
||||
use sp_core::traits::Externalities;
|
||||
use sp_wasm_interface::{Pointer, WordSize, Function};
|
||||
use sp_runtime_interface::unpack_ptr_and_len;
|
||||
|
||||
@@ -70,11 +69,10 @@ impl WasmRuntime for WasmtimeRuntime {
|
||||
&self.host_functions
|
||||
}
|
||||
|
||||
fn call(&mut self, ext: &mut dyn Externalities, method: &str, data: &[u8]) -> Result<Vec<u8>> {
|
||||
fn call(&mut self, method: &str, data: &[u8]) -> Result<Vec<u8>> {
|
||||
call_method(
|
||||
&mut self.context,
|
||||
&mut self.module,
|
||||
ext,
|
||||
method,
|
||||
data,
|
||||
self.heap_pages,
|
||||
@@ -146,7 +144,6 @@ fn create_compiled_unit(
|
||||
fn call_method(
|
||||
context: &mut Context,
|
||||
module: &mut CompiledModule,
|
||||
ext: &mut dyn Externalities,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
heap_pages: u32,
|
||||
@@ -176,11 +173,9 @@ fn call_method(
|
||||
let args = [RuntimeValue::I32(u32::from(data_ptr) as i32), RuntimeValue::I32(data_len as i32)];
|
||||
|
||||
// Invoke the function in the runtime.
|
||||
let outcome = sp_externalities::set_and_run_with_externalities(ext, || {
|
||||
context
|
||||
.invoke(&mut instance, method, &args[..])
|
||||
.map_err(|e| Error::Other(format!("error calling runtime: {}", e)))
|
||||
})?;
|
||||
let outcome = context
|
||||
.invoke(&mut instance, method, &args[..])
|
||||
.map_err(|e| Error::Other(format!("error calling runtime: {}", e)))?;
|
||||
let trap_error = reset_env_state_and_take_trap(context, None)?;
|
||||
let (output_ptr, output_len) = match outcome {
|
||||
ActionOutcome::Returned { values } => match values.as_slice() {
|
||||
|
||||
@@ -412,7 +412,7 @@ for Environment<B, E, Block, N, RA, SC, VR>
|
||||
where
|
||||
Block: 'static,
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
N: NetworkT<Block> + 'static + Send,
|
||||
SC: SelectChain<Block> + 'static,
|
||||
VR: VotingRule<Block, Client<B, E, Block, RA>>,
|
||||
|
||||
@@ -372,7 +372,7 @@ pub trait GenesisAuthoritySetProvider<Block: BlockT> {
|
||||
impl<B, E, Block: BlockT, RA> GenesisAuthoritySetProvider<Block> for Client<B, E, Block, RA>
|
||||
where
|
||||
B: Backend<Block> + Send + Sync + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
{
|
||||
fn get(&self) -> Result<AuthorityList, ClientError> {
|
||||
@@ -408,7 +408,7 @@ pub fn block_import<B, E, Block: BlockT, RA, SC>(
|
||||
), ClientError>
|
||||
where
|
||||
B: Backend<Block> + 'static,
|
||||
E: CallExecutor<Block> + 'static + Clone + Send + Sync,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
RA: Send + Sync,
|
||||
SC: SelectChain<Block>,
|
||||
Client<B, E, Block, RA>: AuxStore,
|
||||
|
||||
@@ -67,7 +67,7 @@ fn grandpa_observer<B, E, Block: BlockT, RA, S, F>(
|
||||
) -> impl Future<Item=(), Error=CommandOrError<Block::Hash, NumberFor<Block>>> where
|
||||
NumberFor<Block>: BlockNumberOps,
|
||||
B: Backend<Block>,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
E: CallExecutor<Block> + Send + Sync + 'static,
|
||||
RA: Send + Sync,
|
||||
S: Stream<
|
||||
Item = CommunicationIn<Block>,
|
||||
|
||||
@@ -399,7 +399,7 @@ fn should_return_runtime_version() {
|
||||
let api = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor())));
|
||||
|
||||
let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\
|
||||
\"specVersion\":1,\"implVersion\":1,\"apis\":[[\"0xdf6acb689907609b\",2],\
|
||||
\"specVersion\":1,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",2],\
|
||||
[\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",1],[\"0x40fe3ad401f8959a\",4],\
|
||||
[\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\
|
||||
[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]]}";
|
||||
|
||||
@@ -147,7 +147,7 @@ pub fn new_full_client<TBl, TRtApi, TExecDisp, TCfg, TGen, TCSExt>(
|
||||
config: &Configuration<TCfg, TGen, TCSExt>,
|
||||
) -> Result<TFullClient<TBl, TRtApi, TExecDisp>, Error> where
|
||||
TBl: BlockT,
|
||||
TExecDisp: NativeExecutionDispatch,
|
||||
TExecDisp: NativeExecutionDispatch + 'static,
|
||||
TGen: sp_runtime::BuildStorage + serde::Serialize + for<'de> serde::Deserialize<'de>,
|
||||
TCSExt: Extension,
|
||||
{
|
||||
@@ -158,7 +158,7 @@ fn new_full_parts<TBl, TRtApi, TExecDisp, TCfg, TGen, TCSExt>(
|
||||
config: &Configuration<TCfg, TGen, TCSExt>,
|
||||
) -> Result<TFullParts<TBl, TRtApi, TExecDisp>, Error> where
|
||||
TBl: BlockT,
|
||||
TExecDisp: NativeExecutionDispatch,
|
||||
TExecDisp: NativeExecutionDispatch + 'static,
|
||||
TGen: sp_runtime::BuildStorage + serde::Serialize + for<'de> serde::Deserialize<'de>,
|
||||
TCSExt: Extension,
|
||||
{
|
||||
@@ -226,7 +226,7 @@ fn new_full_parts<TBl, TRtApi, TExecDisp, TCfg, TGen, TCSExt>(
|
||||
impl<TCfg, TGen, TCSExt> ServiceBuilder<(), (), TCfg, TGen, TCSExt, (), (), (), (), (), (), (), (), (), ()>
|
||||
where TGen: RuntimeGenesis, TCSExt: Extension {
|
||||
/// Start the service builder with a configuration.
|
||||
pub fn new_full<TBl: BlockT, TRtApi, TExecDisp: NativeExecutionDispatch>(
|
||||
pub fn new_full<TBl: BlockT, TRtApi, TExecDisp: NativeExecutionDispatch + 'static>(
|
||||
config: Configuration<TCfg, TGen, TCSExt>
|
||||
) -> Result<ServiceBuilder<
|
||||
TBl,
|
||||
|
||||
@@ -61,7 +61,7 @@ impl<B, E> Clone for LocalCallExecutor<B, E> where E: Clone {
|
||||
impl<B, E, Block> CallExecutor<Block> for LocalCallExecutor<B, E>
|
||||
where
|
||||
B: backend::Backend<Block>,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
E: CodeExecutor + RuntimeInfo + Clone + 'static,
|
||||
Block: BlockT,
|
||||
{
|
||||
type Error = E::Error;
|
||||
@@ -225,7 +225,7 @@ where
|
||||
impl<B, E, Block> sp_version::GetRuntimeVersion<Block> for LocalCallExecutor<B, E>
|
||||
where
|
||||
B: backend::Backend<Block>,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
E: CodeExecutor + RuntimeInfo + Clone + 'static,
|
||||
Block: BlockT,
|
||||
{
|
||||
fn native_version(&self) -> &sp_version::NativeVersion {
|
||||
|
||||
@@ -156,7 +156,7 @@ pub fn new_with_backend<B, E, Block, S, RA>(
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
S: BuildStorage,
|
||||
Block: BlockT,
|
||||
B: backend::LocalBackend<Block>
|
||||
B: backend::LocalBackend<Block> + 'static,
|
||||
{
|
||||
let call_executor = LocalCallExecutor::new(backend.clone(), executor);
|
||||
let extensions = ExecutionExtensions::new(Default::default(), keystore);
|
||||
@@ -750,7 +750,6 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
import_block: BlockImportParams<Block, backend::TransactionFor<B, Block>>,
|
||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||
) -> sp_blockchain::Result<ImportResult> where
|
||||
E: CallExecutor<Block> + Send + Sync + Clone,
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
ApiExt<Block, StateBackend = B::State>,
|
||||
@@ -829,7 +828,6 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
|
||||
fork_choice: ForkChoiceStrategy,
|
||||
import_existing: bool,
|
||||
) -> sp_blockchain::Result<ImportResult> where
|
||||
E: CallExecutor<Block> + Send + Sync + Clone,
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
ApiExt<Block, StateBackend = B::State>,
|
||||
@@ -1387,7 +1385,7 @@ impl<B, E, Block, RA> ProvideCache<Block> for Client<B, E, Block, RA> where
|
||||
|
||||
impl<B, E, Block, RA> ProvideRuntimeApi<Block> for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block>,
|
||||
E: CallExecutor<Block, Backend = B> + Clone + Send + Sync,
|
||||
E: CallExecutor<Block, Backend = B> + Send + Sync,
|
||||
Block: BlockT,
|
||||
RA: ConstructRuntimeApi<Block, Self>,
|
||||
{
|
||||
@@ -1400,7 +1398,7 @@ impl<B, E, Block, RA> ProvideRuntimeApi<Block> for Client<B, E, Block, RA> where
|
||||
|
||||
impl<B, E, Block, RA> CallApiAt<Block> for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block>,
|
||||
E: CallExecutor<Block, Backend = B> + Clone + Send + Sync,
|
||||
E: CallExecutor<Block, Backend = B> + Send + Sync,
|
||||
Block: BlockT,
|
||||
{
|
||||
type Error = Error;
|
||||
@@ -1448,7 +1446,7 @@ impl<B, E, Block, RA> CallApiAt<Block> for Client<B, E, Block, RA> where
|
||||
/// important verification work.
|
||||
impl<B, E, Block, RA> sp_consensus::BlockImport<Block> for &Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block>,
|
||||
E: CallExecutor<Block> + Clone + Send + Sync,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
Block: BlockT,
|
||||
Client<B, E, Block, RA>: ProvideRuntimeApi<Block>,
|
||||
<Client<B, E, Block, RA> as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
@@ -1552,7 +1550,7 @@ impl<B, E, Block, RA> sp_consensus::BlockImport<Block> for &Client<B, E, Block,
|
||||
|
||||
impl<B, E, Block, RA> sp_consensus::BlockImport<Block> for Client<B, E, Block, RA> where
|
||||
B: backend::Backend<Block>,
|
||||
E: CallExecutor<Block> + Clone + Send + Sync,
|
||||
E: CallExecutor<Block> + Send + Sync,
|
||||
Block: BlockT,
|
||||
Self: ProvideRuntimeApi<Block>,
|
||||
<Self as ProvideRuntimeApi<Block>>::Api: CoreApi<Block, Error = Error> +
|
||||
|
||||
@@ -59,7 +59,7 @@ mod tests {
|
||||
native_executor_instance!(
|
||||
Executor,
|
||||
substrate_test_runtime_client::runtime::api::dispatch,
|
||||
substrate_test_runtime_client::runtime::native_version
|
||||
substrate_test_runtime_client::runtime::native_version,
|
||||
);
|
||||
|
||||
fn executor() -> sc_executor::NativeExecutor<Executor> {
|
||||
|
||||
@@ -222,7 +222,7 @@ pub fn check_execution_proof<Header, E, H>(
|
||||
) -> ClientResult<Vec<u8>>
|
||||
where
|
||||
Header: HeaderT,
|
||||
E: CodeExecutor,
|
||||
E: CodeExecutor + Clone + 'static,
|
||||
H: Hasher,
|
||||
H::Out: Ord + codec::Codec + 'static,
|
||||
{
|
||||
@@ -248,7 +248,7 @@ fn check_execution_proof_with_make_header<Header, E, H, MakeNextHeader: Fn(&Head
|
||||
) -> ClientResult<Vec<u8>>
|
||||
where
|
||||
Header: HeaderT,
|
||||
E: CodeExecutor,
|
||||
E: CodeExecutor + Clone + 'static,
|
||||
H: Hasher,
|
||||
H::Out: Ord + codec::Codec + 'static,
|
||||
{
|
||||
|
||||
@@ -197,7 +197,7 @@ impl<E, H, B: BlockT, S: BlockchainStorage<B>> LightDataChecker<E, H, B, S> {
|
||||
impl<E, Block, H, S> FetchChecker<Block> for LightDataChecker<E, H, Block, S>
|
||||
where
|
||||
Block: BlockT,
|
||||
E: CodeExecutor,
|
||||
E: CodeExecutor + Clone + 'static,
|
||||
H: Hasher,
|
||||
H::Out: Ord + codec::Codec + 'static,
|
||||
S: BlockchainStorage<Block>,
|
||||
|
||||
@@ -73,7 +73,7 @@ pub fn new_light<B, S, GS, RA, E>(
|
||||
B: BlockT,
|
||||
S: BlockchainStorage<B> + 'static,
|
||||
GS: BuildStorage,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
E: CodeExecutor + RuntimeInfo + Clone + 'static,
|
||||
{
|
||||
let local_executor = LocalCallExecutor::new(backend.clone(), code_executor);
|
||||
let executor = GenesisCallExecutor::new(backend.clone(), local_executor);
|
||||
|
||||
Reference in New Issue
Block a user