diff --git a/Cargo.lock b/Cargo.lock index 2cd20023e50d4..4b21f2c3a5cb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -386,6 +386,7 @@ dependencies = [ "substrate-runtime-support 0.1.0", "substrate-runtime-system 0.1.0", "substrate-runtime-timestamp 0.1.0", + "substrate-runtime-version 0.1.0", ] [[package]] @@ -1529,6 +1530,7 @@ dependencies = [ "substrate-runtime-support 0.1.0", "substrate-runtime-system 0.1.0", "substrate-runtime-timestamp 0.1.0", + "substrate-runtime-version 0.1.0", "substrate-serializer 0.1.0", ] @@ -2135,6 +2137,7 @@ dependencies = [ "patricia-trie 0.1.0 (git+https://github.com/paritytech/parity.git)", "substrate-client 0.1.0", "substrate-codec 0.1.0", + "substrate-executor 0.1.0", "substrate-primitives 0.1.0", "substrate-runtime-primitives 0.1.0", "substrate-runtime-support 0.1.0", @@ -2165,6 +2168,7 @@ dependencies = [ "substrate-codec 0.1.0", "substrate-primitives 0.1.0", "substrate-runtime-io 0.1.0", + "substrate-runtime-version 0.1.0", "substrate-serializer 0.1.0", "substrate-state-machine 0.1.0", "triehash 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2543,6 +2547,17 @@ dependencies = [ "substrate-runtime-system 0.1.0", ] +[[package]] +name = "substrate-runtime-version" +version = "0.1.0" +dependencies = [ + "serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", +] + [[package]] name = "substrate-serializer" version = "0.1.0" @@ -2623,6 +2638,7 @@ dependencies = [ "substrate-runtime-primitives 0.1.0", "substrate-runtime-std 0.1.0", "substrate-runtime-support 0.1.0", + "substrate-runtime-version 0.1.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4d730a0236e73..ba44a71bd30d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ members = [ "substrate/runtime/staking", "substrate/runtime/system", "substrate/runtime/timestamp", + "substrate/runtime/version", "substrate/serializer", "substrate/state-db", "substrate/state-machine", diff --git a/demo/executor/src/lib.rs b/demo/executor/src/lib.rs index e1d9a97161676..0b914b396c4ef 100644 --- a/demo/executor/src/lib.rs +++ b/demo/executor/src/lib.rs @@ -34,7 +34,7 @@ extern crate triehash; #[cfg(test)] extern crate substrate_runtime_system as system; #[cfg(test)] #[macro_use] extern crate hex_literal; -native_executor_instance!(pub Executor, demo_runtime::api::dispatch, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm")); +native_executor_instance!(pub Executor, demo_runtime::api::dispatch, demo_runtime::VERSION, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm")); #[cfg(test)] mod tests { diff --git a/demo/runtime/Cargo.toml b/demo/runtime/Cargo.toml index cb9988ffc9e01..e541dcb029e4c 100644 --- a/demo/runtime/Cargo.toml +++ b/demo/runtime/Cargo.toml @@ -25,6 +25,7 @@ substrate-runtime-session = { path = "../../substrate/runtime/session" } substrate-runtime-staking = { path = "../../substrate/runtime/staking" } substrate-runtime-system = { path = "../../substrate/runtime/system" } substrate-runtime-timestamp = { path = "../../substrate/runtime/timestamp" } +substrate-runtime-version = { path = "../../substrate/runtime/version" } demo-primitives = { path = "../primitives" } [features] @@ -44,6 +45,7 @@ std = [ "substrate-runtime-staking/std", "substrate-runtime-system/std", "substrate-runtime-timestamp/std", + "substrate-runtime-version/std", "demo-primitives/std", "serde_derive", "serde/std", diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index d6c943f065569..938bcbbfa2be3 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -43,12 +43,15 @@ extern crate substrate_runtime_session as session; extern crate substrate_runtime_staking as staking; extern crate substrate_runtime_system as system; extern crate substrate_runtime_timestamp as timestamp; +#[macro_use] +extern crate substrate_runtime_version as version; extern crate demo_primitives; use rstd::prelude::*; use demo_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature}; use runtime_primitives::generic; use runtime_primitives::traits::{Convert, HasPublicAux, BlakeTwo256}; +use version::RuntimeVersion; #[cfg(any(feature = "std", test))] pub use runtime_primitives::BuildStorage; @@ -59,6 +62,22 @@ pub use runtime_primitives::BuildStorage; /// Concrete runtime type used to parameterize the various modules. pub struct Concrete; +/// Runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: ver_str!("demo"), + impl_name: ver_str!("parity-demo"), + authoring_version: 0, + spec_version: 0, + impl_version: 0, +}; + +/// Version module for this concrete runtime. +pub type Version = version::Module; + +impl version::Trait for Concrete { + const VERSION: RuntimeVersion = VERSION; +} + impl HasPublicAux for Concrete { type PublicAux = AccountId; } @@ -189,6 +208,7 @@ impl_outer_config! { pub mod api { impl_stubs!( + version => |()| super::Version::version(), authorities => |()| super::Consensus::authorities(), initialise_block => |header| super::Executive::initialise_block(&header), apply_extrinsic => |extrinsic| super::Executive::apply_extrinsic(extrinsic), diff --git a/demo/runtime/wasm/Cargo.lock b/demo/runtime/wasm/Cargo.lock index 29919b2141c45..007ee64ed1806 100644 --- a/demo/runtime/wasm/Cargo.lock +++ b/demo/runtime/wasm/Cargo.lock @@ -137,6 +137,7 @@ dependencies = [ "substrate-runtime-support 0.1.0", "substrate-runtime-system 0.1.0", "substrate-runtime-timestamp 0.1.0", + "substrate-runtime-version 0.1.0", ] [[package]] @@ -972,6 +973,17 @@ dependencies = [ "substrate-runtime-system 0.1.0", ] +[[package]] +name = "substrate-runtime-version" +version = "0.1.0" +dependencies = [ + "serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", +] + [[package]] name = "substrate-state-machine" version = "0.1.0" diff --git a/demo/runtime/wasm/Cargo.toml b/demo/runtime/wasm/Cargo.toml index 32af7412f4b2c..8490777097eef 100644 --- a/demo/runtime/wasm/Cargo.toml +++ b/demo/runtime/wasm/Cargo.toml @@ -23,6 +23,7 @@ substrate-runtime-session = { path = "../../../substrate/runtime/session", defau substrate-runtime-staking = { path = "../../../substrate/runtime/staking", default-features = false } substrate-runtime-system = { path = "../../../substrate/runtime/system", default-features = false } substrate-runtime-timestamp = { path = "../../../substrate/runtime/timestamp", default-features = false } +substrate-runtime-version = { path = "../../../substrate/runtime/version", default-features = false } demo-primitives = { path = "../../primitives", default-features = false } [features] @@ -43,6 +44,7 @@ std = [ "substrate-runtime-staking/std", "substrate-runtime-system/std", "substrate-runtime-timestamp/std", + "substrate-runtime-version/std", "demo-primitives/std", ] diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm index 2cc100715c8ef..f466a1023391e 100644 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.compact.wasm differ diff --git a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm index dcd6e96a25afe..9685d89fa8496 100755 Binary files a/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm and b/demo/runtime/wasm/target/wasm32-unknown-unknown/release/demo_runtime.wasm differ diff --git a/polkadot/api/src/full.rs b/polkadot/api/src/full.rs index 6b3035e5daa3e..7c39bc3c6c42d 100644 --- a/polkadot/api/src/full.rs +++ b/polkadot/api/src/full.rs @@ -20,7 +20,7 @@ use client::backend::{Backend, LocalBackend}; use client::block_builder::BlockBuilder as ClientBlockBuilder; use client::{Client, LocalCallExecutor}; use polkadot_executor::Executor as LocalDispatch; -use substrate_executor::{NativeExecutionDispatch, NativeExecutor}; +use substrate_executor::NativeExecutor; use state_machine; use runtime::Address; @@ -28,23 +28,13 @@ use runtime_primitives::traits::AuxLookup; use primitives::{AccountId, Block, Header, BlockId, Hash, Index, SessionKey, Timestamp, UncheckedExtrinsic}; use primitives::parachain::{CandidateReceipt, DutyRoster, Id as ParaId}; -use {CheckedBlockId, BlockBuilder, PolkadotApi, LocalPolkadotApi, ErrorKind, Error, Result}; - -/// A checked block ID used for the substrate-client implementation of CheckedBlockId; -#[derive(Debug, Clone, Copy)] -pub struct CheckedId(pub(crate) BlockId); - -impl CheckedBlockId for CheckedId { - fn block_id(&self) -> &BlockId { - &self.0 - } -} +use {BlockBuilder, PolkadotApi, LocalPolkadotApi, ErrorKind, Error, Result}; // set up the necessary scaffolding to execute a set of calls to the runtime. // this creates a new block on top of the given ID and initialises it. macro_rules! with_runtime { ($client: ident, $at: expr, $exec: expr) => {{ - let parent = $at.block_id(); + let parent = $at; let header = Header { parent_hash: $client.block_hash_from_id(&parent)? .ok_or_else(|| ErrorKind::UnknownBlock(format!("{:?}", parent)))?, @@ -83,39 +73,29 @@ impl> BlockBuilder for ClientBlockBuilder> PolkadotApi for Client>, Block> where ::client::error::Error: From<<>::State as state_machine::backend::Backend>::Error> { - type CheckedBlockId = CheckedId; type BlockBuilder = ClientBlockBuilder>, Block>; - fn check_id(&self, id: BlockId) -> Result { - // bail if the code is not the same as the natively linked. - if self.code_at(&id.into())? != LocalDispatch::native_equivalent() { - bail!("This node is out of date. Block authoring may not work correctly. Bailing.") - } - - Ok(CheckedId(id)) - } - - fn session_keys(&self, at: &CheckedId) -> Result> { + fn session_keys(&self, at: &BlockId) -> Result> { with_runtime!(self, at, ::runtime::Consensus::authorities) } - fn validators(&self, at: &CheckedId) -> Result> { + fn validators(&self, at: &BlockId) -> Result> { with_runtime!(self, at, ::runtime::Session::validators) } - fn random_seed(&self, at: &CheckedId) -> Result { + fn random_seed(&self, at: &BlockId) -> Result { with_runtime!(self, at, ::runtime::System::random_seed) } - fn duty_roster(&self, at: &CheckedId) -> Result { + fn duty_roster(&self, at: &BlockId) -> Result { with_runtime!(self, at, ::runtime::Parachains::calculate_duty_roster) } - fn timestamp(&self, at: &CheckedId) -> Result { + fn timestamp(&self, at: &BlockId) -> Result { with_runtime!(self, at, ::runtime::Timestamp::get) } - fn evaluate_block(&self, at: &CheckedId, block: Block) -> Result { + fn evaluate_block(&self, at: &BlockId, block: Block) -> Result { use substrate_executor::error::ErrorKind as ExecErrorKind; use codec::Slicable; use runtime::Block as RuntimeBlock; @@ -136,28 +116,28 @@ impl> PolkadotApi for Client Result { + fn index(&self, at: &BlockId, account: AccountId) -> Result { with_runtime!(self, at, || ::runtime::System::account_nonce(account)) } - fn lookup(&self, at: &Self::CheckedBlockId, address: Address) -> Result> { + fn lookup(&self, at: &BlockId, address: Address) -> Result> { with_runtime!(self, at, || <::runtime::Staking as AuxLookup>::lookup(address).ok()) } - fn active_parachains(&self, at: &CheckedId) -> Result> { + fn active_parachains(&self, at: &BlockId) -> Result> { with_runtime!(self, at, ::runtime::Parachains::active_parachains) } - fn parachain_code(&self, at: &CheckedId, parachain: ParaId) -> Result>> { + fn parachain_code(&self, at: &BlockId, parachain: ParaId) -> Result>> { with_runtime!(self, at, || ::runtime::Parachains::parachain_code(parachain)) } - fn parachain_head(&self, at: &CheckedId, parachain: ParaId) -> Result>> { + fn parachain_head(&self, at: &BlockId, parachain: ParaId) -> Result>> { with_runtime!(self, at, || ::runtime::Parachains::parachain_head(parachain)) } - fn build_block(&self, at: &CheckedId, timestamp: Timestamp, new_heads: Vec) -> Result { - let mut block_builder = self.new_block_at(at.block_id())?; + fn build_block(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec) -> Result { + let mut block_builder = self.new_block_at(at)?; for inherent in self.inherent_extrinsics(at, timestamp, new_heads)? { block_builder.push(inherent)?; } @@ -165,7 +145,7 @@ impl> PolkadotApi for Client) -> Result> { + fn inherent_extrinsics(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec) -> Result> { use codec::Slicable; with_runtime!(self, at, || { @@ -231,7 +211,7 @@ mod tests { #[test] fn gets_session_and_validator_keys() { let client = client(); - let id = client.check_id(BlockId::number(0)).unwrap(); + let id = BlockId::number(0); assert_eq!(client.session_keys(&id).unwrap(), session_keys()); assert_eq!(client.validators(&id).unwrap(), validators()); } @@ -240,7 +220,7 @@ mod tests { fn build_block_implicit_succeeds() { let client = client(); - let id = client.check_id(BlockId::number(0)).unwrap(); + let id = BlockId::number(0); let block_builder = client.build_block(&id, 1_000_000, Vec::new()).unwrap(); let block = block_builder.bake().unwrap(); @@ -252,10 +232,10 @@ mod tests { fn build_block_with_inherent_succeeds() { let client = client(); - let id = client.check_id(BlockId::number(0)).unwrap(); + let id = BlockId::number(0); let inherent = client.inherent_extrinsics(&id, 1_000_000, Vec::new()).unwrap(); - let mut block_builder = client.new_block_at(id.block_id()).unwrap(); + let mut block_builder = client.new_block_at(&id).unwrap(); for extrinsic in inherent { block_builder.push(extrinsic).unwrap(); } @@ -266,16 +246,11 @@ mod tests { assert!(block.header.extrinsics_root != Default::default()); } - #[test] - fn fails_to_check_id_for_unknown_block() { - assert!(client().check_id(BlockId::number(100)).is_err()); - } - #[test] fn gets_random_seed_with_genesis() { let client = client(); - let id = client.check_id(BlockId::number(0)).unwrap(); + let id = BlockId::number(0); assert!(client.random_seed(&id).is_ok()); } } diff --git a/polkadot/api/src/lib.rs b/polkadot/api/src/lib.rs index 81e3b024201e3..27bea18a0d0a3 100644 --- a/polkadot/api/src/lib.rs +++ b/polkadot/api/src/lib.rs @@ -77,12 +77,6 @@ impl From for Error { } } -/// A checked block identifier. -pub trait CheckedBlockId: Clone + 'static { - /// Yield the underlying block ID. - fn block_id(&self) -> &BlockId; -} - /// Build new blocks. pub trait BlockBuilder { /// Push an extrinsic onto the block. Fails if the extrinsic is invalid. @@ -96,57 +90,49 @@ pub trait BlockBuilder { /// /// All calls should fail when the exact runtime is unknown. pub trait PolkadotApi { - /// A checked block ID. Used to avoid redundancy of code check. - type CheckedBlockId: CheckedBlockId; /// The block builder for this API type. type BlockBuilder: BlockBuilder; - /// Check whether requests at the given block ID can be served. - /// - /// It should not be possible to instantiate this type without going - /// through this function. - fn check_id(&self, id: BlockId) -> Result; - /// Get session keys at a given block. - fn session_keys(&self, at: &Self::CheckedBlockId) -> Result>; + fn session_keys(&self, at: &BlockId) -> Result>; /// Get validators at a given block. - fn validators(&self, at: &Self::CheckedBlockId) -> Result>; + fn validators(&self, at: &BlockId) -> Result>; /// Get the value of the randomness beacon at a given block. - fn random_seed(&self, at: &Self::CheckedBlockId) -> Result; + fn random_seed(&self, at: &BlockId) -> Result; /// Get the authority duty roster at a block. - fn duty_roster(&self, at: &Self::CheckedBlockId) -> Result; + fn duty_roster(&self, at: &BlockId) -> Result; /// Get the timestamp registered at a block. - fn timestamp(&self, at: &Self::CheckedBlockId) -> Result; + fn timestamp(&self, at: &BlockId) -> Result; /// Get the nonce (né index) of an account at a block. - fn index(&self, at: &Self::CheckedBlockId, account: AccountId) -> Result; + fn index(&self, at: &BlockId, account: AccountId) -> Result; /// Get the account id of an address at a block. - fn lookup(&self, at: &Self::CheckedBlockId, address: Address) -> Result>; + fn lookup(&self, at: &BlockId, address: Address) -> Result>; /// Get the active parachains at a block. - fn active_parachains(&self, at: &Self::CheckedBlockId) -> Result>; + fn active_parachains(&self, at: &BlockId) -> Result>; /// Get the validation code of a parachain at a block. If the parachain is active, this will always return `Some`. - fn parachain_code(&self, at: &Self::CheckedBlockId, parachain: ParaId) -> Result>>; + fn parachain_code(&self, at: &BlockId, parachain: ParaId) -> Result>>; /// Get the chain head of a parachain. If the parachain is active, this will always return `Some`. - fn parachain_head(&self, at: &Self::CheckedBlockId, parachain: ParaId) -> Result>>; + fn parachain_head(&self, at: &BlockId, parachain: ParaId) -> Result>>; /// Evaluate a block. Returns true if the block is good, false if it is known to be bad, /// and an error if we can't evaluate for some reason. - fn evaluate_block(&self, at: &Self::CheckedBlockId, block: Block) -> Result; + fn evaluate_block(&self, at: &BlockId, block: Block) -> Result; /// Build a block on top of the given, with inherent extrinsics pre-pushed. - fn build_block(&self, at: &Self::CheckedBlockId, timestamp: Timestamp, new_heads: Vec) -> Result; + fn build_block(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec) -> Result; /// Attempt to produce the (encoded) inherent extrinsics for a block being built upon the given. /// This may vary by runtime and will fail if a runtime doesn't follow the same API. - fn inherent_extrinsics(&self, at: &Self::CheckedBlockId, timestamp: Timestamp, new_heads: Vec) -> Result>; + fn inherent_extrinsics(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec) -> Result>; } /// Mark for all Polkadot API implementations, that are making use of state data, stored locally. diff --git a/polkadot/api/src/light.rs b/polkadot/api/src/light.rs index 6a4f1f0322438..e20c1a245ec82 100644 --- a/polkadot/api/src/light.rs +++ b/polkadot/api/src/light.rs @@ -24,8 +24,7 @@ use state_machine; use primitives::{AccountId, Block, BlockId, Hash, Index, SessionKey, Timestamp, UncheckedExtrinsic}; use runtime::Address; use primitives::parachain::{CandidateReceipt, DutyRoster, Id as ParaId}; -use full::CheckedId; -use {PolkadotApi, BlockBuilder, RemotePolkadotApi, CheckedBlockId, Result, ErrorKind}; +use {PolkadotApi, BlockBuilder, RemotePolkadotApi, Result, ErrorKind}; /// Light block builder. TODO: make this work (efficiently) #[derive(Clone, Copy)] @@ -47,65 +46,60 @@ pub struct RemotePolkadotApiWrapper, E: CallExecutor>(p impl, E: CallExecutor> PolkadotApi for RemotePolkadotApiWrapper where ::client::error::Error: From<<>::State as state_machine::backend::Backend>::Error> { - type CheckedBlockId = CheckedId; type BlockBuilder = LightBlockBuilder; - fn check_id(&self, id: BlockId) -> Result { - Ok(CheckedId(id)) - } - - fn session_keys(&self, at: &CheckedId) -> Result> { - self.0.executor().call(at.block_id(), "authorities", &[]) + fn session_keys(&self, at: &BlockId) -> Result> { + self.0.executor().call(at, "authorities", &[]) .and_then(|r| Vec::::decode(&mut &r.return_data[..]) .ok_or("error decoding session keys".into())) .map_err(Into::into) } - fn validators(&self, _at: &CheckedId) -> Result> { + fn validators(&self, _at: &BlockId) -> Result> { Err(ErrorKind::UnknownRuntime.into()) } - fn random_seed(&self, _at: &Self::CheckedBlockId) -> Result { + fn random_seed(&self, _at: &BlockId) -> Result { Err(ErrorKind::UnknownRuntime.into()) } - fn duty_roster(&self, _at: &CheckedId) -> Result { + fn duty_roster(&self, _at: &BlockId) -> Result { Err(ErrorKind::UnknownRuntime.into()) } - fn timestamp(&self, _at: &CheckedId) -> Result { + fn timestamp(&self, _at: &BlockId) -> Result { Err(ErrorKind::UnknownRuntime.into()) } - fn evaluate_block(&self, _at: &CheckedId, _block: Block) -> Result { + fn evaluate_block(&self, _at: &BlockId, _block: Block) -> Result { Err(ErrorKind::UnknownRuntime.into()) } - fn index(&self, _at: &CheckedId, _account: AccountId) -> Result { + fn index(&self, _at: &BlockId, _account: AccountId) -> Result { Err(ErrorKind::UnknownRuntime.into()) } - fn lookup(&self, _at: &CheckedId, _address: Address) -> Result> { + fn lookup(&self, _at: &BlockId, _address: Address) -> Result> { Err(ErrorKind::UnknownRuntime.into()) } - fn active_parachains(&self, _at: &Self::CheckedBlockId) -> Result> { + fn active_parachains(&self, _at: &BlockId) -> Result> { Err(ErrorKind::UnknownRuntime.into()) } - fn parachain_code(&self, _at: &Self::CheckedBlockId, _parachain: ParaId) -> Result>> { + fn parachain_code(&self, _at: &BlockId, _parachain: ParaId) -> Result>> { Err(ErrorKind::UnknownRuntime.into()) } - fn parachain_head(&self, _at: &Self::CheckedBlockId, _parachain: ParaId) -> Result>> { + fn parachain_head(&self, _at: &BlockId, _parachain: ParaId) -> Result>> { Err(ErrorKind::UnknownRuntime.into()) } - fn build_block(&self, _at: &Self::CheckedBlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result { + fn build_block(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result { Err(ErrorKind::UnknownRuntime.into()) } - fn inherent_extrinsics(&self, _at: &Self::CheckedBlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result>> { + fn inherent_extrinsics(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result>> { Err(ErrorKind::UnknownRuntime.into()) } } diff --git a/polkadot/consensus/src/collation.rs b/polkadot/consensus/src/collation.rs index 3738ae900413a..f0b1f626c68e1 100644 --- a/polkadot/consensus/src/collation.rs +++ b/polkadot/consensus/src/collation.rs @@ -22,7 +22,7 @@ use std::sync::Arc; use polkadot_api::PolkadotApi; -use polkadot_primitives::{Hash, AccountId}; +use polkadot_primitives::{Hash, AccountId, BlockId}; use polkadot_primitives::parachain::{Id as ParaId, Chain, BlockData, Extrinsic, CandidateReceipt}; use futures::prelude::*; @@ -57,7 +57,7 @@ pub trait Collators: Clone { pub struct CollationFetch { parachain: Option, relay_parent_hash: Hash, - relay_parent: P::CheckedBlockId, + relay_parent: BlockId, collators: C, live_fetch: Option<::Future>, client: Arc

, @@ -65,7 +65,7 @@ pub struct CollationFetch { impl CollationFetch { /// Create a new collation fetcher for the given chain. - pub fn new(parachain: Chain, relay_parent: P::CheckedBlockId, relay_parent_hash: Hash, collators: C, client: Arc

) -> Self { + pub fn new(parachain: Chain, relay_parent: BlockId, relay_parent_hash: Hash, collators: C, client: Arc

) -> Self { CollationFetch { relay_parent_hash, relay_parent, @@ -145,7 +145,7 @@ error_chain! { } /// Check whether a given collation is valid. Returns `Ok` on success, error otherwise. -pub fn validate_collation(client: &P, relay_parent: &P::CheckedBlockId, collation: &Collation) -> Result<(), Error> { +pub fn validate_collation(client: &P, relay_parent: &BlockId, collation: &Collation) -> Result<(), Error> { use parachain::{self, ValidationParams}; let para_id = collation.receipt.parachain_index; diff --git a/polkadot/consensus/src/lib.rs b/polkadot/consensus/src/lib.rs index 4fb8fc4090fdd..c75d8ac6ee6b7 100644 --- a/polkadot/consensus/src/lib.rs +++ b/polkadot/consensus/src/lib.rs @@ -240,7 +240,6 @@ pub struct ProposerFactory { impl bft::ProposerFactory for ProposerFactory where C: PolkadotApi + Send + Sync, - C::CheckedBlockId: Sync, N: Network, P: Collators, { @@ -254,9 +253,9 @@ impl bft::ProposerFactory for ProposerFactory let parent_hash = parent_header.blake2_256().into(); - let checked_id = self.client.check_id(BlockId::hash(parent_hash))?; - let duty_roster = self.client.duty_roster(&checked_id)?; - let random_seed = self.client.random_seed(&checked_id)?; + let id = BlockId::hash(parent_hash); + let duty_roster = self.client.duty_roster(&id)?; + let random_seed = self.client.random_seed(&id)?; let (group_info, local_duty) = make_group_info( duty_roster, @@ -264,7 +263,7 @@ impl bft::ProposerFactory for ProposerFactory sign_with.public().into(), )?; - let active_parachains = self.client.active_parachains(&checked_id)?; + let active_parachains = self.client.active_parachains(&id)?; let n_parachains = active_parachains.len(); let table = Arc::new(SharedTable::new(group_info, sign_with.clone(), parent_hash)); @@ -291,7 +290,7 @@ impl bft::ProposerFactory for ProposerFactory local_duty, local_key: sign_with, parent_hash, - parent_id: checked_id, + parent_id: id, parent_number: parent_header.number, random_seed, router, @@ -315,7 +314,7 @@ pub struct Proposer { local_duty: LocalDuty, local_key: Arc, parent_hash: Hash, - parent_id: C::CheckedBlockId, + parent_id: BlockId, parent_number: BlockNumber, random_seed: Hash, router: R, @@ -326,7 +325,6 @@ pub struct Proposer { impl bft::Proposer for Proposer where C: PolkadotApi + Send + Sync, - C::CheckedBlockId: Sync, R: TableRouter, P: Collators, { @@ -621,7 +619,7 @@ impl ProposalTiming { pub struct CreateProposal { parent_hash: Hash, parent_number: BlockNumber, - parent_id: C::CheckedBlockId, + parent_id: BlockId, client: Arc, transaction_pool: Arc>, collation: CollationFetch, diff --git a/polkadot/consensus/src/service.rs b/polkadot/consensus/src/service.rs index f761c51d019f0..494e7858096e8 100644 --- a/polkadot/consensus/src/service.rs +++ b/polkadot/consensus/src/service.rs @@ -242,7 +242,6 @@ impl Service { where A: LocalPolkadotApi + Send + Sync + 'static, C: BlockchainEvents + ChainHead + bft::BlockImport + bft::Authorities + Send + Sync + 'static, - A::CheckedBlockId: Sync, { let (signal, exit) = ::exit_future::signal(); let thread = thread::spawn(move || { diff --git a/polkadot/executor/src/lib.rs b/polkadot/executor/src/lib.rs index be44d8afbae9e..82cd5cd47851c 100644 --- a/polkadot/executor/src/lib.rs +++ b/polkadot/executor/src/lib.rs @@ -20,4 +20,4 @@ extern crate polkadot_runtime; #[macro_use] extern crate substrate_executor; -native_executor_instance!(pub Executor, polkadot_runtime::api::dispatch, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm")); +native_executor_instance!(pub Executor, polkadot_runtime::api::dispatch, polkadot_runtime::VERSION, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm")); diff --git a/polkadot/runtime/Cargo.toml b/polkadot/runtime/Cargo.toml index 9ac1f50175300..40685956016c9 100644 --- a/polkadot/runtime/Cargo.toml +++ b/polkadot/runtime/Cargo.toml @@ -26,6 +26,7 @@ substrate-runtime-session = { path = "../../substrate/runtime/session" } substrate-runtime-staking = { path = "../../substrate/runtime/staking" } substrate-runtime-system = { path = "../../substrate/runtime/system" } substrate-runtime-timestamp = { path = "../../substrate/runtime/timestamp" } +substrate-runtime-version = { path = "../../substrate/runtime/version" } [dev-dependencies] hex-literal = "0.1.0" @@ -48,6 +49,7 @@ std = [ "substrate-runtime-staking/std", "substrate-runtime-system/std", "substrate-runtime-timestamp/std", + "substrate-runtime-version/std", "serde_derive", "serde/std", "log", diff --git a/polkadot/runtime/src/lib.rs b/polkadot/runtime/src/lib.rs index 6452aadcfdc46..532de07cd76ef 100644 --- a/polkadot/runtime/src/lib.rs +++ b/polkadot/runtime/src/lib.rs @@ -56,6 +56,8 @@ extern crate substrate_runtime_session as session; extern crate substrate_runtime_staking as staking; extern crate substrate_runtime_system as system; extern crate substrate_runtime_timestamp as timestamp; +#[macro_use] +extern crate substrate_runtime_version as version; #[cfg(feature = "std")] mod checked_block; @@ -69,6 +71,7 @@ pub use staking::address::Address as RawAddress; use primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Log, SessionKey, Signature}; use runtime_primitives::{generic, traits::{HasPublicAux, BlakeTwo256, Convert}}; +use version::RuntimeVersion; #[cfg(feature = "std")] pub use runtime_primitives::BuildStorage; @@ -102,6 +105,22 @@ pub type Block = generic::Block; #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] pub struct Concrete; +/// Polkadot runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: ver_str!("polkadot"), + impl_name: ver_str!("parity-polkadot"), + authoring_version: 0, + spec_version: 0, + impl_version: 0, +}; + +impl version::Trait for Concrete { + const VERSION: RuntimeVersion = VERSION; +} + +/// Version module for this concrete runtime. +pub type Version = version::Module; + impl HasPublicAux for Concrete { type PublicAux = AccountId; // TODO: Option } @@ -221,6 +240,7 @@ impl_outer_config! { pub mod api { impl_stubs!( + version => |()| super::Version::version(), authorities => |()| super::Consensus::authorities(), initialise_block => |header| super::Executive::initialise_block(&header), apply_extrinsic => |extrinsic| super::Executive::apply_extrinsic(extrinsic), diff --git a/polkadot/runtime/wasm/Cargo.lock b/polkadot/runtime/wasm/Cargo.lock index 82cbbb68e9895..b5b23aa1d448a 100644 --- a/polkadot/runtime/wasm/Cargo.lock +++ b/polkadot/runtime/wasm/Cargo.lock @@ -485,6 +485,7 @@ dependencies = [ "substrate-runtime-support 0.1.0", "substrate-runtime-system 0.1.0", "substrate-runtime-timestamp 0.1.0", + "substrate-runtime-version 0.1.0", ] [[package]] @@ -972,6 +973,17 @@ dependencies = [ "substrate-runtime-system 0.1.0", ] +[[package]] +name = "substrate-runtime-version" +version = "0.1.0" +dependencies = [ + "serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", +] + [[package]] name = "substrate-state-machine" version = "0.1.0" diff --git a/polkadot/runtime/wasm/Cargo.toml b/polkadot/runtime/wasm/Cargo.toml index f5dc280e6f6b2..3a73d894001e0 100644 --- a/polkadot/runtime/wasm/Cargo.toml +++ b/polkadot/runtime/wasm/Cargo.toml @@ -24,6 +24,7 @@ substrate-runtime-session = { path = "../../../substrate/runtime/session", defau substrate-runtime-staking = { path = "../../../substrate/runtime/staking", default-features = false } substrate-runtime-system = { path = "../../../substrate/runtime/system", default-features = false } substrate-runtime-timestamp = { path = "../../../substrate/runtime/timestamp", default-features = false } +substrate-runtime-version = { path = "../../../substrate/runtime/version", default-features = false } [features] default = [] @@ -44,6 +45,7 @@ std = [ "substrate-runtime-staking/std", "substrate-runtime-system/std", "substrate-runtime-timestamp/std", + "substrate-runtime-version/std", ] [profile.release] diff --git a/polkadot/runtime/wasm/genesis.wasm b/polkadot/runtime/wasm/genesis.wasm index 07c28e8cff597..c862998de6414 100644 Binary files a/polkadot/runtime/wasm/genesis.wasm and b/polkadot/runtime/wasm/genesis.wasm differ diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm index 5010850d88d50..f114ea539bc69 100644 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm differ diff --git a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm index 77c56b6c0a0ec..0794dc20ffe32 100755 Binary files a/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm and b/polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm differ diff --git a/polkadot/transaction-pool/src/lib.rs b/polkadot/transaction-pool/src/lib.rs index 1fab5d481ee13..5f344035cec0a 100644 --- a/polkadot/transaction-pool/src/lib.rs +++ b/polkadot/transaction-pool/src/lib.rs @@ -180,7 +180,7 @@ impl txpool::Scoring for Scoring { /// Readiness evaluator for polkadot transactions. pub struct Ready<'a, A: 'a + PolkadotApi> { - at_block: A::CheckedBlockId, + at_block: BlockId, api: &'a A, known_nonces: HashMap, } @@ -188,7 +188,7 @@ pub struct Ready<'a, A: 'a + PolkadotApi> { impl<'a, A: 'a + PolkadotApi> Ready<'a, A> { /// Create a new readiness evaluator at the given block. Requires that /// the ID has already been checked for local corresponding and available state. - fn create(at: A::CheckedBlockId, api: &'a A) -> Self { + fn create(at: BlockId, api: &'a A) -> Self { Ready { at_block: at, api, @@ -244,12 +244,12 @@ impl<'a, A: 'a + PolkadotApi> txpool::Ready for Ready<'a, A } } -pub struct Verifier<'a, A: 'a, B> { +pub struct Verifier<'a, A: 'a> { api: &'a A, - at_block: B, + at_block: BlockId, } -impl<'a, A> Verifier<'a, A, A::CheckedBlockId> where +impl<'a, A> Verifier<'a, A> where A: 'a + PolkadotApi, { const NO_ACCOUNT: &'static str = "Account not found."; @@ -267,7 +267,7 @@ impl<'a, A> Verifier<'a, A, A::CheckedBlockId> where } } -impl<'a, A> txpool::Verifier for Verifier<'a, A, A::CheckedBlockId> where +impl<'a, A> txpool::Verifier for Verifier<'a, A> where A: 'a + PolkadotApi, { type VerifiedTransaction = VerifiedTransaction; @@ -322,7 +322,7 @@ impl TransactionPool where pub fn import_unchecked_extrinsic(&self, block: BlockId, uxt: UncheckedExtrinsic) -> Result> { let verifier = Verifier { api: &*self.api, - at_block: self.api.check_id(block)?, + at_block: block, }; self.inner.submit(verifier, vec![uxt]).map(|mut v| v.swap_remove(0)) } @@ -332,7 +332,7 @@ impl TransactionPool where let to_reverify = self.inner.remove_sender(None); let verifier = Verifier { api: &*self.api, - at_block: self.api.check_id(block)?, + at_block: block, }; self.inner.submit(verifier, to_reverify.into_iter().map(|tx| tx.original.clone()))?; @@ -358,8 +358,7 @@ impl TransactionPool where /// Cull old transactions from the queue. pub fn cull(&self, block: BlockId) -> Result { - let id = self.api.check_id(block)?; - let ready = Ready::create(id, &*self.api); + let ready = Ready::create(block, &*self.api); Ok(self.inner.cull(None, ready)) } @@ -367,8 +366,7 @@ impl TransactionPool where pub fn cull_and_get_pending(&self, block: BlockId, f: F) -> Result where F: FnOnce(txpool::PendingIterator, Scoring, Listener>) -> T, { - let id = self.api.check_id(block)?; - let ready = Ready::create(id, &*self.api); + let ready = Ready::create(block, &*self.api); self.inner.cull(None, ready.clone()); Ok(self.inner.pending(ready, f)) } @@ -413,7 +411,7 @@ mod tests { use super::TransactionPool; use substrate_keyring::Keyring::{self, *}; use codec::Slicable; - use polkadot_api::{PolkadotApi, BlockBuilder, CheckedBlockId, Result}; + use polkadot_api::{PolkadotApi, BlockBuilder, Result}; use primitives::{AccountId, AccountIndex, Block, BlockId, Hash, Index, SessionKey, Timestamp, UncheckedExtrinsic as FutureProofUncheckedExtrinsic}; use runtime::{RawAddress, Call, TimestampCall, BareExtrinsic, Extrinsic, UncheckedExtrinsic}; @@ -426,15 +424,9 @@ mod tests { fn bake(self) -> Result { unimplemented!() } } - #[derive(Clone)] - struct TestCheckedBlockId(pub BlockId); - impl CheckedBlockId for TestCheckedBlockId { - fn block_id(&self) -> &BlockId { &self.0 } - } - - fn number_of(at: &TestCheckedBlockId) -> u32 { - match at.0 { - generic::BlockId::Number(n) => n as u32, + fn number_of(at: &BlockId) -> u32 { + match at { + generic::BlockId::Number(n) => *n as u32, _ => 0, } } @@ -457,26 +449,24 @@ mod tests { } impl PolkadotApi for TestPolkadotApi { - type CheckedBlockId = TestCheckedBlockId; type BlockBuilder = TestBlockBuilder; - fn check_id(&self, id: BlockId) -> Result { Ok(TestCheckedBlockId(id)) } - fn session_keys(&self, _at: &TestCheckedBlockId) -> Result> { unimplemented!() } - fn validators(&self, _at: &TestCheckedBlockId) -> Result> { unimplemented!() } - fn random_seed(&self, _at: &TestCheckedBlockId) -> Result { unimplemented!() } - fn duty_roster(&self, _at: &TestCheckedBlockId) -> Result { unimplemented!() } - fn timestamp(&self, _at: &TestCheckedBlockId) -> Result { unimplemented!() } - fn evaluate_block(&self, _at: &TestCheckedBlockId, _block: Block) -> Result { unimplemented!() } - fn active_parachains(&self, _at: &TestCheckedBlockId) -> Result> { unimplemented!() } - fn parachain_code(&self, _at: &TestCheckedBlockId, _parachain: ParaId) -> Result>> { unimplemented!() } - fn parachain_head(&self, _at: &TestCheckedBlockId, _parachain: ParaId) -> Result>> { unimplemented!() } - fn build_block(&self, _at: &TestCheckedBlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result { unimplemented!() } - fn inherent_extrinsics(&self, _at: &TestCheckedBlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result>> { unimplemented!() } - - fn index(&self, _at: &TestCheckedBlockId, _account: AccountId) -> Result { + fn session_keys(&self, _at: &BlockId) -> Result> { unimplemented!() } + fn validators(&self, _at: &BlockId) -> Result> { unimplemented!() } + fn random_seed(&self, _at: &BlockId) -> Result { unimplemented!() } + fn duty_roster(&self, _at: &BlockId) -> Result { unimplemented!() } + fn timestamp(&self, _at: &BlockId) -> Result { unimplemented!() } + fn evaluate_block(&self, _at: &BlockId, _block: Block) -> Result { unimplemented!() } + fn active_parachains(&self, _at: &BlockId) -> Result> { unimplemented!() } + fn parachain_code(&self, _at: &BlockId, _parachain: ParaId) -> Result>> { unimplemented!() } + fn parachain_head(&self, _at: &BlockId, _parachain: ParaId) -> Result>> { unimplemented!() } + fn build_block(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result { unimplemented!() } + fn inherent_extrinsics(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec) -> Result>> { unimplemented!() } + + fn index(&self, _at: &BlockId, _account: AccountId) -> Result { Ok((_account[0] as u32) + number_of(_at)) } - fn lookup(&self, _at: &TestCheckedBlockId, _address: RawAddress) -> Result> { + fn lookup(&self, _at: &BlockId, _address: RawAddress) -> Result> { match _address { RawAddress::Id(i) => Ok(Some(i)), RawAddress::Index(_) if self.no_lookup.load(atomic::Ordering::SeqCst) => Ok(None), diff --git a/substrate/bft/src/error.rs b/substrate/bft/src/error.rs index c18528a3f1e09..1e3b3a523f502 100644 --- a/substrate/bft/src/error.rs +++ b/substrate/bft/src/error.rs @@ -54,6 +54,12 @@ error_chain! { display("Message sender {:?} is not a valid authority.", a), } + /// Authoring interface does not match the runtime. + InvalidRuntime { + description("Authoring for current runtime is not supported"), + display("Authoring for current runtime is not supported."), + } + /// Justification requirements not met. InvalidJustification { description("Invalid justification"), diff --git a/substrate/client/db/Cargo.toml b/substrate/client/db/Cargo.toml index ac821794c9b3a..5a26a7cdb8537 100644 --- a/substrate/client/db/Cargo.toml +++ b/substrate/client/db/Cargo.toml @@ -18,6 +18,7 @@ substrate-client = { path = "../../../substrate/client" } substrate-state-machine = { path = "../../../substrate/state-machine" } substrate-runtime-support = { path = "../../../substrate/runtime-support" } substrate-codec = { path = "../../../substrate/codec" } +substrate-executor = { path = "../../../substrate/executor" } substrate-state-db = { path = "../../../substrate/state-db" } [dev-dependencies] diff --git a/substrate/client/db/src/lib.rs b/substrate/client/db/src/lib.rs index b33a834f6c2a5..9dd7c1d3b2354 100644 --- a/substrate/client/db/src/lib.rs +++ b/substrate/client/db/src/lib.rs @@ -27,6 +27,7 @@ extern crate substrate_primitives as primitives; extern crate substrate_runtime_support as runtime_support; extern crate substrate_runtime_primitives as runtime_primitives; extern crate substrate_codec as codec; +extern crate substrate_executor as executor; extern crate substrate_state_db as state_db; #[macro_use] @@ -52,6 +53,7 @@ use runtime_primitives::bft::Justification; use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, Hashing, HashingFor, Zero}; use runtime_primitives::BuildStorage; use state_machine::backend::Backend as StateBackend; +use executor::RuntimeInfo; use state_machine::{CodeExecutor, TrieH256, DBValue}; use utils::{Meta, db_err, meta_keys, number_to_db_key, open_database, read_db, read_id, read_meta}; use state_db::StateDb; @@ -82,7 +84,7 @@ pub fn new_client( Block: BlockT, ::Number: As, Block::Hash: Into<[u8; 32]>, // TODO: remove when patricia_trie generic. - E: CodeExecutor, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, { let backend = Arc::new(Backend::new(settings, FINALIZATION_WINDOW)?); diff --git a/substrate/client/src/call_executor.rs b/substrate/client/src/call_executor.rs index b0d2c2707cc2e..498190cc6ab16 100644 --- a/substrate/client/src/call_executor.rs +++ b/substrate/client/src/call_executor.rs @@ -18,6 +18,7 @@ use std::sync::Arc; use runtime_primitives::generic::BlockId; use runtime_primitives::traits::Block as BlockT; use state_machine::{self, OverlayedChanges, Backend as StateBackend, CodeExecutor}; +use executor::{RuntimeVersion, RuntimeInfo}; use backend; use error; @@ -50,6 +51,9 @@ pub trait CallExecutor { /// /// No changes are made. fn prove_at_state(&self, state: S, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8]) -> Result<(Vec, Vec>), error::Error>; + + /// Get runtime version if supported. + fn native_runtime_version(&self) -> Option; } /// Call executor that executes methods locally, querying all required @@ -78,7 +82,7 @@ impl Clone for LocalCallExecutor where E: Clone { impl CallExecutor for LocalCallExecutor where B: backend::LocalBackend, - E: CodeExecutor, + E: CodeExecutor + RuntimeInfo, Block: BlockT, error::Error: From<<>::State as StateBackend>::Error>, { @@ -111,4 +115,8 @@ impl CallExecutor for LocalCallExecutor .map(|(result, proof, _)| (result, proof)) .map_err(Into::into) } -} \ No newline at end of file + + fn native_runtime_version(&self) -> Option { + ::NATIVE_VERSION + } +} diff --git a/substrate/client/src/client.rs b/substrate/client/src/client.rs index 53b8cb5e0ba46..2d8b18f93228c 100644 --- a/substrate/client/src/client.rs +++ b/substrate/client/src/client.rs @@ -30,12 +30,13 @@ use state_machine::{self, Ext, OverlayedChanges, Backend as StateBackend, CodeEx use backend::{self, BlockImportOperation}; use blockchain::{self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend as ChainHeaderBackend}; use call_executor::{CallExecutor, LocalCallExecutor}; +use executor::{RuntimeVersion, RuntimeInfo}; use {error, in_mem, block_builder, runtime_io, bft, genesis}; /// Type that implements `futures::Stream` of block import events. pub type BlockchainEventStream = mpsc::UnboundedReceiver>; -/// Polkadot Client +/// Substrate Client pub struct Client where Block: BlockT { backend: Arc, executor: E, @@ -146,7 +147,7 @@ pub fn new_in_mem( genesis_storage: S ) -> error::Result, LocalCallExecutor, E>, Block>> where - E: CodeExecutor, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, Block: BlockT, { @@ -161,7 +162,7 @@ impl Client where Block: BlockT, error::Error: From<<>::State as StateBackend>::Error>, { - /// Creates new Polkadot Client with given blockchain and code executor. + /// Creates new Substrate Client with given blockchain and code executor. pub fn new( backend: Arc, executor: E, @@ -210,11 +211,20 @@ impl Client where /// Get the set of authorities at a given block. pub fn authorities_at(&self, id: &BlockId) -> error::Result> { - self.executor.call(id, "authorities",&[]) + self.executor.call(id, "authorities", &[]) .and_then(|r| Vec::::decode(&mut &r.return_data[..]) .ok_or(error::ErrorKind::AuthLenInvalid.into())) } + /// Get the set of authorities at a given block. + pub fn runtime_version_at(&self, id: &BlockId) -> error::Result { + // TODO: Post Poc-2 return an error if version is missing + Ok(self.executor.call(id, "version", &[]) + .and_then(|r| RuntimeVersion::decode(&mut &r.return_data[..]) + .ok_or(error::ErrorKind::VersionInvalid.into())) + .unwrap_or_default()) + } + /// Get call executor reference. pub fn executor(&self) -> &E { &self.executor @@ -439,6 +449,11 @@ impl bft::Authorities for Client error::Error: From<::Error>, { fn authorities(&self, at: &BlockId) -> Result, bft::Error> { + let version: Result<_, bft::Error> = self.runtime_version_at(at).map_err(|_| bft::ErrorKind::InvalidRuntime.into()); + let version = version?; + if !self.executor.native_runtime_version().map_or(true, |v| v.can_author_with(&version)) { + return Err(bft::ErrorKind::InvalidRuntime.into()) + } self.authorities_at(at).map_err(|_| { let descriptor = format!("{:?}", at); bft::ErrorKind::StateUnavailable(descriptor).into() diff --git a/substrate/client/src/error.rs b/substrate/client/src/error.rs index 9ee6e7639fea9..b9447d38a30b4 100644 --- a/substrate/client/src/error.rs +++ b/substrate/client/src/error.rs @@ -70,6 +70,12 @@ error_chain! { display("Current state of blockchain has invalid authority count value"), } + /// Cound not get runtime version. + VersionInvalid { + description("Runtime version error"), + display("On-chain runtime does not specify version"), + } + /// Invalid state data. AuthInvalid(i: u32) { description("authority value state error"), diff --git a/substrate/client/src/genesis.rs b/substrate/client/src/genesis.rs index f4033243e42a9..a4e9f9cf87d8f 100644 --- a/substrate/client/src/genesis.rs +++ b/substrate/client/src/genesis.rs @@ -52,7 +52,7 @@ mod tests { use test_client::runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest, Extrinsic}; use ed25519::{Public, Pair}; - native_executor_instance!(Executor, test_client::runtime::api::dispatch, 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::VERSION, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); fn construct_block(backend: &InMemory, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec) -> (Vec, Hash) { use triehash::ordered_trie_root; diff --git a/substrate/client/src/lib.rs b/substrate/client/src/lib.rs index 7c84e9f3614d8..4bf79e16d51ce 100644 --- a/substrate/client/src/lib.rs +++ b/substrate/client/src/lib.rs @@ -36,7 +36,7 @@ extern crate triehash; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; -#[cfg(test)] #[macro_use] extern crate substrate_executor as executor; +#[cfg_attr(test, macro_use)] extern crate substrate_executor as executor; #[cfg(test)] #[macro_use] extern crate hex_literal; pub mod error; diff --git a/substrate/client/src/light/call_executor.rs b/substrate/client/src/light/call_executor.rs index 330781667b1fe..a052d7eee39ee 100644 --- a/substrate/client/src/light/call_executor.rs +++ b/substrate/client/src/light/call_executor.rs @@ -28,6 +28,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; /// Call executor that executes methods on remote node, querying execution proof /// and checking proof by re-executing locally. @@ -72,6 +73,10 @@ impl CallExecutor for RemoteCallExecutor fn prove_at_state(&self, _state: S, _changes: &mut OverlayedChanges, _method: &str, _call_data: &[u8]) -> ClientResult<(Vec, Vec>)> { Err(ClientErrorKind::NotAvailableOnLightClient.into()) } + + fn native_runtime_version(&self) -> Option { + None + } } /// Check remote execution proof using given backend. diff --git a/substrate/codec/src/lib.rs b/substrate/codec/src/lib.rs index b0ed6dc328dca..d38e3f6f723d8 100644 --- a/substrate/codec/src/lib.rs +++ b/substrate/codec/src/lib.rs @@ -38,6 +38,6 @@ mod slicable; mod joiner; mod keyedvec; -pub use self::slicable::{Input, Slicable}; +pub use self::slicable::{Input, Slicable, encode_slice}; pub use self::joiner::Joiner; pub use self::keyedvec::KeyedVec; diff --git a/substrate/codec/src/slicable.rs b/substrate/codec/src/slicable.rs index 8d66b896faf6d..c6363d35025e6 100644 --- a/substrate/codec/src/slicable.rs +++ b/substrate/codec/src/slicable.rs @@ -63,6 +63,16 @@ pub trait Slicable: Sized { } } +/// Encode a bytes slice as `Slicable` that can be decoded into a vector. +pub fn encode_slice(bytes: &[u8]) -> Vec { + let len = bytes.len(); + assert!(len <= u32::max_value() as usize, "Attempted to serialize a collection with too many elements."); + + let mut r: Vec = Vec::new().and(&(len as u32)); + r.extend_from_slice(bytes); + r +} + impl Slicable for Result { fn decode(input: &mut I) -> Option { match input.read_byte()? { @@ -182,12 +192,7 @@ impl Slicable for Vec { } fn encode(&self) -> Vec { - let len = self.len(); - assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements."); - - let mut r: Vec = Vec::new().and(&(len as u32)); - r.extend_from_slice(self); - r + encode_slice(&self) } } diff --git a/substrate/executor/Cargo.toml b/substrate/executor/Cargo.toml index 58152c27a9309..e2dbb56eed0a7 100644 --- a/substrate/executor/Cargo.toml +++ b/substrate/executor/Cargo.toml @@ -10,6 +10,7 @@ substrate-runtime-io = { path = "../runtime-io" } substrate-primitives = { path = "../primitives" } substrate-serializer = { path = "../serializer" } substrate-state-machine = { path = "../state-machine" } +substrate-runtime-version = { path = "../runtime/version" } ed25519 = { path = "../ed25519" } serde = "1.0" serde_derive = "1.0" diff --git a/substrate/executor/src/lib.rs b/substrate/executor/src/lib.rs index 6c79977c5efd6..2983cf9f54e33 100644 --- a/substrate/executor/src/lib.rs +++ b/substrate/executor/src/lib.rs @@ -26,12 +26,14 @@ //! I leave it as is for now as it might be removed before this is ever done. #![warn(missing_docs)] +#![recursion_limit="128"] extern crate substrate_codec as codec; extern crate substrate_runtime_io as runtime_io; extern crate substrate_primitives as primitives; extern crate substrate_serializer as serializer; extern crate substrate_state_machine as state_machine; +extern crate substrate_runtime_version as runtime_version; extern crate ed25519; extern crate serde; @@ -61,3 +63,11 @@ 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 codec::Slicable; + +/// Provides runtime information. +pub trait RuntimeInfo { + /// Native runtime information if any. + const NATIVE_VERSION: Option; +} diff --git a/substrate/executor/src/native_executor.rs b/substrate/executor/src/native_executor.rs index a759c046c662b..5625082604c12 100644 --- a/substrate/executor/src/native_executor.rs +++ b/substrate/executor/src/native_executor.rs @@ -17,6 +17,9 @@ use error::{Error, ErrorKind, Result}; use state_machine::{CodeExecutor, Externalities}; use wasm_executor::WasmExecutor; +use runtime_version::RuntimeVersion; +use codec::Slicable; +use RuntimeInfo; fn safe_call(f: F) -> Result where F: ::std::panic::UnwindSafe + FnOnce() -> U @@ -41,22 +44,40 @@ pub trait NativeExecutionDispatch { /// Dispatch a method and input data to be executed natively. Returns `Some` result or `None` /// if the `method` is unknown. Panics if there's an unrecoverable error. fn dispatch(ext: &mut Externalities, method: &str, data: &[u8]) -> Result>; + + /// Get native runtime version. + const VERSION: RuntimeVersion; } /// 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. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct NativeExecutor { /// Dummy field to avoid the compiler complaining about us not using `D`. - pub _dummy: ::std::marker::PhantomData, + _dummy: ::std::marker::PhantomData, +} + +impl NativeExecutor { + /// Create new instance. + pub fn new() -> Self { + NativeExecutor { + _dummy: Default::default(), + } + } } impl Clone for NativeExecutor { fn clone(&self) -> Self { - NativeExecutor { _dummy: Default::default() } + NativeExecutor { + _dummy: Default::default(), + } } } +impl RuntimeInfo for NativeExecutor { + const NATIVE_VERSION: Option = Some(D::VERSION); +} + impl CodeExecutor for NativeExecutor { type Error = Error; @@ -71,6 +92,11 @@ impl CodeExecutor for NativeExecutor CodeExecutor for NativeExecutor { + (pub $name:ident, $dispatcher:path, $version:path, $code:expr) => { pub struct $name; - native_executor_instance!(IMPL $name, $dispatcher, $code); + native_executor_instance!(IMPL $name, $dispatcher, $version, $code); }; - ($name:ident, $dispatcher:path, $code:expr) => { + ($name:ident, $dispatcher:path, $version:path, $code:expr) => { /// A unit struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime. struct $name; - native_executor_instance!(IMPL $name, $dispatcher, $code); + native_executor_instance!(IMPL $name, $dispatcher, $version, $code); }; - (IMPL $name:ident, $dispatcher:path, $code:expr) => { + (IMPL $name:ident, $dispatcher:path, $version:path, $code:expr) => { 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. @@ -104,9 +131,8 @@ macro_rules! native_executor_instance { impl $name { pub fn new() -> $crate::NativeExecutor<$name> { - $crate::NativeExecutor { _dummy: Default::default() } + $crate::NativeExecutor::new() } } } - } diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm index 230b273941292..470961909f0b5 100644 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm differ diff --git a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm index 4413fb0b70955..a7b0bdd9fc55b 100755 Binary files a/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm and b/substrate/executor/wasm/target/wasm32-unknown-unknown/release/runtime_test.wasm differ diff --git a/substrate/rpc/src/chain/tests.rs b/substrate/rpc/src/chain/tests.rs index 51fb7b907574a..e2e24b8e2c60a 100644 --- a/substrate/rpc/src/chain/tests.rs +++ b/substrate/rpc/src/chain/tests.rs @@ -34,7 +34,7 @@ fn should_return_header() { Ok(Some(ref x)) if x == &Header { parent_hash: 0.into(), number: 0, - state_root: "987aa0851a133413b42c6d9aa3c91b1dddc2ad5337508ee8815116b11e44c64d".into(), + state_root: "17dccc74bd9200b7ce5a2f6a1bf379f1cdcf91bca3d19c3d17e1478b8d404703".into(), extrinsics_root: "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421".into(), digest: Default::default(), } @@ -70,7 +70,7 @@ fn should_notify_about_latest_block() { // assert notification send to transport let (notification, next) = core.run(transport.into_future()).unwrap(); assert_eq!(notification, Some( - r#"{"jsonrpc":"2.0","method":"test","params":{"result":{"digest":{"logs":[]},"extrinsicsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","number":1,"parentHash":"0x27f04d7574733bb155bbf5a0399fcc99d3c4dbf15bf99862d261bced9444179a","stateRoot":"0x987aa0851a133413b42c6d9aa3c91b1dddc2ad5337508ee8815116b11e44c64d"},"subscription":0}}"#.to_owned() + r#"{"jsonrpc":"2.0","method":"test","params":{"result":{"digest":{"logs":[]},"extrinsicsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","number":1,"parentHash":"0x50fb1e7f32e8ad17f553846f4338861e17eb95132e7c3b433e0429ffab2f8f13","stateRoot":"0x17dccc74bd9200b7ce5a2f6a1bf379f1cdcf91bca3d19c3d17e1478b8d404703"},"subscription":0}}"#.to_owned() )); // no more notifications on this channel assert_eq!(core.run(next.into_future()).unwrap().0, None); diff --git a/substrate/runtime/version/Cargo.toml b/substrate/runtime/version/Cargo.toml new file mode 100644 index 0000000000000..febbe10d31070 --- /dev/null +++ b/substrate/runtime/version/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "substrate-runtime-version" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +serde = { version = "1.0", default_features = false } +serde_derive = { version = "1.0", optional = true } +substrate-codec = { path = "../../codec", default_features = false } +substrate-runtime-std = { path = "../../runtime-std", default_features = false } +substrate-runtime-support = { path = "../../runtime-support", default_features = false } + +[features] +default = ["std"] +std = [ + "serde/std", + "serde_derive", + "substrate-codec/std", + "substrate-runtime-std/std", + "substrate-runtime-support/std", +] diff --git a/substrate/runtime/version/src/lib.rs b/substrate/runtime/version/src/lib.rs new file mode 100644 index 0000000000000..b93ebde932208 --- /dev/null +++ b/substrate/runtime/version/src/lib.rs @@ -0,0 +1,154 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Substrate Demo. + +// Substrate Demo 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 Demo 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 Demo. If not, see . + +//! Version module for runtime; Provide a function that returns runtime version. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(feature = "std")] +extern crate serde; + +#[cfg(feature = "std")] +#[macro_use] +extern crate serde_derive; + +#[allow(unused_imports)] +#[macro_use] +extern crate substrate_runtime_std as rstd; + +#[macro_use] +extern crate substrate_runtime_support as runtime_support; + +extern crate substrate_codec as codec; + +use rstd::prelude::*; +use codec::Slicable; +#[cfg(feature = "std")] +use std::borrow::Cow; + +#[cfg(feature = "std")] +pub type VersionString = ::std::borrow::Cow<'static, str>; +#[cfg(not(feature = "std"))] +pub type VersionString = &'static str; + +#[cfg(feature = "std")] +#[macro_export] +macro_rules! ver_str { + ( $y:expr ) => {{ ::std::borrow::Cow::Borrowed($y) }} +} + +#[cfg(not(feature = "std"))] +#[macro_export] +macro_rules! ver_str { + ( $y:expr ) => {{ $y }} +} + +/// Runtime version. +/// This should not be thought of as classic Semver (major/minor/tiny). +/// This triplet have different semantics and mis-interpretation could cause problems. +/// In particular: bug fixes should result in an increment of `spec_version` and possibly `authoring_version`, +/// absolutely not `impl_version` since they change the semantics of the runtime. +#[derive(Clone)] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +pub struct RuntimeVersion { + /// Identifies the different Substrate runtimes. There'll be at least polkadot and demo. A different on-chain spec_name to that of the native runtime would normally result in node not attempting to sync further. + pub spec_name: VersionString, + /// Name of the implementation of the spec. This is of little consequence for the node and serves only to differentiate code of different implementation teams. For this codebase, it will be parity-polkadot. + /// If there were a non-Rust implementation of the Polkadot runtime (e.g. C++), then it would identify itself with an accordingly different impl_name. + pub impl_name: VersionString, + /// `authoring_version` is the version of the authorship interface. An authoring node will not attempt to author blocks unless this is equal to its native runtime. + pub authoring_version: u32, + /// Version of the runtime specification. A full-node will not attempt to use its native runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`, `spec_version` and `authoring_version` + /// are the same between Wasm and native. + pub spec_version: u32, + /// Version of the implementation of the specification. Nodes are free to ignore this; it serves only as an indication that the code is different; + /// as long as the other two versions are the same then while the code may be different, it is nonetheless required to do the same thing. + /// Non-consensus-breaking optimisations are about the only changes that could be made which would result in only the impl_version changing. + pub impl_version: u32, +} + +// TODO: remove this after PoC-2 +#[cfg(feature = "std")] +impl Default for RuntimeVersion { + fn default() -> RuntimeVersion { + RuntimeVersion { + spec_name: ver_str!("polkadot"), + impl_name: ver_str!("parity-polkadot"), + authoring_version: 0, + spec_version: 0, + impl_version: 0, + } + } +} + +#[cfg(feature = "std")] +impl RuntimeVersion { + /// Check if this version matches other version for calling into runtime. + pub fn can_call_with(&self, other: &RuntimeVersion) -> bool { + self.spec_version == other.spec_version && + self.spec_name == other.spec_name && + 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 + } +} + +impl Slicable for RuntimeVersion { + fn encode(&self) -> Vec { + let mut v = Vec::new(); + v.extend(codec::encode_slice(self.spec_name.as_bytes())); + v.extend(codec::encode_slice(self.impl_name.as_bytes())); + self.authoring_version.using_encoded(|s| v.extend(s)); + self.spec_version.using_encoded(|s| v.extend(s)); + self.impl_version.using_encoded(|s| v.extend(s)); + v + } + + #[cfg(not(feature = "std"))] + fn decode(_value: &mut I) -> Option { + unreachable!() + } + + #[cfg(feature = "std")] + fn decode(value: &mut I) -> Option { + Some(RuntimeVersion { + spec_name: Cow::Owned(String::from_utf8_lossy(&Vec::decode(value)?).into()), + impl_name: Cow::Owned(String::from_utf8_lossy(&Vec::decode(value)?).into()), + authoring_version: Slicable::decode(value)?, + spec_version: Slicable::decode(value)?, + impl_version: Slicable::decode(value)?, + }) + } +} + +pub trait Trait { + const VERSION: RuntimeVersion; +} + +decl_module! { + pub struct Module; +} + +impl Module { + /// Get runtime version. + pub fn version() -> RuntimeVersion { + T::VERSION.clone() + } +} diff --git a/substrate/test-client/src/lib.rs b/substrate/test-client/src/lib.rs index 1500e603a07fe..fed17e46cda72 100644 --- a/substrate/test-client/src/lib.rs +++ b/substrate/test-client/src/lib.rs @@ -37,7 +37,7 @@ mod native_executor { #![allow(missing_docs)] use super::runtime; - native_executor_instance!(pub NativeExecutor, runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); + native_executor_instance!(pub NativeExecutor, runtime::api::dispatch, runtime::VERSION, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); } /// Native executor used for tests. diff --git a/substrate/test-runtime/Cargo.toml b/substrate/test-runtime/Cargo.toml index bd0654e2ef945..f955d0eab3bee 100644 --- a/substrate/test-runtime/Cargo.toml +++ b/substrate/test-runtime/Cargo.toml @@ -16,6 +16,7 @@ substrate-runtime-io = { path = "../runtime-io", default-features = false } substrate-runtime-support = { path = "../runtime-support", default-features = false } substrate-primitives = { path = "../primitives", default-features = false } substrate-runtime-primitives = { path = "../runtime/primitives", default-features = false } +substrate-runtime-version = { path = "../runtime/version", default-features = false } [features] default = ["std"] @@ -31,5 +32,6 @@ std = [ "substrate-runtime-io/std", "substrate-runtime-support/std", "substrate-primitives/std", - "substrate-runtime-primitives/std" + "substrate-runtime-primitives/std", + "substrate-runtime-version/std" ] diff --git a/substrate/test-runtime/src/lib.rs b/substrate/test-runtime/src/lib.rs index 8454a8c7bd60c..1b07035e966e8 100644 --- a/substrate/test-runtime/src/lib.rs +++ b/substrate/test-runtime/src/lib.rs @@ -43,6 +43,8 @@ extern crate substrate_keyring as keyring; extern crate substrate_primitives as primitives; #[macro_use] extern crate substrate_runtime_io as runtime_io; +#[macro_use] +extern crate substrate_runtime_version as runtime_version; #[cfg(feature = "std")] pub mod genesismap; @@ -53,8 +55,22 @@ use codec::Slicable; use runtime_primitives::traits::{BlindCheckable, BlakeTwo256}; use runtime_primitives::Ed25519Signature; +use runtime_version::RuntimeVersion; pub use primitives::hash::H256; +/// Test runtime version. +pub const VERSION: RuntimeVersion = RuntimeVersion { + spec_name: ver_str!("test"), + impl_name: ver_str!("parity-test"), + authoring_version: 1, + spec_version: 1, + impl_version: 1, +}; + +fn version() -> RuntimeVersion { + VERSION +} + /// Calls in transactions. #[derive(Clone, PartialEq, Eq)] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] @@ -146,8 +162,8 @@ pub fn run_tests(mut input: &[u8]) -> Vec { pub mod api { use system; - impl_stubs!( + version => |()| super::version(), authorities => |()| system::authorities(), initialise_block => |header| system::initialise_block(header), execute_block => |block| system::execute_block(block), diff --git a/substrate/test-runtime/wasm/Cargo.lock b/substrate/test-runtime/wasm/Cargo.lock index 8489efdb0db23..e2b1b17d41c73 100644 --- a/substrate/test-runtime/wasm/Cargo.lock +++ b/substrate/test-runtime/wasm/Cargo.lock @@ -730,6 +730,17 @@ dependencies = [ "substrate-runtime-std 0.1.0", ] +[[package]] +name = "substrate-runtime-version" +version = "0.1.0" +dependencies = [ + "serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-codec 0.1.0", + "substrate-runtime-std 0.1.0", + "substrate-runtime-support 0.1.0", +] + [[package]] name = "substrate-state-machine" version = "0.1.0" @@ -759,6 +770,7 @@ dependencies = [ "substrate-runtime-primitives 0.1.0", "substrate-runtime-std 0.1.0", "substrate-runtime-support 0.1.0", + "substrate-runtime-version 0.1.0", ] [[package]] diff --git a/substrate/test-runtime/wasm/Cargo.toml b/substrate/test-runtime/wasm/Cargo.toml index 99d86cd6a4c5b..61e7c594cc2af 100644 --- a/substrate/test-runtime/wasm/Cargo.toml +++ b/substrate/test-runtime/wasm/Cargo.toml @@ -11,6 +11,7 @@ substrate-codec = { path = "../../codec", default-features = false } substrate-runtime-std = { path = "../../runtime-std", default-features = false } substrate-runtime-io = { path = "../../runtime-io", default-features = false } substrate-runtime-support = { path = "../../runtime-support", default-features = false } +substrate-runtime-version = { path = "../../runtime/version", default-features = false } substrate-primitives = { path = "../../primitives", default-features = false } substrate-runtime-primitives = { path = "../../runtime/primitives", default-features = false } @@ -24,6 +25,7 @@ std = [ "substrate-runtime-std/std", "substrate-runtime-io/std", "substrate-runtime-support/std", + "substrate-runtime-version/std", "substrate-primitives/std", "substrate-runtime-primitives/std" ] diff --git a/substrate/test-runtime/wasm/genesis.wasm b/substrate/test-runtime/wasm/genesis.wasm index 94bf42b3f97dd..f5879aebc1ad4 100644 Binary files a/substrate/test-runtime/wasm/genesis.wasm and b/substrate/test-runtime/wasm/genesis.wasm differ diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index f63301135f1af..80d8c4e431b3b 100644 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm index 70e09c31afdfe..36c7255551a0b 100755 Binary files a/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm and b/substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.wasm differ diff --git a/update-genesis.sh b/update-genesis.sh index 627c22401976a..47f4dfdef3580 100755 --- a/update-genesis.sh +++ b/update-genesis.sh @@ -1,3 +1,4 @@ #!/usr/bin/env bash cp polkadot/runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm polkadot/runtime/wasm/genesis.wasm +cp substrate/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm substrate/test-runtime/wasm/genesis.wasm