Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/node/executor/benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
5 changes: 1 addition & 4 deletions client/api/src/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -106,7 +106,4 @@ pub trait CallExecutor<B: BlockT> {
method: &str,
call_data: &[u8],
) -> Result<(Vec<u8>, StorageProof), sp_blockchain::Error>;

/// Get runtime version if supported.
fn native_runtime_version(&self) -> Option<&NativeVersion>;
}
7 changes: 2 additions & 5 deletions client/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
58 changes: 51 additions & 7 deletions client/executor/src/native_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use crate::{
error::{Error, Result},
wasm_runtime::{RuntimeCache, WasmExecutionMethod},
RuntimeInfo,
RuntimeVersionOf,
};

use std::{
Expand All @@ -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
Expand Down Expand Up @@ -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<R, Box<dyn std::error::Error + Send + Sync>> + UnwindSafe,
>(
&self,
ext: &mut dyn Externalities,
runtime_code: &RuntimeCode,
method: &str,
data: &[u8],
_use_native: bool,
Copy link
Contributor

@gilescope gilescope Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if use_native is true then panic? (or log a warning perhaps?)

_native_call: Option<NC>,
) -> (Result<NativeOrEncoded<R>>, 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<RuntimeVersion> {
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<D> {
Expand Down Expand Up @@ -324,11 +366,7 @@ impl<D: NativeExecutionDispatch> NativeExecutor<D> {
}
}

impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
fn native_version(&self) -> &NativeVersion {
&self.native_version
}

impl<D: NativeExecutionDispatch> RuntimeVersionOf for NativeExecutor<D> {
fn runtime_version(
&self,
ext: &mut dyn Externalities,
Expand All @@ -341,6 +379,12 @@ impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
}
}

impl<D: NativeExecutionDispatch> GetNativeVersion for NativeExecutor<D> {
fn native_version(&self) -> &NativeVersion {
&self.native_version
}
}

/// Helper inner struct to implement `RuntimeSpawn` extension.
pub struct RuntimeInstanceSpawn {
module: Arc<dyn WasmModule>,
Expand Down
6 changes: 1 addition & 5 deletions client/light/src/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -162,10 +162,6 @@ where
Err(ClientError::NotAvailableOnLightClient)
}
}

fn native_runtime_version(&self) -> Option<&NativeVersion> {
None
}
}

/// Check remote contextual execution proof using given backend.
Expand Down
4 changes: 2 additions & 2 deletions client/service/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -454,7 +454,7 @@ pub fn new_client<E, Block, RA>(
>
where
Block: BlockT,
E: CodeExecutor + RuntimeInfo,
E: CodeExecutor + RuntimeVersionOf,
{
let executor = crate::client::LocalCallExecutor::new(
backend.clone(),
Expand Down
25 changes: 14 additions & 11 deletions client/service/src/client/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -49,7 +49,7 @@ pub struct LocalCallExecutor<Block: BlockT, B, E> {

impl<Block: BlockT, B, E> LocalCallExecutor<Block, B, E>
where
E: CodeExecutor + RuntimeInfo + Clone + 'static,
E: CodeExecutor + RuntimeVersionOf + Clone + 'static,
B: backend::Backend<Block>,
{
/// Creates new instance of local call executor.
Expand Down Expand Up @@ -137,7 +137,7 @@ where
impl<B, E, Block> CallExecutor<Block> for LocalCallExecutor<Block, B, E>
where
B: backend::Backend<Block>,
E: CodeExecutor + RuntimeInfo + Clone + 'static,
E: CodeExecutor + RuntimeVersionOf + Clone + 'static,
Block: BlockT,
{
type Error = E::Error;
Expand Down Expand Up @@ -333,25 +333,28 @@ where
)
.map_err(Into::into)
}
}

fn native_runtime_version(&self) -> Option<&NativeVersion> {
Some(self.executor.native_version())
impl<Block, B, E> sp_version::GetRuntimeVersionAt<Block> for LocalCallExecutor<Block, B, E>
where
B: backend::Backend<Block>,
E: CodeExecutor + RuntimeVersionOf + Clone + 'static,
Block: BlockT,
{
fn runtime_version(&self, at: &BlockId<Block>) -> Result<sp_version::RuntimeVersion, String> {
CallExecutor::runtime_version(self, at).map_err(|e| format!("{:?}", e))
}
}

impl<Block, B, E> sp_version::GetRuntimeVersion<Block> for LocalCallExecutor<Block, B, E>
impl<Block, B, E> sp_version::GetNativeVersion for LocalCallExecutor<Block, B, E>
where
B: backend::Backend<Block>,
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<Block>) -> Result<sp_version::RuntimeVersion, String> {
CallExecutor::runtime_version(self, at).map_err(|e| format!("{:?}", e))
}
}

#[cfg(test)]
Expand Down
6 changes: 3 additions & 3 deletions client/service/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};

Expand Down Expand Up @@ -169,7 +169,7 @@ pub fn new_in_mem<E, Block, S, RA>(
Client<in_mem::Backend<Block>, LocalCallExecutor<Block, in_mem::Backend<Block>, E>, Block, RA>,
>
where
E: CodeExecutor + RuntimeInfo,
E: CodeExecutor + RuntimeVersionOf,
S: BuildStorage,
Block: BlockT,
{
Expand Down Expand Up @@ -227,7 +227,7 @@ pub fn new_with_backend<B, E, Block, S, RA>(
config: ClientConfig<Block>,
) -> sp_blockchain::Result<Client<B, LocalCallExecutor<Block, B, E>, Block, RA>>
where
E: CodeExecutor + RuntimeInfo,
E: CodeExecutor + RuntimeVersionOf,
S: BuildStorage,
Block: BlockT,
B: backend::LocalBackend<Block> + 'static,
Expand Down
4 changes: 2 additions & 2 deletions client/service/src/client/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -59,7 +59,7 @@ pub fn new_light<B, S, RA, E>(
where
B: BlockT,
S: BlockchainStorage<B> + 'static,
E: CodeExecutor + RuntimeInfo + Clone + 'static,
E: CodeExecutor + RuntimeVersionOf + Clone + 'static,
{
let local_executor = LocalCallExecutor::new(
backend.clone(),
Expand Down
6 changes: 3 additions & 3 deletions client/service/src/client/wasm_override.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -112,7 +112,7 @@ pub struct WasmOverride<E> {

impl<E> WasmOverride<E>
where
E: RuntimeInfo + Clone + 'static,
E: RuntimeVersionOf + Clone + 'static,
{
pub fn new<P>(path: P, executor: E) -> Result<Self>
where
Expand Down Expand Up @@ -192,7 +192,7 @@ where
#[cfg(test)]
pub fn dummy_overrides<E>(executor: &E) -> WasmOverride<E>
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]));
Expand Down
4 changes: 2 additions & 2 deletions client/service/src/client/wasm_substitutes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -139,7 +139,7 @@ impl<Block: BlockT, Executor: Clone, Backend> Clone for WasmSubstitutes<Block, E

impl<Executor, Backend, Block> WasmSubstitutes<Block, Executor, Backend>
where
Executor: RuntimeInfo + Clone + 'static,
Executor: RuntimeVersionOf + Clone + 'static,
Backend: backend::Backend<Block>,
Block: BlockT,
{
Expand Down
6 changes: 1 addition & 5 deletions client/service/test/src/client/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -256,10 +256,6 @@ impl CallExecutor<Block> for DummyCallExecutor {
) -> Result<(Vec<u8>, StorageProof), ClientError> {
unreachable!()
}

fn native_runtime_version(&self) -> Option<&NativeVersion> {
unreachable!()
}
}

fn local_executor() -> NativeExecutor<substrate_test_runtime_client::LocalExecutor> {
Expand Down
4 changes: 2 additions & 2 deletions primitives/consensus/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ impl<T> CanAuthorWithNativeVersion<T> {
}
}

impl<T: sp_version::GetRuntimeVersion<Block>, Block: BlockT> CanAuthorWith<Block>
for CanAuthorWithNativeVersion<T>
impl<T: sp_version::GetRuntimeVersionAt<Block> + sp_version::GetNativeVersion, Block: BlockT>
CanAuthorWith<Block> for CanAuthorWithNativeVersion<T>
{
fn can_author_with(&self, at: &BlockId<Block>) -> Result<(), String> {
match self.0.runtime_version(at) {
Expand Down
23 changes: 16 additions & 7 deletions primitives/version/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,27 +246,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<Block: BlockT> {
/// 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<Block: BlockT> {
/// Returns the version of runtime at the given block.
fn runtime_version(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, String>;
}

#[cfg(feature = "std")]
impl<T: GetRuntimeVersion<Block>, Block: BlockT> GetRuntimeVersion<Block> for std::sync::Arc<T> {
fn native_version(&self) -> &NativeVersion {
(&**self).native_version()
}

impl<T: GetRuntimeVersionAt<Block>, Block: BlockT> GetRuntimeVersionAt<Block>
for std::sync::Arc<T>
{
fn runtime_version(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, String> {
(&**self).runtime_version(at)
}
}

#[cfg(feature = "std")]
impl<T: GetNativeVersion> GetNativeVersion for std::sync::Arc<T> {
fn native_version(&self) -> &NativeVersion {
(&**self).native_version()
}
}

#[cfg(feature = "std")]
mod apis_serialize {
use super::*;
Expand Down