diff --git a/substrate/bin/node/executor/benches/bench.rs b/substrate/bin/node/executor/benches/bench.rs index cd201cfc95..485298e8c4 100644 --- a/substrate/bin/node/executor/benches/bench.rs +++ b/substrate/bin/node/executor/benches/bench.rs @@ -25,7 +25,7 @@ use node_runtime::{ UncheckedExtrinsic, }; use node_testing::keyring::*; -use sc_executor::{Externalities, NativeExecutor, RuntimeInfo, WasmExecutionMethod}; +use sc_executor::{Externalities, NativeExecutor, RuntimeVersionOf, WasmExecutionMethod}; use sp_core::{ storage::well_known_keys, traits::{CodeExecutor, RuntimeCode}, diff --git a/substrate/client/api/src/call_executor.rs b/substrate/client/api/src/call_executor.rs index a19df74326..22af495c06 100644 --- a/substrate/client/api/src/call_executor.rs +++ b/substrate/client/api/src/call_executor.rs @@ -19,7 +19,7 @@ //! A method call executor interface. use codec::{Decode, Encode}; -use sc_executor::{NativeVersion, RuntimeVersion}; +use sc_executor::RuntimeVersion; use sp_core::NativeOrEncoded; use sp_externalities::Extensions; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; @@ -106,7 +106,4 @@ pub trait CallExecutor { method: &str, call_data: &[u8], ) -> Result<(Vec, StorageProof), sp_blockchain::Error>; - - /// Get runtime version if supported. - fn native_runtime_version(&self) -> Option<&NativeVersion>; } diff --git a/substrate/client/executor/src/lib.rs b/substrate/client/executor/src/lib.rs index f4b972a86f..e4442960ea 100644 --- a/substrate/client/executor/src/lib.rs +++ b/substrate/client/executor/src/lib.rs @@ -51,11 +51,8 @@ pub use wasmi; pub use sc_executor_common::{error, sandbox}; -/// Provides runtime information. -pub trait RuntimeInfo { - /// Native runtime information. - fn native_version(&self) -> &NativeVersion; - +/// Extracts the runtime version of a given runtime code. +pub trait RuntimeVersionOf { /// Extract [`RuntimeVersion`](sp_version::RuntimeVersion) of the given `runtime_code`. fn runtime_version( &self, diff --git a/substrate/client/executor/src/native_executor.rs b/substrate/client/executor/src/native_executor.rs index 8222e00b17..51b9a404bb 100644 --- a/substrate/client/executor/src/native_executor.rs +++ b/substrate/client/executor/src/native_executor.rs @@ -19,7 +19,7 @@ use crate::{ error::{Error, Result}, wasm_runtime::{RuntimeCache, WasmExecutionMethod}, - RuntimeInfo, + RuntimeVersionOf, }; use std::{ @@ -45,7 +45,7 @@ use sp_core::{ }; use sp_externalities::ExternalitiesExt as _; use sp_tasks::new_async_externalities; -use sp_version::{NativeVersion, RuntimeVersion}; +use sp_version::{GetNativeVersion, NativeVersion, RuntimeVersion}; use sp_wasm_interface::{Function, HostFunctions}; /// Default num of pages for the heap @@ -269,6 +269,48 @@ impl sp_core::traits::ReadRuntimeVersion for WasmExecutor { } } +impl CodeExecutor for WasmExecutor { + type Error = Error; + + fn call< + R: Decode + Encode + PartialEq, + NC: FnOnce() -> result::Result> + UnwindSafe, + >( + &self, + ext: &mut dyn Externalities, + runtime_code: &RuntimeCode, + method: &str, + data: &[u8], + _use_native: bool, + _native_call: Option, + ) -> (Result>, bool) { + let result = self.with_instance( + runtime_code, + ext, + false, + |module, instance, _onchain_version, mut ext| { + with_externalities_safe(&mut **ext, move || { + preregister_builtin_ext(module.clone()); + instance.call_export(method, data).map(NativeOrEncoded::Encoded) + }) + }, + ); + (result, false) + } +} + +impl RuntimeVersionOf for WasmExecutor { + fn runtime_version( + &self, + ext: &mut dyn Externalities, + runtime_code: &RuntimeCode, + ) -> Result { + self.with_instance(runtime_code, ext, false, |_module, _instance, version, _ext| { + Ok(version.cloned().ok_or_else(|| Error::ApiError("Unknown version".into()))) + }) + } +} + /// A generic `CodeExecutor` implementation that uses a delegate to determine wasm code equivalence /// and dispatch to native code when possible, falling back on `WasmExecutor` when not. pub struct NativeExecutor { @@ -324,11 +366,7 @@ impl NativeExecutor { } } -impl RuntimeInfo for NativeExecutor { - fn native_version(&self) -> &NativeVersion { - &self.native_version - } - +impl RuntimeVersionOf for NativeExecutor { fn runtime_version( &self, ext: &mut dyn Externalities, @@ -341,6 +379,12 @@ impl RuntimeInfo for NativeExecutor { } } +impl GetNativeVersion for NativeExecutor { + fn native_version(&self) -> &NativeVersion { + &self.native_version + } +} + /// Helper inner struct to implement `RuntimeSpawn` extension. pub struct RuntimeInstanceSpawn { module: Arc, diff --git a/substrate/client/light/src/call_executor.rs b/substrate/client/light/src/call_executor.rs index 144e0cbf96..a0776131e4 100644 --- a/substrate/client/light/src/call_executor.rs +++ b/substrate/client/light/src/call_executor.rs @@ -44,7 +44,7 @@ use sp_blockchain::{Error as ClientError, Result as ClientResult}; use sc_client_api::{ backend::RemoteBackend, call_executor::CallExecutor, light::RemoteCallRequest, }; -use sc_executor::{NativeVersion, RuntimeVersion}; +use sc_executor::RuntimeVersion; /// Call executor that is able to execute calls only on genesis state. /// @@ -162,10 +162,6 @@ where Err(ClientError::NotAvailableOnLightClient) } } - - fn native_runtime_version(&self) -> Option<&NativeVersion> { - None - } } /// Check remote contextual execution proof using given backend. diff --git a/substrate/client/service/src/builder.rs b/substrate/client/service/src/builder.rs index 83c8e1d9d1..18f701d6f1 100644 --- a/substrate/client/service/src/builder.rs +++ b/substrate/client/service/src/builder.rs @@ -37,7 +37,7 @@ use sc_client_api::{ }; use sc_client_db::{Backend, DatabaseSettings}; use sc_consensus::import_queue::ImportQueue; -use sc_executor::{NativeExecutionDispatch, NativeExecutor, RuntimeInfo}; +use sc_executor::{NativeExecutionDispatch, NativeExecutor, RuntimeVersionOf}; use sc_keystore::LocalKeystore; use sc_network::{ block_request_handler::{self, BlockRequestHandler}, @@ -454,7 +454,7 @@ pub fn new_client( > where Block: BlockT, - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeVersionOf, { let executor = crate::client::LocalCallExecutor::new( backend.clone(), diff --git a/substrate/client/service/src/client/call_executor.rs b/substrate/client/service/src/client/call_executor.rs index 2fae972d34..0710c4ae87 100644 --- a/substrate/client/service/src/client/call_executor.rs +++ b/substrate/client/service/src/client/call_executor.rs @@ -19,7 +19,7 @@ use super::{client::ClientConfig, wasm_override::WasmOverride, wasm_substitutes::WasmSubstitutes}; use codec::{Decode, Encode}; use sc_client_api::{backend, call_executor::CallExecutor, HeaderBackend}; -use sc_executor::{NativeVersion, RuntimeInfo, RuntimeVersion}; +use sc_executor::{RuntimeVersion, RuntimeVersionOf}; use sp_api::{ProofRecorder, StorageTransactionCache}; use sp_core::{ traits::{CodeExecutor, RuntimeCode, SpawnNamed}, @@ -49,7 +49,7 @@ pub struct LocalCallExecutor { impl LocalCallExecutor where - E: CodeExecutor + RuntimeInfo + Clone + 'static, + E: CodeExecutor + RuntimeVersionOf + Clone + 'static, B: backend::Backend, { /// Creates new instance of local call executor. @@ -137,7 +137,7 @@ where impl CallExecutor for LocalCallExecutor where B: backend::Backend, - E: CodeExecutor + RuntimeInfo + Clone + 'static, + E: CodeExecutor + RuntimeVersionOf + Clone + 'static, Block: BlockT, { type Error = E::Error; @@ -333,25 +333,28 @@ where ) .map_err(Into::into) } +} - fn native_runtime_version(&self) -> Option<&NativeVersion> { - Some(self.executor.native_version()) +impl sp_version::GetRuntimeVersionAt for LocalCallExecutor +where + B: backend::Backend, + E: CodeExecutor + RuntimeVersionOf + Clone + 'static, + Block: BlockT, +{ + fn runtime_version(&self, at: &BlockId) -> Result { + CallExecutor::runtime_version(self, at).map_err(|e| format!("{:?}", e)) } } -impl sp_version::GetRuntimeVersion for LocalCallExecutor +impl sp_version::GetNativeVersion for LocalCallExecutor where B: backend::Backend, - E: CodeExecutor + RuntimeInfo + Clone + 'static, + E: CodeExecutor + sp_version::GetNativeVersion + Clone + 'static, Block: BlockT, { fn native_version(&self) -> &sp_version::NativeVersion { self.executor.native_version() } - - fn runtime_version(&self, at: &BlockId) -> Result { - CallExecutor::runtime_version(self, at).map_err(|e| format!("{:?}", e)) - } } #[cfg(test)] diff --git a/substrate/client/service/src/client/client.rs b/substrate/client/service/src/client/client.rs index 17fbe6988d..727d58dfa0 100644 --- a/substrate/client/service/src/client/client.rs +++ b/substrate/client/service/src/client/client.rs @@ -96,7 +96,7 @@ use std::{ use { super::call_executor::LocalCallExecutor, sc_client_api::in_mem, - sc_executor::RuntimeInfo, + sc_executor::RuntimeVersionOf, sp_core::traits::{CodeExecutor, SpawnNamed}, }; @@ -169,7 +169,7 @@ pub fn new_in_mem( Client, LocalCallExecutor, E>, Block, RA>, > where - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeVersionOf, S: BuildStorage, Block: BlockT, { @@ -227,7 +227,7 @@ pub fn new_with_backend( config: ClientConfig, ) -> sp_blockchain::Result, Block, RA>> where - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeVersionOf, S: BuildStorage, Block: BlockT, B: backend::LocalBackend + 'static, diff --git a/substrate/client/service/src/client/light.rs b/substrate/client/service/src/client/light.rs index 82fe17e685..7c13b98843 100644 --- a/substrate/client/service/src/client/light.rs +++ b/substrate/client/service/src/client/light.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use prometheus_endpoint::Registry; -use sc_executor::RuntimeInfo; +use sc_executor::RuntimeVersionOf; use sc_telemetry::TelemetryHandle; use sp_blockchain::Result as ClientResult; use sp_core::traits::{CodeExecutor, SpawnNamed}; @@ -59,7 +59,7 @@ pub fn new_light( where B: BlockT, S: BlockchainStorage + 'static, - E: CodeExecutor + RuntimeInfo + Clone + 'static, + E: CodeExecutor + RuntimeVersionOf + Clone + 'static, { let local_executor = LocalCallExecutor::new( backend.clone(), diff --git a/substrate/client/service/src/client/wasm_override.rs b/substrate/client/service/src/client/wasm_override.rs index 7abd04f2be..a04a48f9c4 100644 --- a/substrate/client/service/src/client/wasm_override.rs +++ b/substrate/client/service/src/client/wasm_override.rs @@ -35,7 +35,7 @@ //! A custom WASM blob will override on-chain WASM if the spec version matches. If it is //! required to overrides multiple runtimes, multiple WASM blobs matching each of the spec versions //! needed must be provided in the given directory. -use sc_executor::RuntimeInfo; +use sc_executor::RuntimeVersionOf; use sp_blockchain::Result; use sp_core::traits::{FetchRuntimeCode, RuntimeCode}; use sp_state_machine::BasicExternalities; @@ -112,7 +112,7 @@ pub struct WasmOverride { impl WasmOverride where - E: RuntimeInfo + Clone + 'static, + E: RuntimeVersionOf + Clone + 'static, { pub fn new

(path: P, executor: E) -> Result where @@ -192,7 +192,7 @@ where #[cfg(test)] pub fn dummy_overrides(executor: &E) -> WasmOverride where - E: RuntimeInfo + Clone + 'static, + E: RuntimeVersionOf + Clone + 'static, { let mut overrides = HashMap::new(); overrides.insert(0, WasmBlob::new(vec![0, 0, 0, 0, 0, 0, 0, 0])); diff --git a/substrate/client/service/src/client/wasm_substitutes.rs b/substrate/client/service/src/client/wasm_substitutes.rs index ac48059fc2..28975790e9 100644 --- a/substrate/client/service/src/client/wasm_substitutes.rs +++ b/substrate/client/service/src/client/wasm_substitutes.rs @@ -20,7 +20,7 @@ use parking_lot::RwLock; use sc_client_api::backend; -use sc_executor::RuntimeInfo; +use sc_executor::RuntimeVersionOf; use sp_blockchain::{HeaderBackend, Result}; use sp_core::traits::{FetchRuntimeCode, RuntimeCode}; use sp_runtime::{ @@ -139,7 +139,7 @@ impl Clone for WasmSubstitutes WasmSubstitutes where - Executor: RuntimeInfo + Clone + 'static, + Executor: RuntimeVersionOf + Clone + 'static, Backend: backend::Backend, Block: BlockT, { diff --git a/substrate/client/service/test/src/client/light.rs b/substrate/client/service/test/src/client/light.rs index 90f87670c0..da4363b881 100644 --- a/substrate/client/service/test/src/client/light.rs +++ b/substrate/client/service/test/src/client/light.rs @@ -30,7 +30,7 @@ use sc_client_api::{ RemoteBodyRequest, RemoteCallRequest, RemoteChangesRequest, RemoteHeaderRequest, RemoteReadChildRequest, RemoteReadRequest, Storage, StorageProof, StorageProvider, }; -use sc_executor::{NativeExecutor, NativeVersion, RuntimeVersion, WasmExecutionMethod}; +use sc_executor::{NativeExecutor, RuntimeVersion, WasmExecutionMethod}; use sc_light::{ backend::{Backend, GenesisOrUnavailableState}, blockchain::{Blockchain, BlockchainCache}, @@ -256,10 +256,6 @@ impl CallExecutor for DummyCallExecutor { ) -> Result<(Vec, StorageProof), ClientError> { unreachable!() } - - fn native_runtime_version(&self) -> Option<&NativeVersion> { - unreachable!() - } } fn local_executor() -> NativeExecutor { diff --git a/substrate/primitives/consensus/common/src/lib.rs b/substrate/primitives/consensus/common/src/lib.rs index c72024e112..d7979baf47 100644 --- a/substrate/primitives/consensus/common/src/lib.rs +++ b/substrate/primitives/consensus/common/src/lib.rs @@ -294,8 +294,8 @@ impl CanAuthorWithNativeVersion { } } -impl, Block: BlockT> CanAuthorWith - for CanAuthorWithNativeVersion +impl + sp_version::GetNativeVersion, Block: BlockT> + CanAuthorWith for CanAuthorWithNativeVersion { fn can_author_with(&self, at: &BlockId) -> Result<(), String> { match self.0.runtime_version(at) { diff --git a/substrate/primitives/version/src/lib.rs b/substrate/primitives/version/src/lib.rs index da2cb342d2..c76fb44a2c 100644 --- a/substrate/primitives/version/src/lib.rs +++ b/substrate/primitives/version/src/lib.rs @@ -251,27 +251,36 @@ impl NativeVersion { } } -/// Something that can provide the runtime version at a given block and the native runtime version. #[cfg(feature = "std")] -pub trait GetRuntimeVersion { +/// Returns the version of the native runtime. +pub trait GetNativeVersion { /// Returns the version of the native runtime. fn native_version(&self) -> &NativeVersion; +} +/// Something that can provide the runtime version at a given block. +#[cfg(feature = "std")] +pub trait GetRuntimeVersionAt { /// Returns the version of runtime at the given block. fn runtime_version(&self, at: &BlockId) -> Result; } #[cfg(feature = "std")] -impl, Block: BlockT> GetRuntimeVersion for std::sync::Arc { - fn native_version(&self) -> &NativeVersion { - (&**self).native_version() - } - +impl, Block: BlockT> GetRuntimeVersionAt + for std::sync::Arc +{ fn runtime_version(&self, at: &BlockId) -> Result { (&**self).runtime_version(at) } } +#[cfg(feature = "std")] +impl GetNativeVersion for std::sync::Arc { + fn native_version(&self) -> &NativeVersion { + (&**self).native_version() + } +} + #[cfg(feature = "std")] mod apis_serialize { use super::*;