mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-08 21:48:02 +00:00
Runtime version (#256)
* Runtime version * Updated genesis.wasm * Minor fixes * Fresh runtime * Default version for pre Poc-2; Fixed authorship interface check * Fixed authoring check
This commit is contained in:
committed by
Gav Wood
parent
e6a7c64518
commit
12268ae700
Generated
+16
@@ -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]]
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<Concrete>;
|
||||
|
||||
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),
|
||||
|
||||
Generated
+12
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
@@ -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<B: LocalBackend<Block>> BlockBuilder for ClientBlockBuilder<B, LocalCallExe
|
||||
impl<B: LocalBackend<Block>> PolkadotApi for Client<B, LocalCallExecutor<B, NativeExecutor<LocalDispatch>>, Block>
|
||||
where ::client::error::Error: From<<<B as Backend<Block>>::State as state_machine::backend::Backend>::Error>
|
||||
{
|
||||
type CheckedBlockId = CheckedId;
|
||||
type BlockBuilder = ClientBlockBuilder<B, LocalCallExecutor<B, NativeExecutor<LocalDispatch>>, Block>;
|
||||
|
||||
fn check_id(&self, id: BlockId) -> Result<CheckedId> {
|
||||
// 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<Vec<SessionKey>> {
|
||||
fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>> {
|
||||
with_runtime!(self, at, ::runtime::Consensus::authorities)
|
||||
}
|
||||
|
||||
fn validators(&self, at: &CheckedId) -> Result<Vec<AccountId>> {
|
||||
fn validators(&self, at: &BlockId) -> Result<Vec<AccountId>> {
|
||||
with_runtime!(self, at, ::runtime::Session::validators)
|
||||
}
|
||||
|
||||
fn random_seed(&self, at: &CheckedId) -> Result<Hash> {
|
||||
fn random_seed(&self, at: &BlockId) -> Result<Hash> {
|
||||
with_runtime!(self, at, ::runtime::System::random_seed)
|
||||
}
|
||||
|
||||
fn duty_roster(&self, at: &CheckedId) -> Result<DutyRoster> {
|
||||
fn duty_roster(&self, at: &BlockId) -> Result<DutyRoster> {
|
||||
with_runtime!(self, at, ::runtime::Parachains::calculate_duty_roster)
|
||||
}
|
||||
|
||||
fn timestamp(&self, at: &CheckedId) -> Result<Timestamp> {
|
||||
fn timestamp(&self, at: &BlockId) -> Result<Timestamp> {
|
||||
with_runtime!(self, at, ::runtime::Timestamp::get)
|
||||
}
|
||||
|
||||
fn evaluate_block(&self, at: &CheckedId, block: Block) -> Result<bool> {
|
||||
fn evaluate_block(&self, at: &BlockId, block: Block) -> Result<bool> {
|
||||
use substrate_executor::error::ErrorKind as ExecErrorKind;
|
||||
use codec::Slicable;
|
||||
use runtime::Block as RuntimeBlock;
|
||||
@@ -136,28 +116,28 @@ impl<B: LocalBackend<Block>> PolkadotApi for Client<B, LocalCallExecutor<B, Nati
|
||||
}
|
||||
}
|
||||
|
||||
fn index(&self, at: &CheckedId, account: AccountId) -> Result<Index> {
|
||||
fn index(&self, at: &BlockId, account: AccountId) -> Result<Index> {
|
||||
with_runtime!(self, at, || ::runtime::System::account_nonce(account))
|
||||
}
|
||||
|
||||
fn lookup(&self, at: &Self::CheckedBlockId, address: Address) -> Result<Option<AccountId>> {
|
||||
fn lookup(&self, at: &BlockId, address: Address) -> Result<Option<AccountId>> {
|
||||
with_runtime!(self, at, || <::runtime::Staking as AuxLookup>::lookup(address).ok())
|
||||
}
|
||||
|
||||
fn active_parachains(&self, at: &CheckedId) -> Result<Vec<ParaId>> {
|
||||
fn active_parachains(&self, at: &BlockId) -> Result<Vec<ParaId>> {
|
||||
with_runtime!(self, at, ::runtime::Parachains::active_parachains)
|
||||
}
|
||||
|
||||
fn parachain_code(&self, at: &CheckedId, parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
fn parachain_code(&self, at: &BlockId, parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
with_runtime!(self, at, || ::runtime::Parachains::parachain_code(parachain))
|
||||
}
|
||||
|
||||
fn parachain_head(&self, at: &CheckedId, parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
fn parachain_head(&self, at: &BlockId, parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
with_runtime!(self, at, || ::runtime::Parachains::parachain_head(parachain))
|
||||
}
|
||||
|
||||
fn build_block(&self, at: &CheckedId, timestamp: Timestamp, new_heads: Vec<CandidateReceipt>) -> Result<Self::BlockBuilder> {
|
||||
let mut block_builder = self.new_block_at(at.block_id())?;
|
||||
fn build_block(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec<CandidateReceipt>) -> Result<Self::BlockBuilder> {
|
||||
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<B: LocalBackend<Block>> PolkadotApi for Client<B, LocalCallExecutor<B, Nati
|
||||
Ok(block_builder)
|
||||
}
|
||||
|
||||
fn inherent_extrinsics(&self, at: &Self::CheckedBlockId, timestamp: Timestamp, new_heads: Vec<CandidateReceipt>) -> Result<Vec<UncheckedExtrinsic>> {
|
||||
fn inherent_extrinsics(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec<CandidateReceipt>) -> Result<Vec<UncheckedExtrinsic>> {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,12 +77,6 @@ impl From<client::error::Error> 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<Self::CheckedBlockId>;
|
||||
|
||||
/// Get session keys at a given block.
|
||||
fn session_keys(&self, at: &Self::CheckedBlockId) -> Result<Vec<SessionKey>>;
|
||||
fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>>;
|
||||
|
||||
/// Get validators at a given block.
|
||||
fn validators(&self, at: &Self::CheckedBlockId) -> Result<Vec<AccountId>>;
|
||||
fn validators(&self, at: &BlockId) -> Result<Vec<AccountId>>;
|
||||
|
||||
/// Get the value of the randomness beacon at a given block.
|
||||
fn random_seed(&self, at: &Self::CheckedBlockId) -> Result<Hash>;
|
||||
fn random_seed(&self, at: &BlockId) -> Result<Hash>;
|
||||
|
||||
/// Get the authority duty roster at a block.
|
||||
fn duty_roster(&self, at: &Self::CheckedBlockId) -> Result<DutyRoster>;
|
||||
fn duty_roster(&self, at: &BlockId) -> Result<DutyRoster>;
|
||||
|
||||
/// Get the timestamp registered at a block.
|
||||
fn timestamp(&self, at: &Self::CheckedBlockId) -> Result<Timestamp>;
|
||||
fn timestamp(&self, at: &BlockId) -> Result<Timestamp>;
|
||||
|
||||
/// Get the nonce (né index) of an account at a block.
|
||||
fn index(&self, at: &Self::CheckedBlockId, account: AccountId) -> Result<Index>;
|
||||
fn index(&self, at: &BlockId, account: AccountId) -> Result<Index>;
|
||||
|
||||
/// Get the account id of an address at a block.
|
||||
fn lookup(&self, at: &Self::CheckedBlockId, address: Address) -> Result<Option<AccountId>>;
|
||||
fn lookup(&self, at: &BlockId, address: Address) -> Result<Option<AccountId>>;
|
||||
|
||||
/// Get the active parachains at a block.
|
||||
fn active_parachains(&self, at: &Self::CheckedBlockId) -> Result<Vec<ParaId>>;
|
||||
fn active_parachains(&self, at: &BlockId) -> Result<Vec<ParaId>>;
|
||||
|
||||
/// 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<Option<Vec<u8>>>;
|
||||
fn parachain_code(&self, at: &BlockId, parachain: ParaId) -> Result<Option<Vec<u8>>>;
|
||||
|
||||
/// 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<Option<Vec<u8>>>;
|
||||
fn parachain_head(&self, at: &BlockId, parachain: ParaId) -> Result<Option<Vec<u8>>>;
|
||||
|
||||
/// 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<bool>;
|
||||
fn evaluate_block(&self, at: &BlockId, block: Block) -> Result<bool>;
|
||||
|
||||
/// 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<CandidateReceipt>) -> Result<Self::BlockBuilder>;
|
||||
fn build_block(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec<CandidateReceipt>) -> Result<Self::BlockBuilder>;
|
||||
|
||||
/// 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<CandidateReceipt>) -> Result<Vec<UncheckedExtrinsic>>;
|
||||
fn inherent_extrinsics(&self, at: &BlockId, timestamp: Timestamp, new_heads: Vec<CandidateReceipt>) -> Result<Vec<UncheckedExtrinsic>>;
|
||||
}
|
||||
|
||||
/// Mark for all Polkadot API implementations, that are making use of state data, stored locally.
|
||||
|
||||
@@ -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<B: Backend<Block>, E: CallExecutor<Block>>(p
|
||||
impl<B: Backend<Block>, E: CallExecutor<Block>> PolkadotApi for RemotePolkadotApiWrapper<B, E>
|
||||
where ::client::error::Error: From<<<B as Backend<Block>>::State as state_machine::backend::Backend>::Error>
|
||||
{
|
||||
type CheckedBlockId = CheckedId;
|
||||
type BlockBuilder = LightBlockBuilder;
|
||||
|
||||
fn check_id(&self, id: BlockId) -> Result<CheckedId> {
|
||||
Ok(CheckedId(id))
|
||||
}
|
||||
|
||||
fn session_keys(&self, at: &CheckedId) -> Result<Vec<SessionKey>> {
|
||||
self.0.executor().call(at.block_id(), "authorities", &[])
|
||||
fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>> {
|
||||
self.0.executor().call(at, "authorities", &[])
|
||||
.and_then(|r| Vec::<SessionKey>::decode(&mut &r.return_data[..])
|
||||
.ok_or("error decoding session keys".into()))
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn validators(&self, _at: &CheckedId) -> Result<Vec<AccountId>> {
|
||||
fn validators(&self, _at: &BlockId) -> Result<Vec<AccountId>> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn random_seed(&self, _at: &Self::CheckedBlockId) -> Result<Hash> {
|
||||
fn random_seed(&self, _at: &BlockId) -> Result<Hash> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn duty_roster(&self, _at: &CheckedId) -> Result<DutyRoster> {
|
||||
fn duty_roster(&self, _at: &BlockId) -> Result<DutyRoster> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn timestamp(&self, _at: &CheckedId) -> Result<Timestamp> {
|
||||
fn timestamp(&self, _at: &BlockId) -> Result<Timestamp> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn evaluate_block(&self, _at: &CheckedId, _block: Block) -> Result<bool> {
|
||||
fn evaluate_block(&self, _at: &BlockId, _block: Block) -> Result<bool> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn index(&self, _at: &CheckedId, _account: AccountId) -> Result<Index> {
|
||||
fn index(&self, _at: &BlockId, _account: AccountId) -> Result<Index> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn lookup(&self, _at: &CheckedId, _address: Address) -> Result<Option<AccountId>> {
|
||||
fn lookup(&self, _at: &BlockId, _address: Address) -> Result<Option<AccountId>> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn active_parachains(&self, _at: &Self::CheckedBlockId) -> Result<Vec<ParaId>> {
|
||||
fn active_parachains(&self, _at: &BlockId) -> Result<Vec<ParaId>> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn parachain_code(&self, _at: &Self::CheckedBlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
fn parachain_code(&self, _at: &BlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn parachain_head(&self, _at: &Self::CheckedBlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
fn parachain_head(&self, _at: &BlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn build_block(&self, _at: &Self::CheckedBlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Self::BlockBuilder> {
|
||||
fn build_block(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Self::BlockBuilder> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
|
||||
fn inherent_extrinsics(&self, _at: &Self::CheckedBlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Vec<Vec<u8>>> {
|
||||
fn inherent_extrinsics(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Vec<Vec<u8>>> {
|
||||
Err(ErrorKind::UnknownRuntime.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<C: Collators, P: PolkadotApi> {
|
||||
parachain: Option<ParaId>,
|
||||
relay_parent_hash: Hash,
|
||||
relay_parent: P::CheckedBlockId,
|
||||
relay_parent: BlockId,
|
||||
collators: C,
|
||||
live_fetch: Option<<C::Collation as IntoFuture>::Future>,
|
||||
client: Arc<P>,
|
||||
@@ -65,7 +65,7 @@ pub struct CollationFetch<C: Collators, P: PolkadotApi> {
|
||||
|
||||
impl<C: Collators, P: PolkadotApi> CollationFetch<C, P> {
|
||||
/// 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<P>) -> Self {
|
||||
pub fn new(parachain: Chain, relay_parent: BlockId, relay_parent_hash: Hash, collators: C, client: Arc<P>) -> 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<P: PolkadotApi>(client: &P, relay_parent: &P::CheckedBlockId, collation: &Collation) -> Result<(), Error> {
|
||||
pub fn validate_collation<P: PolkadotApi>(client: &P, relay_parent: &BlockId, collation: &Collation) -> Result<(), Error> {
|
||||
use parachain::{self, ValidationParams};
|
||||
|
||||
let para_id = collation.receipt.parachain_index;
|
||||
|
||||
@@ -240,7 +240,6 @@ pub struct ProposerFactory<C, N, P> {
|
||||
impl<C, N, P> bft::ProposerFactory<Block> for ProposerFactory<C, N, P>
|
||||
where
|
||||
C: PolkadotApi + Send + Sync,
|
||||
C::CheckedBlockId: Sync,
|
||||
N: Network,
|
||||
P: Collators,
|
||||
{
|
||||
@@ -254,9 +253,9 @@ impl<C, N, P> bft::ProposerFactory<Block> for ProposerFactory<C, N, P>
|
||||
|
||||
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<C, N, P> bft::ProposerFactory<Block> for ProposerFactory<C, N, P>
|
||||
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<C, N, P> bft::ProposerFactory<Block> for ProposerFactory<C, N, P>
|
||||
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<C: PolkadotApi, R, P> {
|
||||
local_duty: LocalDuty,
|
||||
local_key: Arc<ed25519::Pair>,
|
||||
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<C: PolkadotApi, R, P> {
|
||||
impl<C, R, P> bft::Proposer<Block> for Proposer<C, R, P>
|
||||
where
|
||||
C: PolkadotApi + Send + Sync,
|
||||
C::CheckedBlockId: Sync,
|
||||
R: TableRouter,
|
||||
P: Collators,
|
||||
{
|
||||
@@ -621,7 +619,7 @@ impl ProposalTiming {
|
||||
pub struct CreateProposal<C: PolkadotApi, R, P: Collators> {
|
||||
parent_hash: Hash,
|
||||
parent_number: BlockNumber,
|
||||
parent_id: C::CheckedBlockId,
|
||||
parent_id: BlockId,
|
||||
client: Arc<C>,
|
||||
transaction_pool: Arc<TransactionPool<C>>,
|
||||
collation: CollationFetch<P, C>,
|
||||
|
||||
@@ -242,7 +242,6 @@ impl Service {
|
||||
where
|
||||
A: LocalPolkadotApi + Send + Sync + 'static,
|
||||
C: BlockchainEvents<Block> + ChainHead<Block> + bft::BlockImport<Block> + bft::Authorities<Block> + Send + Sync + 'static,
|
||||
A::CheckedBlockId: Sync,
|
||||
{
|
||||
let (signal, exit) = ::exit_future::signal();
|
||||
let thread = thread::spawn(move || {
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<Header, UncheckedExtrinsic>;
|
||||
#[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<Concrete>;
|
||||
|
||||
impl HasPublicAux for Concrete {
|
||||
type PublicAux = AccountId; // TODO: Option<AccountId>
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
+12
@@ -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"
|
||||
|
||||
@@ -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]
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -180,7 +180,7 @@ impl txpool::Scoring<VerifiedTransaction> 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<AccountId, ::primitives::Index>,
|
||||
}
|
||||
@@ -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<VerifiedTransaction> 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<UncheckedExtrinsic> for Verifier<'a, A, A::CheckedBlockId> where
|
||||
impl<'a, A> txpool::Verifier<UncheckedExtrinsic> for Verifier<'a, A> where
|
||||
A: 'a + PolkadotApi,
|
||||
{
|
||||
type VerifiedTransaction = VerifiedTransaction;
|
||||
@@ -322,7 +322,7 @@ impl<A> TransactionPool<A> where
|
||||
pub fn import_unchecked_extrinsic(&self, block: BlockId, uxt: UncheckedExtrinsic) -> Result<Arc<VerifiedTransaction>> {
|
||||
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<A> TransactionPool<A> 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<A> TransactionPool<A> where
|
||||
|
||||
/// Cull old transactions from the queue.
|
||||
pub fn cull(&self, block: BlockId) -> Result<usize> {
|
||||
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<A> TransactionPool<A> where
|
||||
pub fn cull_and_get_pending<F, T>(&self, block: BlockId, f: F) -> Result<T> where
|
||||
F: FnOnce(txpool::PendingIterator<VerifiedTransaction, Ready<A>, Scoring, Listener<Hash>>) -> 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<Block> { 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<TestCheckedBlockId> { Ok(TestCheckedBlockId(id)) }
|
||||
fn session_keys(&self, _at: &TestCheckedBlockId) -> Result<Vec<SessionKey>> { unimplemented!() }
|
||||
fn validators(&self, _at: &TestCheckedBlockId) -> Result<Vec<AccountId>> { unimplemented!() }
|
||||
fn random_seed(&self, _at: &TestCheckedBlockId) -> Result<Hash> { unimplemented!() }
|
||||
fn duty_roster(&self, _at: &TestCheckedBlockId) -> Result<DutyRoster> { unimplemented!() }
|
||||
fn timestamp(&self, _at: &TestCheckedBlockId) -> Result<u64> { unimplemented!() }
|
||||
fn evaluate_block(&self, _at: &TestCheckedBlockId, _block: Block) -> Result<bool> { unimplemented!() }
|
||||
fn active_parachains(&self, _at: &TestCheckedBlockId) -> Result<Vec<ParaId>> { unimplemented!() }
|
||||
fn parachain_code(&self, _at: &TestCheckedBlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> { unimplemented!() }
|
||||
fn parachain_head(&self, _at: &TestCheckedBlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> { unimplemented!() }
|
||||
fn build_block(&self, _at: &TestCheckedBlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Self::BlockBuilder> { unimplemented!() }
|
||||
fn inherent_extrinsics(&self, _at: &TestCheckedBlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Vec<Vec<u8>>> { unimplemented!() }
|
||||
fn session_keys(&self, _at: &BlockId) -> Result<Vec<SessionKey>> { unimplemented!() }
|
||||
fn validators(&self, _at: &BlockId) -> Result<Vec<AccountId>> { unimplemented!() }
|
||||
fn random_seed(&self, _at: &BlockId) -> Result<Hash> { unimplemented!() }
|
||||
fn duty_roster(&self, _at: &BlockId) -> Result<DutyRoster> { unimplemented!() }
|
||||
fn timestamp(&self, _at: &BlockId) -> Result<u64> { unimplemented!() }
|
||||
fn evaluate_block(&self, _at: &BlockId, _block: Block) -> Result<bool> { unimplemented!() }
|
||||
fn active_parachains(&self, _at: &BlockId) -> Result<Vec<ParaId>> { unimplemented!() }
|
||||
fn parachain_code(&self, _at: &BlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> { unimplemented!() }
|
||||
fn parachain_head(&self, _at: &BlockId, _parachain: ParaId) -> Result<Option<Vec<u8>>> { unimplemented!() }
|
||||
fn build_block(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Self::BlockBuilder> { unimplemented!() }
|
||||
fn inherent_extrinsics(&self, _at: &BlockId, _timestamp: Timestamp, _new_heads: Vec<CandidateReceipt>) -> Result<Vec<Vec<u8>>> { unimplemented!() }
|
||||
|
||||
fn index(&self, _at: &TestCheckedBlockId, _account: AccountId) -> Result<Index> {
|
||||
fn index(&self, _at: &BlockId, _account: AccountId) -> Result<Index> {
|
||||
Ok((_account[0] as u32) + number_of(_at))
|
||||
}
|
||||
fn lookup(&self, _at: &TestCheckedBlockId, _address: RawAddress<AccountId, AccountIndex>) -> Result<Option<AccountId>> {
|
||||
fn lookup(&self, _at: &BlockId, _address: RawAddress<AccountId, AccountIndex>) -> Result<Option<AccountId>> {
|
||||
match _address {
|
||||
RawAddress::Id(i) => Ok(Some(i)),
|
||||
RawAddress::Index(_) if self.no_lookup.load(atomic::Ordering::SeqCst) => Ok(None),
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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<E, S, Block>(
|
||||
Block: BlockT,
|
||||
<Block::Header as HeaderT>::Number: As<u32>,
|
||||
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)?);
|
||||
|
||||
@@ -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<B: BlockT> {
|
||||
///
|
||||
/// No changes are made.
|
||||
fn prove_at_state<S: state_machine::Backend>(&self, state: S, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8]) -> Result<(Vec<u8>, Vec<Vec<u8>>), error::Error>;
|
||||
|
||||
/// Get runtime version if supported.
|
||||
fn native_runtime_version(&self) -> Option<RuntimeVersion>;
|
||||
}
|
||||
|
||||
/// Call executor that executes methods locally, querying all required
|
||||
@@ -78,7 +82,7 @@ impl<B, E> Clone for LocalCallExecutor<B, E> where E: Clone {
|
||||
impl<B, E, Block> CallExecutor<Block> for LocalCallExecutor<B, E>
|
||||
where
|
||||
B: backend::LocalBackend<Block>,
|
||||
E: CodeExecutor,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
Block: BlockT,
|
||||
error::Error: From<<<B as backend::Backend<Block>>::State as StateBackend>::Error>,
|
||||
{
|
||||
@@ -111,4 +115,8 @@ impl<B, E, Block> CallExecutor<Block> for LocalCallExecutor<B, E>
|
||||
.map(|(result, proof, _)| (result, proof))
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
fn native_runtime_version(&self) -> Option<RuntimeVersion> {
|
||||
<E as RuntimeInfo>::NATIVE_VERSION
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Block> = mpsc::UnboundedReceiver<BlockImportNotification<Block>>;
|
||||
|
||||
/// Polkadot Client
|
||||
/// Substrate Client
|
||||
pub struct Client<B, E, Block> where Block: BlockT {
|
||||
backend: Arc<B>,
|
||||
executor: E,
|
||||
@@ -146,7 +147,7 @@ pub fn new_in_mem<E, Block, S>(
|
||||
genesis_storage: S
|
||||
) -> error::Result<Client<in_mem::Backend<Block>, LocalCallExecutor<in_mem::Backend<Block>, E>, Block>>
|
||||
where
|
||||
E: CodeExecutor,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
S: BuildStorage,
|
||||
Block: BlockT,
|
||||
{
|
||||
@@ -161,7 +162,7 @@ impl<B, E, Block> Client<B, E, Block> where
|
||||
Block: BlockT,
|
||||
error::Error: From<<<B as backend::Backend<Block>>::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<S: BuildStorage>(
|
||||
backend: Arc<B>,
|
||||
executor: E,
|
||||
@@ -210,11 +211,20 @@ impl<B, E, Block> Client<B, E, Block> where
|
||||
|
||||
/// Get the set of authorities at a given block.
|
||||
pub fn authorities_at(&self, id: &BlockId<Block>) -> error::Result<Vec<AuthorityId>> {
|
||||
self.executor.call(id, "authorities",&[])
|
||||
self.executor.call(id, "authorities", &[])
|
||||
.and_then(|r| Vec::<AuthorityId>::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<Block>) -> error::Result<RuntimeVersion> {
|
||||
// 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<B, E, Block> bft::Authorities<Block> for Client<B, E, Block>
|
||||
error::Error: From<<B::State as state_machine::backend::Backend>::Error>,
|
||||
{
|
||||
fn authorities(&self, at: &BlockId<Block>) -> Result<Vec<AuthorityId>, 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()
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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<Transfer>) -> (Vec<u8>, Hash) {
|
||||
use triehash::ordered_trie_root;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<B, F, Block> CallExecutor<Block> for RemoteCallExecutor<B, F>
|
||||
fn prove_at_state<S: StateBackend>(&self, _state: S, _changes: &mut OverlayedChanges, _method: &str, _call_data: &[u8]) -> ClientResult<(Vec<u8>, Vec<Vec<u8>>)> {
|
||||
Err(ClientErrorKind::NotAvailableOnLightClient.into())
|
||||
}
|
||||
|
||||
fn native_runtime_version(&self) -> Option<RuntimeVersion> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Check remote execution proof using given backend.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<u8> {
|
||||
let len = bytes.len();
|
||||
assert!(len <= u32::max_value() as usize, "Attempted to serialize a collection with too many elements.");
|
||||
|
||||
let mut r: Vec<u8> = Vec::new().and(&(len as u32));
|
||||
r.extend_from_slice(bytes);
|
||||
r
|
||||
}
|
||||
|
||||
impl<T: Slicable, E: Slicable> Slicable for Result<T, E> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
@@ -182,12 +192,7 @@ impl Slicable for Vec<u8> {
|
||||
}
|
||||
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
let len = self.len();
|
||||
assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements.");
|
||||
|
||||
let mut r: Vec<u8> = Vec::new().and(&(len as u32));
|
||||
r.extend_from_slice(self);
|
||||
r
|
||||
encode_slice(&self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<RuntimeVersion>;
|
||||
}
|
||||
|
||||
@@ -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, U>(f: F) -> Result<U>
|
||||
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<Vec<u8>>;
|
||||
|
||||
/// 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<D: NativeExecutionDispatch + Sync + Send> {
|
||||
/// Dummy field to avoid the compiler complaining about us not using `D`.
|
||||
pub _dummy: ::std::marker::PhantomData<D>,
|
||||
_dummy: ::std::marker::PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: NativeExecutionDispatch + Sync + Send> NativeExecutor<D> {
|
||||
/// Create new instance.
|
||||
pub fn new() -> Self {
|
||||
NativeExecutor {
|
||||
_dummy: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: NativeExecutionDispatch + Sync + Send> Clone for NativeExecutor<D> {
|
||||
fn clone(&self) -> Self {
|
||||
NativeExecutor { _dummy: Default::default() }
|
||||
NativeExecutor {
|
||||
_dummy: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: NativeExecutionDispatch + Sync + Send> RuntimeInfo for NativeExecutor<D> {
|
||||
const NATIVE_VERSION: Option<RuntimeVersion> = Some(D::VERSION);
|
||||
}
|
||||
|
||||
impl<D: NativeExecutionDispatch + Sync + Send> CodeExecutor for NativeExecutor<D> {
|
||||
type Error = Error;
|
||||
|
||||
@@ -71,6 +92,11 @@ impl<D: NativeExecutionDispatch + Sync + Send> CodeExecutor for NativeExecutor<D
|
||||
// call native
|
||||
D::dispatch(ext, method, data)
|
||||
} else {
|
||||
let version = WasmExecutor.call(ext, code, "version", &[])?;
|
||||
let version = RuntimeVersion::decode(&mut version.as_slice());
|
||||
if version.map_or(false, |v| D::VERSION.can_call_with(&v)) {
|
||||
return D::dispatch(ext, method, data)
|
||||
}
|
||||
// call into wasm.
|
||||
WasmExecutor.call(ext, code, method, data)
|
||||
}
|
||||
@@ -79,17 +105,18 @@ impl<D: NativeExecutionDispatch + Sync + Send> CodeExecutor for NativeExecutor<D
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! native_executor_instance {
|
||||
(pub $name:ident, $dispatcher:path, $code:expr) => {
|
||||
(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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -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);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "substrate-runtime-version"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[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",
|
||||
]
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! 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<u8> {
|
||||
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<I: codec::Input>(_value: &mut I) -> Option<Self> {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn decode<I: codec::Input>(value: &mut I) -> Option<Self> {
|
||||
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<T: Trait>;
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
/// Get runtime version.
|
||||
pub fn version() -> RuntimeVersion {
|
||||
T::VERSION.clone()
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
@@ -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<u8> {
|
||||
|
||||
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),
|
||||
|
||||
+12
@@ -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]]
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user