diff --git a/Cargo.lock b/Cargo.lock index 21e7829a7bf44..589ed78a04614 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2761,6 +2761,7 @@ version = "0.1.0" dependencies = [ "ed25519 0.1.0", "environmental 0.1.0", + "hashdb 0.2.1 (git+https://github.com/paritytech/parity-common)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-codec 0.1.0", "substrate-primitives 0.1.0", diff --git a/substrate/client/src/block_builder.rs b/substrate/client/src/block_builder.rs index 30216f4157f27..5dd90526080b5 100644 --- a/substrate/client/src/block_builder.rs +++ b/substrate/client/src/block_builder.rs @@ -24,9 +24,9 @@ use runtime_primitives::generic::BlockId; use {backend, error, Client, CallExecutor}; use runtime_primitives::{ApplyResult, ApplyOutcome}; use patricia_trie::NodeCodec; -use primitives::{KeccakHasher, RlpCodec}; use hashdb::Hasher; use rlp::Encodable; +use heapsize::HeapSizeOf; /// Utility for building new (valid) blocks from a stream of extrinsics. pub struct BlockBuilder @@ -45,20 +45,23 @@ where changes: state_machine::OverlayedChanges, } -impl BlockBuilder +impl BlockBuilder where - B: backend::Backend, - E: CallExecutor + Clone, + B: backend::Backend, + E: CallExecutor + Clone, Block: BlockT, + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec { /// Create a new instance of builder from the given client, building on the latest block. - pub fn new(client: &Client) -> error::Result { + pub fn new(client: &Client) -> error::Result { client.info().and_then(|i| Self::at_block(&BlockId::Hash(i.chain.best_hash), client)) } /// Create a new instance of builder from the given client using a particular block's ID to /// build upon. - pub fn at_block(block_id: &BlockId, client: &Client) -> error::Result { + pub fn at_block(block_id: &BlockId, client: &Client) -> error::Result { let number = client.block_number_from_id(block_id)? .ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{}", block_id)))? + One::one(); diff --git a/substrate/client/src/call_executor.rs b/substrate/client/src/call_executor.rs index 6da6d0a04f00b..21619c4d58fda 100644 --- a/substrate/client/src/call_executor.rs +++ b/substrate/client/src/call_executor.rs @@ -23,9 +23,10 @@ use state_machine::{self, OverlayedChanges, Ext, use runtime_io::Externalities; use executor::{RuntimeVersion, RuntimeInfo}; use patricia_trie::NodeCodec; -use primitives::{KeccakHasher, RlpCodec}; use hashdb::Hasher; use rlp::Encodable; +use std::marker::PhantomData; +use heapsize::HeapSizeOf; use backend; use error; @@ -94,32 +95,39 @@ where /// Call executor that executes methods locally, querying all required /// data from local backend. -pub struct LocalCallExecutor { +pub struct LocalCallExecutor { backend: Arc, executor: E, + _hasher: PhantomData, + _codec: PhantomData, } -impl LocalCallExecutor { +impl LocalCallExecutor { /// Creates new instance of local call executor. pub fn new(backend: Arc, executor: E) -> Self { - LocalCallExecutor { backend, executor } + LocalCallExecutor { backend, executor, _hasher: PhantomData, _codec: PhantomData } } } -impl Clone for LocalCallExecutor where E: Clone { +impl Clone for LocalCallExecutor where E: Clone { fn clone(&self) -> Self { LocalCallExecutor { backend: self.backend.clone(), executor: self.executor.clone(), + _hasher: PhantomData, + _codec: PhantomData, } } } -impl CallExecutor for LocalCallExecutor +impl CallExecutor for LocalCallExecutor where - B: backend::LocalBackend, - E: CodeExecutor + RuntimeInfo, + B: backend::LocalBackend, + E: CodeExecutor + RuntimeInfo, Block: BlockT, + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec { type Error = E::Error; @@ -151,7 +159,7 @@ where } fn call_at_state< - S: state_machine::Backend, + S: state_machine::Backend, F: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, >(&self, state: &S, @@ -170,7 +178,7 @@ where ).map_err(Into::into) } - fn prove_at_state>(&self, + fn prove_at_state>(&self, state: S, changes: &mut OverlayedChanges, method: &str, @@ -188,6 +196,6 @@ where } fn native_runtime_version(&self) -> Option { - ::NATIVE_VERSION + >::NATIVE_VERSION } } diff --git a/substrate/client/src/client.rs b/substrate/client/src/client.rs index 2bd8e9f8a6863..bfd87531fd7dd 100644 --- a/substrate/client/src/client.rs +++ b/substrate/client/src/client.rs @@ -23,7 +23,10 @@ use primitives::AuthorityId; use runtime_primitives::{bft::Justification, generic::{BlockId, SignedBlock, Block as RuntimeBlock}}; use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, One, As, NumberFor}; use runtime_primitives::BuildStorage; -use primitives::{KeccakHasher, RlpCodec}; +use hashdb::Hasher; +use heapsize::HeapSizeOf; +use patricia_trie::NodeCodec; +use rlp::Encodable; use primitives::storage::{StorageKey, StorageData}; use codec::Decode; use state_machine::{ @@ -37,12 +40,13 @@ use call_executor::{CallExecutor, LocalCallExecutor}; use executor::{RuntimeVersion, RuntimeInfo}; use notifications::{StorageNotifications, StorageEventStream}; use {error, in_mem, block_builder, runtime_io, bft, genesis}; +use std::marker::PhantomData; /// Type that implements `futures::Stream` of block import events. pub type BlockchainEventStream = mpsc::UnboundedReceiver>; /// Substrate Client -pub struct Client where Block: BlockT { +pub struct Client where Block: BlockT { backend: Arc, executor: E, storage_notifications: Mutex>, @@ -50,6 +54,8 @@ pub struct Client where Block: BlockT { import_lock: Mutex<()>, importing_block: RwLock>, // holds the block hash currently being imported. TODO: replace this with block queue execution_strategy: ExecutionStrategy, + _hasher: PhantomData, // TODO: feels like these shouldn't be necesseary + _codec: PhantomData, } /// A source of blockchain evenets. @@ -161,24 +167,35 @@ impl JustifiedHeader { } /// Create an instance of in-memory client. -pub fn new_in_mem( +pub fn new_in_mem( executor: E, genesis_storage: S, -) -> error::Result, LocalCallExecutor, E>, Block>> +) -> error::Result, + LocalCallExecutor, E, H, C>, + Block, + H, + C>> where - E: CodeExecutor + RuntimeInfo, + E: CodeExecutor + RuntimeInfo, S: BuildStorage, Block: BlockT, + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec + Send + Sync, { let backend = Arc::new(in_mem::Backend::new()); let executor = LocalCallExecutor::new(backend.clone(), executor); Client::new(backend, executor, genesis_storage, ExecutionStrategy::NativeWhenPossible) } -impl Client where - B: backend::Backend, - E: CallExecutor, +impl Client where + B: backend::Backend, + E: CallExecutor, Block: BlockT, + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec, { /// Creates new Substrate Client with given blockchain and code executor. pub fn new( @@ -204,6 +221,8 @@ impl Client where import_lock: Default::default(), importing_block: Default::default(), execution_strategy, + _hasher: PhantomData, + _codec: PhantomData, }) } @@ -285,14 +304,14 @@ impl Client where } /// Create a new block, built on the head of the chain. - pub fn new_block(&self) -> error::Result> + pub fn new_block(&self) -> error::Result> where E: Clone { block_builder::BlockBuilder::new(self) } /// Create a new block, built on top of `parent`. - pub fn new_block_at(&self, parent: &BlockId) -> error::Result> + pub fn new_block_at(&self, parent: &BlockId) -> error::Result> where E: Clone { block_builder::BlockBuilder::at_block(parent, &self) @@ -507,11 +526,14 @@ impl Client where } } -impl bft::BlockImport for Client - where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, +impl bft::BlockImport for Client +where + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec, + B: backend::Backend, + E: CallExecutor, + Block: BlockT, { fn import_block( &self, @@ -530,11 +552,14 @@ impl bft::BlockImport for Client } } -impl bft::Authorities for Client - where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, +impl bft::Authorities for Client +where + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec, + B: backend::Backend, + E: CallExecutor, + Block: BlockT, { fn authorities(&self, at: &BlockId) -> Result, bft::Error> { let on_chain_version: Result<_, bft::Error> = self.runtime_version_at(at) @@ -553,9 +578,12 @@ impl bft::Authorities for Client } } -impl BlockchainEvents for Client +impl BlockchainEvents for Client where - E: CallExecutor, + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec, + E: CallExecutor, Block: BlockT, { /// Get block import event stream. @@ -571,10 +599,13 @@ where } } -impl ChainHead for Client +impl ChainHead for Client where - B: backend::Backend, - E: CallExecutor, + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec, + B: backend::Backend, + E: CallExecutor, Block: BlockT, { fn best_block_header(&self) -> error::Result<::Header> { @@ -582,11 +613,14 @@ where } } -impl BlockBody for Client - where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, +impl BlockBody for Client +where + H: Hasher, + H::Out: Ord + Encodable + HeapSizeOf, + C: NodeCodec, + B: backend::Backend, + E: CallExecutor, + Block: BlockT, { fn block_body(&self, id: &BlockId) -> error::Result::Extrinsic>>> { self.body(id) diff --git a/substrate/client/src/light/call_executor.rs b/substrate/client/src/light/call_executor.rs index cdbd7ac727932..340a0d30d9797 100644 --- a/substrate/client/src/light/call_executor.rs +++ b/substrate/client/src/light/call_executor.rs @@ -28,7 +28,6 @@ use primitives::H256; use patricia_trie::NodeCodec; use hashdb::Hasher; use rlp::Encodable; -use primitives::{KeccakHasher, RlpCodec}; use blockchain::Backend as ChainBackend; use call_executor::{CallExecutor, CallResult}; @@ -37,26 +36,32 @@ use light::fetcher::{Fetcher, RemoteCallRequest}; use executor::RuntimeVersion; use codec::Decode; use heapsize::HeapSizeOf; +use std::marker::PhantomData; /// Call executor that executes methods on remote node, querying execution proof /// and checking proof by re-executing locally. -pub struct RemoteCallExecutor { +pub struct RemoteCallExecutor { blockchain: Arc, fetcher: Arc, + _hasher: PhantomData, + _codec: PhantomData, } -impl RemoteCallExecutor { +impl RemoteCallExecutor { /// Creates new instance of remote call executor. pub fn new(blockchain: Arc, fetcher: Arc) -> Self { - RemoteCallExecutor { blockchain, fetcher } + RemoteCallExecutor { blockchain, fetcher, _hasher: PhantomData, _codec: PhantomData } } } -impl CallExecutor for RemoteCallExecutor - where - Block: BlockT, - B: ChainBackend, - F: Fetcher, +impl CallExecutor for RemoteCallExecutor +where + Block: BlockT, + B: ChainBackend, + F: Fetcher, + H: Hasher, + H::Out: Ord + Encodable, + C: NodeCodec { type Error = ClientError; @@ -83,7 +88,7 @@ impl CallExecutor for RemoteCallExec } fn call_at_state< - S: StateBackend, + S: StateBackend, FF: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error> >(&self, _state: &S, @@ -95,7 +100,7 @@ impl CallExecutor for RemoteCallExec Err(ClientErrorKind::NotAvailableOnLightClient.into()) } - fn prove_at_state>( + fn prove_at_state>( &self, _state: S, _changes: &mut OverlayedChanges, diff --git a/substrate/client/src/light/mod.rs b/substrate/client/src/light/mod.rs index ba175b14a883d..ceb39db0f419f 100644 --- a/substrate/client/src/light/mod.rs +++ b/substrate/client/src/light/mod.rs @@ -23,6 +23,7 @@ pub mod fetcher; use std::sync::Arc; +use primitives::{KeccakHasher, RlpCodec}; use runtime_primitives::BuildStorage; use runtime_primitives::traits::Block as BlockT; use state_machine::{CodeExecutor, ExecutionStrategy}; @@ -52,7 +53,7 @@ pub fn new_light( backend: Arc>, fetcher: Arc, genesis_storage: GS, -) -> ClientResult, RemoteCallExecutor, F>, B>> +) -> ClientResult, RemoteCallExecutor, F, KeccakHasher, RlpCodec>, B, KeccakHasher, RlpCodec>> where B: BlockT, S: BlockchainStorage, diff --git a/substrate/executor/src/lib.rs b/substrate/executor/src/lib.rs index f0605849d5fa1..813178d4d6a28 100644 --- a/substrate/executor/src/lib.rs +++ b/substrate/executor/src/lib.rs @@ -76,15 +76,15 @@ pub use native_executor::{with_native_environment, NativeExecutor, NativeExecuti pub use state_machine::Externalities; pub use runtime_version::RuntimeVersion; pub use codec::Codec; -use primitives::KeccakHasher; +use hashdb::Hasher; /// Provides runtime information. -pub trait RuntimeInfo { +pub trait RuntimeInfo { /// Native runtime information if any. const NATIVE_VERSION: Option; /// Extract RuntimeVersion of given :code block - fn runtime_version> ( + fn runtime_version> ( &self, ext: &mut E, code: &[u8] diff --git a/substrate/executor/src/native_executor.rs b/substrate/executor/src/native_executor.rs index c1bd44fd935d8..d7ebf44f78c8e 100644 --- a/substrate/executor/src/native_executor.rs +++ b/substrate/executor/src/native_executor.rs @@ -149,7 +149,7 @@ impl Clone for NativeExecutor { } } -impl RuntimeInfo for NativeExecutor { +impl RuntimeInfo for NativeExecutor { const NATIVE_VERSION: Option = Some(D::VERSION); fn runtime_version>( diff --git a/substrate/runtime-io/Cargo.toml b/substrate/runtime-io/Cargo.toml index b46f9909c2018..7fb56926c44e0 100644 --- a/substrate/runtime-io/Cargo.toml +++ b/substrate/runtime-io/Cargo.toml @@ -15,6 +15,7 @@ substrate-primitives = { path = "../primitives", default_features = false } substrate-codec = { path = "../codec", default_features = false } triehash = { version = "0.1.2", optional = true } ed25519 = { path = "../ed25519", optional = true } +hashdb = { git = "https://github.com/paritytech/parity-common", optional = true } [features] default = ["std"] @@ -26,6 +27,7 @@ std = [ "substrate-codec/std", "substrate-runtime-std/std", "ed25519", + "hashdb" ] nightly = [] strict = [] diff --git a/substrate/runtime-io/with_std.rs b/substrate/runtime-io/with_std.rs index f543b8ae2c893..d50f26cb2b75d 100644 --- a/substrate/runtime-io/with_std.rs +++ b/substrate/runtime-io/with_std.rs @@ -23,6 +23,7 @@ extern crate substrate_primitives as primitives; extern crate substrate_state_machine; extern crate triehash; extern crate ed25519; +extern crate hashdb; #[doc(hidden)] pub extern crate substrate_codec as codec; @@ -30,6 +31,7 @@ pub extern crate substrate_codec as codec; pub use primitives::{blake2_256, twox_128, twox_256}; pub use primitives::KeccakHasher; +use hashdb::Hasher; // Switch to this after PoC-3 // pub use primitives::BlakeHasher; pub use substrate_state_machine::{Externalities, TestExternalities}; @@ -130,8 +132,8 @@ pub fn ed25519_verify>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> /// Execute the given closure with global function available whose functionality routes into the /// externalities `ext`. Forwards the value that the closure returns. // NOTE: need a concrete hasher here due to limitations of the `environmental!` macro, otherwise a type param would have been fine I think. -pub fn with_externalities R>(ext: &mut Externalities, f: F) -> R { - ext::using(ext, f) +pub fn with_externalities R>(ext: &mut Externalities, f: F) -> R { + ext::using(ext, f) // REVIEW: this is where the limitations of the `environmental!` macro comes in. Any way to get around this? } /// Trait for things which can be printed. diff --git a/substrate/test-client/src/lib.rs b/substrate/test-client/src/lib.rs index 6a7e52a20103c..5773ae9ccbffa 100644 --- a/substrate/test-client/src/lib.rs +++ b/substrate/test-client/src/lib.rs @@ -53,7 +53,12 @@ pub use local_executor::LocalExecutor; pub type Backend = client::in_mem::Backend; /// Test client executor. -pub type Executor = client::LocalCallExecutor>; +pub type Executor = client::LocalCallExecutor< + Backend, + executor::NativeExecutor, + KeccakHasher, + RlpCodec + >; /// Creates new client instance used for tests. pub fn new() -> client::Client {