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
8 changes: 4 additions & 4 deletions core/client/src/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::Block as BlockT;
use state_machine::{self, OverlayedChanges, Ext,
CodeExecutor, ExecutionManager, native_when_possible};
use executor::{RuntimeVersion, RuntimeInfo};
use executor::{RuntimeVersion, RuntimeInfo, NativeVersion};
use hash_db::Hasher;
use trie::MemoryDB;
use codec::Decode;
Expand Down Expand Up @@ -89,7 +89,7 @@ where
) -> Result<(Vec<u8>, Vec<Vec<u8>>), error::Error>;

/// Get runtime version if supported.
fn native_runtime_version(&self) -> Option<RuntimeVersion>;
fn native_runtime_version(&self) -> Option<&NativeVersion>;
}

/// Call executor that executes methods locally, querying all required
Expand Down Expand Up @@ -194,7 +194,7 @@ where
.map_err(Into::into)
}

fn native_runtime_version(&self) -> Option<RuntimeVersion> {
<E as RuntimeInfo>::NATIVE_VERSION
fn native_runtime_version(&self) -> Option<&NativeVersion> {
Some(self.executor.native_version())
}
}
4 changes: 2 additions & 2 deletions core/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,8 +790,8 @@ impl<B, E, Block> bft::Authorities<Block> for Client<B, E, Block>
let native_version: Result<_, bft::Error> = self.executor.native_runtime_version()
.ok_or_else(|| bft::ErrorKind::NativeRuntimeMissing.into());
let native_version = native_version?;
if !on_chain_version.can_author_with(&native_version) {
return Err(bft::ErrorKind::IncompatibleAuthoringRuntime(on_chain_version, native_version).into())
if !native_version.can_author_with(&on_chain_version) {
return Err(bft::ErrorKind::IncompatibleAuthoringRuntime(on_chain_version, native_version.runtime_version.clone()).into())
}
self.authorities_at(at).map_err(|_| {
let descriptor = format!("{:?}", at);
Expand Down
2 changes: 1 addition & 1 deletion core/client/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ mod tests {
use test_client::runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest, Extrinsic};
use primitives::{Blake2Hasher, ed25519::{Public, Pair}};

native_executor_instance!(Executor, test_client::runtime::api::dispatch, test_client::runtime::VERSION, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
native_executor_instance!(Executor, test_client::runtime::api::dispatch, test_client::runtime::native_version, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));

fn executor() -> ::executor::NativeExecutor<Executor> {
NativeExecutionDispatch::new()
Expand Down
4 changes: 2 additions & 2 deletions core/client/src/light/call_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use blockchain::Backend as ChainBackend;
use call_executor::{CallExecutor, CallResult};
use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult};
use light::fetcher::{Fetcher, RemoteCallRequest};
use executor::RuntimeVersion;
use executor::{RuntimeVersion, NativeVersion};
use codec::Decode;
use heapsize::HeapSizeOf;
use trie::MemoryDB;
Expand Down Expand Up @@ -118,7 +118,7 @@ where
Err(ClientErrorKind::NotAvailableOnLightClient.into())
}

fn native_runtime_version(&self) -> Option<RuntimeVersion> {
fn native_runtime_version(&self) -> Option<&NativeVersion> {
None
}
}
Expand Down
9 changes: 5 additions & 4 deletions core/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ extern crate parking_lot;
extern crate twox_hash;
extern crate hash_db;

#[macro_use] extern crate log;
#[macro_use]
extern crate log;

#[macro_use]
extern crate lazy_static;
Expand Down Expand Up @@ -75,14 +76,14 @@ pub mod error;
pub use wasm_executor::WasmExecutor;
pub use native_executor::{with_native_environment, NativeExecutor, NativeExecutionDispatch};
pub use state_machine::Externalities;
pub use runtime_version::RuntimeVersion;
pub use runtime_version::{RuntimeVersion, NativeVersion};
pub use codec::Codec;
use primitives::Blake2Hasher;

/// Provides runtime information.
pub trait RuntimeInfo {
/// Native runtime information if any.
const NATIVE_VERSION: Option<RuntimeVersion>;
/// Native runtime information.
fn native_version(&self) -> &NativeVersion;

/// Extract RuntimeVersion of given :code block
fn runtime_version<E: Externalities<Blake2Hasher>> (
Expand Down
29 changes: 18 additions & 11 deletions core/executor/src/native_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use error::{Error, ErrorKind, Result};
use state_machine::{CodeExecutor, Externalities};
use wasm_executor::WasmExecutor;
use wasmi::Module as WasmModule;
use runtime_version::RuntimeVersion;
use runtime_version::{NativeVersion, RuntimeVersion};
use std::collections::HashMap;
use codec::Decode;
use primitives::hashing::blake2_256;
Expand Down Expand Up @@ -106,13 +106,11 @@ pub trait NativeExecutionDispatch: Send + Sync {
// fn dispatch<H: hash_db::Hasher>(ext: &mut Externalities<H>, method: &str, data: &[u8]) -> Result<Vec<u8>>;
fn dispatch(ext: &mut Externalities<Blake2Hasher>, method: &str, data: &[u8]) -> Result<Vec<u8>>;

/// Get native runtime version.
const VERSION: RuntimeVersion;
/// Provide native runtime version.
fn native_version() -> NativeVersion;

/// Construct corresponding `NativeExecutor`
fn new() -> NativeExecutor<Self> where Self: Sized {
NativeExecutor::new()
}
fn new() -> NativeExecutor<Self> where Self: Sized;
}

/// A generic `CodeExecutor` implementation that uses a delegate to determine wasm code equivalence
Expand All @@ -123,6 +121,8 @@ pub struct NativeExecutor<D: NativeExecutionDispatch> {
_dummy: ::std::marker::PhantomData<D>,
/// The fallback executor in case native isn't available.
fallback: WasmExecutor,
/// Native runtime version info.
native_version: NativeVersion,
}

impl<D: NativeExecutionDispatch> NativeExecutor<D> {
Expand All @@ -131,6 +131,7 @@ impl<D: NativeExecutionDispatch> NativeExecutor<D> {
NativeExecutor {
_dummy: Default::default(),
fallback: WasmExecutor::new(),
native_version: D::native_version(),
}
}
}
Expand All @@ -140,12 +141,15 @@ impl<D: NativeExecutionDispatch> Clone for NativeExecutor<D> {
NativeExecutor {
_dummy: Default::default(),
fallback: self.fallback.clone(),
native_version: D::native_version(),
}
}
}

impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
const NATIVE_VERSION: Option<RuntimeVersion> = Some(D::VERSION);
fn native_version(&self) -> &NativeVersion {
&self.native_version
}

fn runtime_version<E: Externalities<Blake2Hasher>>(
&self,
Expand Down Expand Up @@ -174,16 +178,16 @@ impl<D: NativeExecutionDispatch> CodeExecutor<Blake2Hasher> for NativeExecutor<D
Ok((module, onchain_version)) => (module, onchain_version),
Err(_) => return (Err(ErrorKind::InvalidCode(code.into()).into()), false),
};
match (use_native, onchain_version.as_ref().map_or(false, |v| v.can_call_with(&D::VERSION))) {
match (use_native, onchain_version.as_ref().map_or(false, |v| v.can_call_with(&self.native_version.runtime_version))) {
(_, false) => {
trace!(target: "executor", "Request for native execution failed (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
trace!(target: "executor", "Request for native execution failed (native: {}, chain: {})", self.native_version.runtime_version, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
(self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false)
}
(false, _) => {
(self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false)
}
_ => {
trace!(target: "executor", "Request for native execution succeeded (native: {}, chain: {})", D::VERSION, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
trace!(target: "executor", "Request for native execution succeeded (native: {}, chain: {})", self.native_version.runtime_version, onchain_version.as_ref().map_or_else(||"<None>".into(), |v| format!("{}", v)));
(D::dispatch(ext, method, data), true)
}
}
Expand All @@ -205,7 +209,6 @@ macro_rules! native_executor_instance {
// TODO: this is not so great – I think I should go back to have dispatch take a type param and modify this macro to accept a type param and then pass it in from the test-client instead
use primitives::Blake2Hasher as _Blake2Hasher;
impl $crate::NativeExecutionDispatch for $name {
const VERSION: $crate::RuntimeVersion = $version;
fn native_equivalent() -> &'static [u8] {
// WARNING!!! This assumes that the runtime was built *before* the main project. Until we
// get a proper build script, this must be strictly adhered to or things will go wrong.
Expand All @@ -216,6 +219,10 @@ macro_rules! native_executor_instance {
.ok_or_else(|| $crate::error::ErrorKind::MethodNotFound(method.to_owned()).into())
}

fn native_version() -> $crate::NativeVersion {
$version()
}

fn new() -> $crate::NativeExecutor<$name> {
$crate::NativeExecutor::new()
}
Expand Down
27 changes: 21 additions & 6 deletions core/sr-version/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ extern crate parity_codec as codec;

#[cfg(feature = "std")]
use std::fmt;
#[cfg(feature = "std")]
use std::collections::HashSet;

#[cfg(feature = "std")]
pub type VersionString = ::std::borrow::Cow<'static, str>;
Expand Down Expand Up @@ -129,14 +131,27 @@ impl RuntimeVersion {
self.authoring_version == other.authoring_version
}

/// Check if this version matches other version for authoring blocks.
pub fn can_author_with(&self, other: &RuntimeVersion) -> bool {
self.authoring_version == other.authoring_version &&
self.spec_name == other.spec_name
}

/// Check if this version supports a particular API.
pub fn has_api(&self, api: ApiId, version: u32) -> bool {
self.apis.iter().any(|&(ref s, v)| &api == s && version == v)
}
}

#[cfg(feature = "std")]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct NativeVersion {
/// Basic runtime version info.
pub runtime_version: RuntimeVersion,
/// Authoring runtimes that this native runtime supports.
pub can_author_with: HashSet<u32>,
}

#[cfg(feature = "std")]
impl NativeVersion {
/// Check if this version matches other version for authoring blocks.
pub fn can_author_with(&self, other: &RuntimeVersion) -> bool {
self.runtime_version.spec_name == other.spec_name &&
(self.runtime_version.authoring_version == other.authoring_version ||
self.can_author_with.contains(&other.authoring_version))
}
}
2 changes: 1 addition & 1 deletion core/test-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ mod local_executor {
#![allow(missing_docs)]
use super::runtime;
// TODO: change the macro and pass in the `BlakeHasher` that dispatch needs from here instead
native_executor_instance!(pub LocalExecutor, runtime::api::dispatch, runtime::VERSION, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
native_executor_instance!(pub LocalExecutor, runtime::api::dispatch, runtime::native_version, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
}

/// Native executor used for tests.
Expand Down
11 changes: 11 additions & 0 deletions core/test-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ use runtime_primitives::traits::{BlindCheckable, BlakeTwo256};
use runtime_primitives::Ed25519Signature;
use runtime_version::RuntimeVersion;
pub use primitives::hash::H256;
#[cfg(any(feature = "std", test))]
use runtime_version::NativeVersion;

/// Test runtime version.
pub const VERSION: RuntimeVersion = RuntimeVersion {
Expand All @@ -74,6 +76,15 @@ fn version() -> RuntimeVersion {
VERSION
}

/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
NativeVersion {
runtime_version: VERSION,
can_author_with: Default::default(),
}
}

/// Calls in transactions.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
Expand Down
2 changes: 1 addition & 1 deletion node/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ extern crate substrate_trie as trie;
#[cfg(test)] #[macro_use] extern crate hex_literal;

pub use substrate_executor::NativeExecutor;
native_executor_instance!(pub Executor, node_runtime::api::dispatch, node_runtime::VERSION, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"));
native_executor_instance!(pub Executor, node_runtime::api::dispatch, node_runtime::native_version, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"));

#[cfg(test)]
mod tests {
Expand Down
11 changes: 11 additions & 0 deletions node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ use runtime_primitives::generic;
use runtime_primitives::traits::{Convert, BlakeTwo256, DigestItem};
use version::{RuntimeVersion, ApiId};
use council::{motions as council_motions, voting as council_voting};
#[cfg(any(feature = "std", test))]
use version::NativeVersion;

#[cfg(any(feature = "std", test))]
pub use runtime_primitives::BuildStorage;
Expand All @@ -94,6 +96,15 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
apis: apis_vec!([(INHERENT, 1), (VALIDATX, 1)]),
};

/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
NativeVersion {
runtime_version: VERSION,
can_author_with: Default::default(),
}
}

impl system::Trait for Runtime {
type Origin = Origin;
type Index = Index;
Expand Down