From 718ba4e159ceeae77beb8e4a2ada4ab6096ae4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 26 Sep 2018 18:57:30 +0200 Subject: [PATCH] Remove `node-api` (#804) * Remove `node-api` from `node-consensus` and `node-transaction-pool` * Remove the `node-api` crate and its last usages * Remove left over file * Fixes compilation errors * Switch to `As` trait * Rename trait * Whitespace --- substrate/Cargo.lock | 17 +- substrate/Cargo.toml | 1 - substrate/node/api/Cargo.toml | 14 -- substrate/node/api/src/lib.rs | 167 --------------- substrate/node/consensus/Cargo.toml | 2 +- substrate/node/consensus/src/error.rs | 3 +- substrate/node/consensus/src/evaluation.rs | 26 +-- substrate/node/consensus/src/lib.rs | 213 ++++++++++++++----- substrate/node/consensus/src/service.rs | 28 ++- substrate/node/network/Cargo.toml | 1 - substrate/node/network/src/consensus.rs | 6 +- substrate/node/network/src/lib.rs | 2 - substrate/node/service/Cargo.toml | 1 - substrate/node/service/src/lib.rs | 6 +- substrate/node/transaction-pool/Cargo.toml | 1 - substrate/node/transaction-pool/src/error.rs | 4 +- substrate/node/transaction-pool/src/lib.rs | 81 ++++--- 17 files changed, 255 insertions(+), 318 deletions(-) delete mode 100644 substrate/node/api/Cargo.toml delete mode 100644 substrate/node/api/src/lib.rs diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 4185a78af5..675015c29d 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -1586,18 +1586,6 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "node-api" -version = "0.1.0" -dependencies = [ - "node-primitives 0.1.0", - "node-runtime 0.1.0", - "sr-primitives 0.1.0", - "substrate-client 0.1.0", - "substrate-keyring 0.1.0", - "substrate-primitives 0.1.0", -] - [[package]] name = "node-cli" version = "0.1.0" @@ -1617,7 +1605,6 @@ dependencies = [ "exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "node-api 0.1.0", "node-primitives 0.1.0", "node-runtime 0.1.0", "node-transaction-pool 0.1.0", @@ -1625,6 +1612,7 @@ dependencies = [ "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rhododendron 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 0.1.0", + "srml-system 0.1.0", "substrate-bft 0.1.0", "substrate-client 0.1.0", "substrate-keyring 0.1.0", @@ -1664,7 +1652,6 @@ version = "0.1.0" dependencies = [ "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "node-api 0.1.0", "node-consensus 0.1.0", "node-primitives 0.1.0", "rhododendron 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1729,7 +1716,6 @@ dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "node-api 0.1.0", "node-consensus 0.1.0", "node-executor 0.1.0", "node-network 0.1.0", @@ -1753,7 +1739,6 @@ version = "0.1.0" dependencies = [ "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "node-api 0.1.0", "node-primitives 0.1.0", "node-runtime 0.1.0", "parity-codec 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/substrate/Cargo.toml b/substrate/Cargo.toml index 9cabf9e8f1..61cf53004f 100644 --- a/substrate/Cargo.toml +++ b/substrate/Cargo.toml @@ -60,7 +60,6 @@ members = [ "core/trie", "core/keystore", "node/cli", - "node/api", "node/consensus", "node/executor", "node/network", diff --git a/substrate/node/api/Cargo.toml b/substrate/node/api/Cargo.toml deleted file mode 100644 index d7771a66d2..0000000000 --- a/substrate/node/api/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "node-api" -version = "0.1.0" -authors = ["Parity Technologies "] - -[dependencies] -node-runtime = { path = "../runtime" } -node-primitives = { path = "../primitives" } -substrate-client = { path = "../../core/client" } -substrate-primitives = { path = "../../core/primitives" } -sr-primitives = { path = "../../core/sr-primitives" } - -[dev-dependencies] -substrate-keyring = { path = "../../core/keyring" } diff --git a/substrate/node/api/src/lib.rs b/substrate/node/api/src/lib.rs deleted file mode 100644 index 7c5e539422..0000000000 --- a/substrate/node/api/src/lib.rs +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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 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. If not, see . - -//! Strongly typed API for Substrate runtime. - -#![warn(missing_docs)] -#![warn(unused_extern_crates)] - -extern crate node_primitives as primitives; -extern crate node_runtime as runtime; -extern crate substrate_client as client; -extern crate sr_primitives; -extern crate substrate_primitives; - -pub use client::error::{Error, ErrorKind, Result}; -use runtime::Address; -use client::backend::Backend; -use client::block_builder::BlockBuilder as ClientBlockBuilder; -use client::{Client, CallExecutor}; -use primitives::{ - AccountId, Block, BlockId, BlockNumber, Hash, Index, InherentData, SessionKey, Timestamp, UncheckedExtrinsic -}; -use sr_primitives::{transaction_validity::TransactionValidity, traits::{CurrentHeight, BlockNumberToHash}}; -use substrate_primitives::{Blake2Hasher}; - -/// Build new blocks. -pub trait BlockBuilder { - /// Push an extrinsic onto the block. Fails if the extrinsic is invalid. - fn push_extrinsic(&mut self, extrinsic: UncheckedExtrinsic) -> Result<()>; - - /// Bake the block with provided extrinsics. - fn bake(self) -> Result; -} - -/// Trait encapsulating the node API. -/// -/// All calls should fail when the exact runtime is unknown. -pub trait Api: CurrentHeight + BlockNumberToHash { - /// The block builder for this API type. - type BlockBuilder: BlockBuilder; - - /// Get session keys at a given block. - fn session_keys(&self, at: &BlockId) -> Result>; - - /// Get validators at a given block. - fn validators(&self, at: &BlockId) -> Result>; - - /// Get the value of the randomness beacon at a given block. - fn random_seed(&self, at: &BlockId) -> Result; - - /// Get the timestamp registered at a block. - fn timestamp(&self, at: &BlockId) -> Result; - - // TODO: remove in favour of validate_transaction - - /// Get the nonce (né index) of an account at a block. - fn index(&self, at: &BlockId, account: AccountId) -> Result; - - /// Get the account id of an address at a block. - fn lookup(&self, at: &BlockId, address: Address) -> Result>; - - /// Validate a transaction and determine its dependencies. - fn validate_transaction(&self, at: &BlockId, transaction: UncheckedExtrinsic) -> 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: &BlockId, block: Block) -> Result; - - /// Build a block on top of the given, with inherent extrinsics pre-pushed. - fn build_block(&self, at: &BlockId, inherent_data: InherentData) -> 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: &BlockId, inherent_data: InherentData) -> Result>; -} - -impl BlockBuilder for ClientBlockBuilder -where - B: Backend, - E: CallExecutor + Clone, -{ - fn push_extrinsic(&mut self, extrinsic: UncheckedExtrinsic) -> Result<()> { - self.push(extrinsic).map_err(Into::into) - } - - /// Bake the block with provided extrinsics. - fn bake(self) -> Result { - ClientBlockBuilder::bake(self).map_err(Into::into) - } -} - -impl Api for Client -where - B: Backend, - E: CallExecutor + Clone, -{ - type BlockBuilder = ClientBlockBuilder; - - fn session_keys(&self, at: &BlockId) -> Result> { - Ok(self.authorities_at(at)?) - } - - fn validators(&self, at: &BlockId) -> Result> { - self.call_api_at(at, "validators", &()) - } - - fn random_seed(&self, at: &BlockId) -> Result { - self.call_api_at(at, "random_seed", &()) - } - - fn timestamp(&self, at: &BlockId) -> Result { - self.call_api_at(at, "timestamp", &()) - } - - fn evaluate_block(&self, at: &BlockId, block: Block) -> Result { - let res: Result<()> = self.call_api_at(at, "execute_block", &block); - match res { - Ok(()) => Ok(true), - Err(err) => match err.kind() { - &client::error::ErrorKind::Execution(_) => Ok(false), - _ => Err(err) - } - } - } - - fn index(&self, at: &BlockId, account: AccountId) -> Result { - self.call_api_at(at, "account_nonce", &account) - } - - fn lookup(&self, at: &BlockId, address: Address) -> Result> { - self.call_api_at(at, "lookup_address", &address) - } - - fn validate_transaction(&self, at: &BlockId, tx: UncheckedExtrinsic) -> Result { - self.call_api_at(at, "validate_transaction", &tx) - } - - fn build_block(&self, at: &BlockId, inherent_data: InherentData) -> Result { - let runtime_version = self.runtime_version_at(at)?; - - let mut block_builder = self.new_block_at(at)?; - if runtime_version.has_api(*b"inherent", 1) { - for inherent in self.inherent_extrinsics(at, inherent_data)? { - block_builder.push(inherent)?; - } - } - Ok(block_builder) - } - - fn inherent_extrinsics(&self, at: &BlockId, inherent_data: InherentData) -> Result> { - self.call_api_at(at, "inherent_extrinsics", &inherent_data) - } -} - diff --git a/substrate/node/consensus/Cargo.toml b/substrate/node/consensus/Cargo.toml index a55e1c045d..3cd28df4f2 100644 --- a/substrate/node/consensus/Cargo.toml +++ b/substrate/node/consensus/Cargo.toml @@ -11,7 +11,6 @@ error-chain = "0.12" log = "0.3" exit-future = "0.1" rhododendron = "0.3" -node-api = { path = "../api" } node-primitives = { path = "../primitives" } node-runtime = { path = "../runtime" } node-transaction-pool = { path = "../transaction-pool" } @@ -20,6 +19,7 @@ parity-codec = { version = "2.0" } substrate-primitives = { path = "../../core/primitives" } substrate-client = { path = "../../core/client" } sr-primitives = { path = "../../core/sr-primitives" } +srml-system = { path = "../../srml/system" } [dev-dependencies] substrate-keyring = { path = "../../core/keyring" } diff --git a/substrate/node/consensus/src/error.rs b/substrate/node/consensus/src/error.rs index 01823a8e50..13192ae202 100644 --- a/substrate/node/consensus/src/error.rs +++ b/substrate/node/consensus/src/error.rs @@ -17,10 +17,11 @@ //! Errors that can occur during the consensus process. use primitives::AuthorityId; +use client; error_chain! { links { - Api(::node_api::Error, ::node_api::ErrorKind); + Client(client::error::Error, client::error::ErrorKind); Bft(::bft::Error, ::bft::ErrorKind); } diff --git a/substrate/node/consensus/src/evaluation.rs b/substrate/node/consensus/src/evaluation.rs index 9d4d5b0911..fb860a6430 100644 --- a/substrate/node/consensus/src/evaluation.rs +++ b/substrate/node/consensus/src/evaluation.rs @@ -20,13 +20,11 @@ use super::MAX_TRANSACTIONS_SIZE; use codec::{Decode, Encode}; use node_runtime::{Block as GenericBlock, CheckedBlock}; -use node_primitives::{Block, Hash, BlockNumber, Timestamp}; +use node_primitives::{Hash, BlockNumber, Timestamp}; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As}; + error_chain! { - links { - Api(::node_api::Error, ::node_api::ErrorKind); - } - errors { BadProposalFormat { description("Proposal provided not a block."), @@ -56,12 +54,16 @@ error_chain! { /// Attempt to evaluate a substrate block as a node block, returning error /// upon any initial validity checks failing. -pub fn evaluate_initial( +pub fn evaluate_initial( proposal: &Block, now: Timestamp, parent_hash: &Hash, - parent_number: BlockNumber, -) -> Result { + parent_number: <::Header as HeaderT>::Number, +) -> Result +where + Hash: PartialEq<<::Header as HeaderT>::Hash>, + Hash: Into + Clone, +{ const MAX_TIMESTAMP_DRIFT: Timestamp = 60; let encoded = Encode::encode(proposal); @@ -77,12 +79,12 @@ pub fn evaluate_initial( bail!(ErrorKind::ProposalTooLarge(transactions_size)) } - if proposal.header.parent_hash != *parent_hash { - bail!(ErrorKind::WrongParentHash(*parent_hash, proposal.header.parent_hash)); + if *parent_hash != *proposal.header().parent_hash() { + bail!(ErrorKind::WrongParentHash((*parent_hash).clone().into(), proposal.header.parent_hash)); } - if proposal.header.number != parent_number + 1 { - bail!(ErrorKind::WrongNumber(parent_number + 1, proposal.header.number)); + if parent_number.as_() + 1 != *proposal.header().number() { + bail!(ErrorKind::WrongNumber(parent_number.as_() + 1, proposal.header.number)); } let block_timestamp = proposal.timestamp(); diff --git a/substrate/node/consensus/src/lib.rs b/substrate/node/consensus/src/lib.rs index dcb6e0441f..d05524590d 100644 --- a/substrate/node/consensus/src/lib.rs +++ b/substrate/node/consensus/src/lib.rs @@ -17,7 +17,6 @@ //! This service uses BFT consensus provided by the substrate. extern crate parking_lot; -extern crate node_api; extern crate node_transaction_pool as transaction_pool; extern crate node_runtime; extern crate node_primitives; @@ -26,6 +25,7 @@ extern crate substrate_bft as bft; extern crate parity_codec as codec; extern crate substrate_primitives as primitives; extern crate sr_primitives as runtime_primitives; +extern crate srml_system; extern crate substrate_client as client; extern crate exit_future; @@ -45,12 +45,15 @@ extern crate substrate_keyring; use std::sync::Arc; use std::time::{self, Duration, Instant}; +use client::{Client as SubstrateClient, CallExecutor}; use codec::{Decode, Encode}; -use node_api::Api; -use node_primitives::{AccountId, Hash, Block, BlockId, BlockNumber, Header, Timestamp, SessionKey}; -use runtime_primitives::generic::Era; -use primitives::{AuthorityId, ed25519}; -use transaction_pool::TransactionPool; +use node_primitives::{AccountId, Timestamp, SessionKey, InherentData}; +use node_runtime::Runtime; +use primitives::{AuthorityId, ed25519, Blake2Hasher}; +use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, As}; +use runtime_primitives::generic::{BlockId, Era}; +use srml_system::Trait as SystemT; +use transaction_pool::{TransactionPool, Client as TPClient}; use tokio::runtime::TaskExecutor; use tokio::timer::Delay; @@ -58,7 +61,7 @@ use futures::prelude::*; use futures::future; use parking_lot::RwLock; -pub use self::error::{ErrorKind, Error}; +pub use self::error::{ErrorKind, Error, Result}; pub use self::offline_tracker::OfflineTracker; pub use service::Service; @@ -73,33 +76,133 @@ pub type SharedOfflineTracker = Arc>; // block size limit. const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024; +/// Build new blocks. +pub trait BlockBuilder { + /// Push an extrinsic onto the block. Fails if the extrinsic is invalid. + fn push_extrinsic(&mut self, extrinsic: ::Extrinsic) -> Result<()>; + + /// Bake the block with provided extrinsics. + fn bake(self) -> Result; +} + +/// Local client abstraction for the consensus. +pub trait AuthoringApi: Send + Sync { + /// The block used for this API type. + type Block: BlockT; + /// The block builder for this API type. + type BlockBuilder: BlockBuilder; + + /// Get the value of the randomness beacon at a given block. + fn random_seed(&self, at: &BlockId) -> Result<::Hash>; + + /// Get validators at a given block. + fn validators(&self, at: &BlockId) -> Result>; + + /// Build a block on top of the given, with inherent extrinsics pre-pushed. + fn build_block(&self, at: &BlockId, inherent_data: InherentData) -> Result; + + /// Get the nonce (né index) of an account at a block. + fn index(&self, at: &BlockId, account: AccountId) -> 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: &BlockId, inherent_data: InherentData) -> Result::Extrinsic>>; + + /// 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: &BlockId, block: Self::Block) -> Result; +} + +impl BlockBuilder for client::block_builder::BlockBuilder where + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT +{ + fn push_extrinsic(&mut self, extrinsic: ::Extrinsic) -> Result<()> { + client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into) + } + + fn bake(self) -> Result { + client::block_builder::BlockBuilder::bake(self).map_err(Into::into) + } +} + +impl AuthoringApi for SubstrateClient where + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT, +{ + type Block = Block; + type BlockBuilder = client::block_builder::BlockBuilder; + + fn random_seed(&self, at: &BlockId) -> Result<::Hash> { + self.call_api_at(at, "random_seed", &()).map_err(Into::into) + } + + fn validators(&self, at: &BlockId) -> Result> { + self.call_api_at(at, "validators", &()).map_err(Into::into) + } + + fn build_block(&self, at: &BlockId, inherent_data: InherentData) -> Result { + let runtime_version = self.runtime_version_at(at)?; + + let mut block_builder = self.new_block_at(at)?; + if runtime_version.has_api(*b"inherent", 1) { + for inherent in self.inherent_extrinsics(at, inherent_data)? { + block_builder.push(inherent)?; + } + } + Ok(block_builder) + } + + fn index(&self, at: &BlockId, account: AccountId) -> Result { + self.call_api_at(at, "account_nonce", &account).map_err(Into::into) + } + + fn inherent_extrinsics(&self, at: &BlockId, inherent_data: InherentData) -> Result::Extrinsic>> { + self.call_api_at(at, "inherent_extrinsics", &inherent_data).map_err(Into::into) + } + + fn evaluate_block(&self, at: &BlockId, block: Self::Block) -> Result { + let res: client::error::Result<()> = self.call_api_at(at, "execute_block", &block); + match res { + Ok(()) => Ok(true), + Err(err) => match err.kind() { + &client::error::ErrorKind::Execution(_) => Ok(false), + _ => Err(err.into()) + } + } + } +} + /// A long-lived network which can create BFT message routing processes on demand. pub trait Network { + /// The block used for this API type. + type Block: BlockT; /// The input stream of BFT messages. Should never logically conclude. - type Input: Stream,Error=Error>; + type Input: Stream,Error=Error>; /// The output sink of BFT messages. Messages sent here should eventually pass to all /// current authorities. - type Output: Sink,SinkError=Error>; + type Output: Sink,SinkError=Error>; /// Instantiate input and output streams. fn communication_for( &self, validators: &[SessionKey], local_id: SessionKey, - parent_hash: Hash, + parent_hash: ::Hash, task_executor: TaskExecutor ) -> (Self::Input, Self::Output); } /// Proposer factory. -pub struct ProposerFactory - where - P: Api + Send + Sync + 'static +pub struct ProposerFactory where + C: AuthoringApi + TPClient, { /// The client instance. - pub client: Arc

, + pub client: Arc, /// The transaction pool. - pub transaction_pool: Arc>, + pub transaction_pool: Arc>, /// The backing network handle. pub network: N, /// handle to remote task executor @@ -108,32 +211,31 @@ pub struct ProposerFactory pub offline: SharedOfflineTracker, } -impl bft::Environment for ProposerFactory - where - N: Network, - P: Api + Send + Sync + 'static, +impl bft::Environment<::Block> for ProposerFactory where + N: Network::Block>, + C: AuthoringApi + TPClient::Block>, + <::Block as BlockT>::Hash: + Into<::Hash> + PartialEq + Into { - type Proposer = Proposer

; + type Proposer = Proposer; type Input = N::Input; type Output = N::Output; type Error = Error; fn init( &self, - parent_header: &Header, + parent_header: &<::Block as BlockT>::Header, authorities: &[AuthorityId], sign_with: Arc, - ) -> Result<(Self::Proposer, Self::Input, Self::Output), Error> { - use runtime_primitives::traits::{Hash as HashT, BlakeTwo256}; - + ) -> Result<(Self::Proposer, Self::Input, Self::Output)> { // force delay in evaluation this long. const FORCE_DELAY: Timestamp = 5; - let parent_hash = parent_header.hash().into(); + let parent_hash = parent_header.hash(); let id = BlockId::hash(parent_hash); let random_seed = self.client.random_seed(&id)?; - let random_seed = BlakeTwo256::hash(&*random_seed); + let random_seed = <<::Block as BlockT>::Header as HeaderT>::Hashing::hash(random_seed.as_ref()); let validators = self.client.validators(&id)?; self.offline.write().note_new_block(&validators[..]); @@ -154,7 +256,7 @@ impl bft::Environment for ProposerFactory local_key: sign_with, parent_hash, parent_id: id, - parent_number: parent_header.number, + parent_number: *parent_header.number(), random_seed, transaction_pool: self.transaction_pool.clone(), offline: self.offline.clone(), @@ -167,43 +269,42 @@ impl bft::Environment for ProposerFactory } /// The proposer logic. -pub struct Proposer { +pub struct Proposer { client: Arc, start: Instant, local_key: Arc, - parent_hash: Hash, - parent_id: BlockId, - parent_number: BlockNumber, - random_seed: Hash, + parent_hash: <::Block as BlockT>::Hash, + parent_id: BlockId<::Block>, + parent_number: <<::Block as BlockT>::Header as HeaderT>::Number, + random_seed: <::Block as BlockT>::Hash, transaction_pool: Arc>, offline: SharedOfflineTracker, validators: Vec, minimum_timestamp: u64, } -impl Proposer { +impl Proposer { fn primary_index(&self, round_number: usize, len: usize) -> usize { use primitives::uint::U256; let big_len = U256::from(len); - let offset = U256::from_big_endian(&self.random_seed.0) % big_len; + let offset = U256::from_big_endian(self.random_seed.as_ref()) % big_len; let offset = offset.low_u64() as usize + round_number; offset % len } } -impl bft::Proposer for Proposer - where - C: Api + Send + Sync, +impl bft::Proposer<::Block> for Proposer where + C: AuthoringApi + TPClient::Block>, + <::Block as BlockT>::Hash: + Into<::Hash> + PartialEq + Into { - type Create = Result; + type Create = Result<::Block>; type Error = Error; type Evaluate = Box>; - fn propose(&self) -> Result { - use node_api::BlockBuilder; - use runtime_primitives::traits::{Hash as HashT, BlakeTwo256}; - use node_primitives::InherentData; + fn propose(&self) -> Result<::Block> { + use runtime_primitives::traits::BlakeTwo256; const MAX_VOTE_OFFLINE_SECONDS: Duration = Duration::from_secs(60); @@ -259,10 +360,10 @@ impl bft::Proposer for Proposer let block = block_builder.bake()?; info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]", - block.header.number, - Hash::from(block.header.hash()), - block.header.parent_hash, - block.extrinsics.iter() + block.header().number(), + <::Block as BlockT>::Hash::from(block.header().hash()), + block.header().parent_hash(), + block.extrinsics().iter() .map(|xt| format!("{}", BlakeTwo256::hash_of(xt))) .collect::>() .join(", ") @@ -281,7 +382,7 @@ impl bft::Proposer for Proposer Ok(substrate_block) } - fn evaluate(&self, unchecked_proposal: &Block) -> Self::Evaluate { + fn evaluate(&self, unchecked_proposal: &::Block) -> Self::Evaluate { debug!(target: "bft", "evaluating block on top of parent ({}, {:?})", self.parent_number, self.parent_hash); let current_timestamp = current_timestamp(); @@ -359,10 +460,9 @@ impl bft::Proposer for Proposer proposer } - fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior)>) { + fn import_misbehavior(&self, misbehavior: Vec<(AuthorityId, bft::Misbehavior<<::Block as BlockT>::Hash>)>) { use rhododendron::Misbehavior as GenericMisbehavior; use runtime_primitives::bft::{MisbehaviorKind, MisbehaviorReport}; - use node_primitives::UncheckedExtrinsic as GenericExtrinsic; use node_runtime::{Call, UncheckedExtrinsic, ConsensusCall}; let local_id = self.local_key.public().0.into(); @@ -371,7 +471,7 @@ impl bft::Proposer for Proposer .filter(|tx| tx.verified.sender == local_id) .last() .map(|tx| Ok(tx.verified.index())) - .unwrap_or_else(|| self.client.index(&self.parent_id, local_id)) + .unwrap_or_else(|| AuthoringApi::index(self.client.as_ref(), &self.parent_id, local_id)) ); match cur_index { @@ -389,16 +489,16 @@ impl bft::Proposer for Proposer for (target, misbehavior) in misbehavior { let report = MisbehaviorReport { - parent_hash: self.parent_hash, - parent_number: self.parent_number, + parent_hash: self.parent_hash.into(), + parent_number: self.parent_number.as_(), target, misbehavior: match misbehavior { GenericMisbehavior::ProposeOutOfTurn(_, _, _) => continue, GenericMisbehavior::DoublePropose(_, _, _) => continue, GenericMisbehavior::DoublePrepare(round, (h1, s1), (h2, s2)) - => MisbehaviorKind::BftDoublePrepare(round as u32, (h1, s1.signature), (h2, s2.signature)), + => MisbehaviorKind::BftDoublePrepare(round as u32, (h1.into(), s1.signature), (h2.into(), s2.signature)), GenericMisbehavior::DoubleCommit(round, (h1, s1), (h2, s2)) - => MisbehaviorKind::BftDoubleCommit(round as u32, (h1, s1.signature), (h2, s2.signature)), + => MisbehaviorKind::BftDoubleCommit(round as u32, (h1.into(), s1.signature), (h2.into(), s2.signature)), } }; let payload = (next_index, Call::Consensus(ConsensusCall::report_misbehavior(report)), Era::immortal(), self.client.genesis_hash()); @@ -410,8 +510,9 @@ impl bft::Proposer for Proposer signature: Some((node_runtime::RawAddress::Id(local_id), signature, payload.0, Era::immortal())), function: payload.1, }; - let uxt: GenericExtrinsic = Decode::decode(&mut extrinsic.encode().as_slice()).expect("Encoded extrinsic is valid"); - self.transaction_pool.submit_one(&BlockId::hash(self.parent_hash), uxt) + let uxt: <::Block as BlockT>::Extrinsic = Decode::decode(&mut extrinsic.encode().as_slice()).expect("Encoded extrinsic is valid"); + let hash = BlockId::<::Block>::hash(self.parent_hash); + self.transaction_pool.submit_one(&hash, uxt) .expect("locally signed extrinsic is valid; qed"); } } diff --git a/substrate/node/consensus/src/service.rs b/substrate/node/consensus/src/service.rs index 08bfe40af6..8ed3136dfb 100644 --- a/substrate/node/consensus/src/service.rs +++ b/substrate/node/consensus/src/service.rs @@ -26,16 +26,16 @@ use bft::{self, BftService}; use client::{BlockchainEvents, ChainHead, BlockBody}; use ed25519; use futures::prelude::*; -use node_api::Api; -use node_primitives::{Block, Header}; -use transaction_pool::TransactionPool; +use transaction_pool::{TransactionPool, Client as TPClient}; +use primitives; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT}; use tokio::executor::current_thread::TaskExecutor as LocalThreadHandle; use tokio::runtime::TaskExecutor as ThreadPoolHandle; use tokio::runtime::current_thread::Runtime as LocalRuntime; use tokio::timer::Interval; -use super::{Network, ProposerFactory}; +use super::{Network, ProposerFactory, AuthoringApi}; use error; const TIMER_DELAY_MS: u64 = 5000; @@ -43,15 +43,16 @@ const TIMER_INTERVAL_MS: u64 = 500; // spin up an instance of BFT agreement on the current thread's executor. // panics if there is no current thread executor. -fn start_bft( - header: Header, +fn start_bft( + header: ::Header, bft_service: Arc>, ) where F: bft::Environment + 'static, C: bft::BlockImport + bft::Authorities + 'static, F::Error: ::std::fmt::Debug, >::Error: ::std::fmt::Display + Into, - >::Error: ::std::fmt::Display + >::Error: ::std::fmt::Display, + Block: BlockT, { let mut handle = LocalThreadHandle::current(); match bft_service.build_upon(&header) { @@ -80,10 +81,15 @@ impl Service { key: ed25519::Pair, ) -> Service where - A: Api + Send + Sync + 'static, - C: BlockchainEvents + ChainHead + BlockBody, - C: bft::BlockImport + bft::Authorities + Send + Sync + 'static, - N: Network + Send + 'static, + A: AuthoringApi + TPClient::Block> + 'static, + C: BlockchainEvents<::Block> + + ChainHead<::Block> + + BlockBody<::Block>, + C: bft::BlockImport<::Block> + + bft::Authorities<::Block> + Send + Sync + 'static, + primitives::H256: From<<::Block as BlockT>::Hash>, + <::Block as BlockT>::Hash: PartialEq + PartialEq, + N: Network::Block> + Send + 'static, { use parking_lot::RwLock; use super::OfflineTracker; diff --git a/substrate/node/network/Cargo.toml b/substrate/node/network/Cargo.toml index 645edcfc42..1087180414 100644 --- a/substrate/node/network/Cargo.toml +++ b/substrate/node/network/Cargo.toml @@ -5,7 +5,6 @@ authors = ["Parity Technologies "] description = "Substrate node networking protocol" [dependencies] -node-api = { path = "../api" } node-consensus = { path = "../consensus" } node-primitives = { path = "../primitives" } substrate-bft = { path = "../../core/bft" } diff --git a/substrate/node/network/src/consensus.rs b/substrate/node/network/src/consensus.rs index 63ed119afe..a98ed7cd77 100644 --- a/substrate/node/network/src/consensus.rs +++ b/substrate/node/network/src/consensus.rs @@ -22,8 +22,7 @@ use bft; use substrate_primitives::ed25519; use substrate_network::{self as net, generic_message as msg}; use substrate_network::consensus_gossip::ConsensusMessage; -use node_api::Api; -use node_consensus::Network; +use node_consensus::{AuthoringApi, Network}; use node_primitives::{Block, Hash, SessionKey}; use rhododendron; @@ -248,12 +247,13 @@ impl

Clone for ConsensusNetwork

{ } /// A long-lived network which can create parachain statement and BFT message routing processes on demand. -impl Network for ConsensusNetwork

{ +impl Network for ConsensusNetwork

{ /// The input stream of BFT messages. Should never logically conclude. type Input = InputAdapter; /// The output sink of BFT messages. Messages sent here should eventually pass to all /// current validators. type Output = BftSink<::node_consensus::Error>; + type Block = Block; /// Get input and output streams of BFT messages. fn communication_for( diff --git a/substrate/node/network/src/lib.rs b/substrate/node/network/src/lib.rs index a01dae79b4..9a931ef131 100644 --- a/substrate/node/network/src/lib.rs +++ b/substrate/node/network/src/lib.rs @@ -24,7 +24,6 @@ extern crate substrate_bft as bft; extern crate substrate_network; extern crate substrate_primitives; -extern crate node_api; extern crate node_consensus; extern crate node_primitives; @@ -114,4 +113,3 @@ impl Specialization for Protocol { fn on_block_imported(&mut self, _ctx: &mut Context, _hash: Hash, _header: &Header) { } } - diff --git a/substrate/node/service/Cargo.toml b/substrate/node/service/Cargo.toml index 045b8c8286..977d1e4afb 100644 --- a/substrate/node/service/Cargo.toml +++ b/substrate/node/service/Cargo.toml @@ -11,7 +11,6 @@ log = "0.3" slog = "^2" tokio = "0.1.7" hex-literal = "0.1" -node-api = { path = "../api" } node-primitives = { path = "../primitives" } node-runtime = { path = "../runtime" } node-executor = { path = "../executor" } diff --git a/substrate/node/service/src/lib.rs b/substrate/node/service/src/lib.rs index 03aca2fc67..ee9ebf7c94 100644 --- a/substrate/node/service/src/lib.rs +++ b/substrate/node/service/src/lib.rs @@ -18,7 +18,6 @@ //! Substrate service. Specialized wrapper over substrate service. -extern crate node_api; extern crate node_primitives; extern crate node_runtime; extern crate node_executor; @@ -41,11 +40,12 @@ pub mod chain_spec; use std::sync::Arc; use transaction_pool::TransactionPool; -use node_api::Api; use node_primitives::{Block, Hash}; use node_runtime::GenesisConfig; use client::Client; +use consensus::AuthoringApi; use node_network::{Protocol as DemoProtocol, consensus::ConsensusNetwork}; +use transaction_pool::Client as TPApi; use tokio::runtime::TaskExecutor; use service::FactoryFullConfiguration; use primitives::{Blake2Hasher}; @@ -63,7 +63,7 @@ pub type NetworkService = network::Service; /// Client executor. diff --git a/substrate/node/transaction-pool/Cargo.toml b/substrate/node/transaction-pool/Cargo.toml index e7460983fb..1ab84dc5c6 100644 --- a/substrate/node/transaction-pool/Cargo.toml +++ b/substrate/node/transaction-pool/Cargo.toml @@ -7,7 +7,6 @@ authors = ["Parity Technologies "] log = "0.3.0" error-chain = "0.12" parking_lot = "0.4" -node-api = { path = "../api" } node-primitives = { path = "../primitives" } node-runtime = { path = "../runtime" } substrate-client = { path = "../../core/client" } diff --git a/substrate/node/transaction-pool/src/error.rs b/substrate/node/transaction-pool/src/error.rs index 6481ad07cd..fcf6e6de2a 100644 --- a/substrate/node/transaction-pool/src/error.rs +++ b/substrate/node/transaction-pool/src/error.rs @@ -15,14 +15,14 @@ // along with Substrate. If not, see . use transaction_pool; -use node_api; use primitives::Hash; use runtime::{Address, UncheckedExtrinsic}; +use client; error_chain! { links { + Client(client::error::Error, client::error::ErrorKind); Pool(transaction_pool::Error, transaction_pool::ErrorKind); - Api(node_api::Error, node_api::ErrorKind); } errors { /// Unexpected extrinsic format submitted diff --git a/substrate/node/transaction-pool/src/lib.rs b/substrate/node/transaction-pool/src/lib.rs index 1eb2a5aa80..931b239c49 100644 --- a/substrate/node/transaction-pool/src/lib.rs +++ b/substrate/node/transaction-pool/src/lib.rs @@ -21,7 +21,6 @@ extern crate substrate_primitives; extern crate sr_primitives; extern crate node_runtime as runtime; extern crate node_primitives as primitives; -extern crate node_api; extern crate parking_lot; #[cfg(test)] @@ -42,11 +41,16 @@ use std::{ }; use codec::{Decode, Encode}; +use client::{Client as SubstrateClient, CallExecutor}; use transaction_pool::{Readiness, scoring::{Change, Choice}, VerifiedFor, ExtrinsicFor}; -use node_api::Api; -use primitives::{AccountId, BlockId, Block, Hash, Index, BlockNumber}; +use primitives::{AccountId, Hash, Index}; use runtime::{Address, UncheckedExtrinsic}; -use sr_primitives::traits::{Bounded, Checkable, Hash as HashT, BlakeTwo256, Lookup, CurrentHeight, BlockNumberToHash}; +use substrate_primitives::{Blake2Hasher}; +use sr_primitives::generic::BlockId; +use sr_primitives::traits::{ + Bounded, Checkable, Block as BlockT, Hash as HashT, Header as HeaderT, BlakeTwo256, Lookup, CurrentHeight, + BlockNumberToHash +}; pub use transaction_pool::{Options, Status, LightStatus, VerifiedTransaction as VerifiedTransactionOps}; pub use error::{Error, ErrorKind, Result}; @@ -54,8 +58,38 @@ pub use error::{Error, ErrorKind, Result}; /// Maximal size of a single encoded extrinsic. const MAX_TRANSACTION_SIZE: usize = 4 * 1024 * 1024; +/// Local client abstraction for the transaction-pool. +pub trait Client: + Send + + Sync + + CurrentHeight::Block as BlockT>::Header as HeaderT>::Number> + + BlockNumberToHash::Block as BlockT>::Header as HeaderT>::Number, Hash=<::Block as BlockT>::Hash> { + /// The block used for this API type. + type Block: BlockT; + /// Get the nonce (né index) of an account at a block. + fn index(&self, at: &BlockId, account: AccountId) -> Result; + /// Get the account id of an address at a block. + fn lookup(&self, at: &BlockId, address: Address) -> Result>; +} + +impl Client for SubstrateClient where + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT, +{ + type Block = Block; + + fn index(&self, at: &BlockId, account: AccountId) -> Result { + self.call_api_at(at, "account_nonce", &account).map_err(Into::into) + } + + fn lookup(&self, at: &BlockId, address: Address) -> Result> { + self.call_api_at(at, "lookup_address", &address).map_err(Into::into) + } +} + /// Type alias for the transaction pool. -pub type TransactionPool = transaction_pool::Pool>; +pub type TransactionPool = transaction_pool::Pool>; /// A verified transaction which should be includable and non-inherent. #[derive(Clone, Debug)] @@ -104,15 +138,13 @@ impl transaction_pool::VerifiedTransaction for VerifiedTransaction { } /// The transaction pool logic. -pub struct ChainApi { - api: Arc, +pub struct ChainApi { + api: Arc, } -impl ChainApi where - A: Api, -{ +impl ChainApi { /// Create a new instance. - pub fn new(api: Arc) -> Self { + pub fn new(api: Arc) -> Self { ChainApi { api, } @@ -123,20 +155,20 @@ impl ChainApi where /// /// This is due for removal when #721 lands pub struct LocalContext<'a, A: 'a>(&'a Arc); -impl<'a, A: 'a + Api> CurrentHeight for LocalContext<'a, A> { - type BlockNumber = BlockNumber; - fn current_height(&self) -> BlockNumber { +impl<'a, C: 'a + Client> CurrentHeight for LocalContext<'a, C> { + type BlockNumber = ::BlockNumber; + fn current_height(&self) -> Self::BlockNumber { self.0.current_height() } } -impl<'a, A: 'a + Api> BlockNumberToHash for LocalContext<'a, A> { - type BlockNumber = BlockNumber; - type Hash = Hash; - fn block_number_to_hash(&self, n: BlockNumber) -> Option { +impl<'a, C: 'a + Client> BlockNumberToHash for LocalContext<'a, C> { + type BlockNumber = ::BlockNumber; + type Hash = ::Hash; + fn block_number_to_hash(&self, n: Self::BlockNumber) -> Option { self.0.block_number_to_hash(n) } } -impl<'a, A: 'a + Api> Lookup for LocalContext<'a, A> { +impl<'a, C: 'a + Client> Lookup for LocalContext<'a, C> { type Source = Address; type Target = AccountId; fn lookup(&self, a: Address) -> ::std::result::Result { @@ -144,10 +176,8 @@ impl<'a, A: 'a + Api> Lookup for LocalContext<'a, A> { } } -impl transaction_pool::ChainApi for ChainApi where - A: Api + Send + Sync, -{ - type Block = Block; +impl transaction_pool::ChainApi for ChainApi { + type Block = C::Block; type Hash = Hash; type Sender = AccountId; type VEx = VerifiedTransaction; @@ -156,7 +186,7 @@ impl transaction_pool::ChainApi for ChainApi where type Score = u64; type Event = (); - fn verify_transaction(&self, _at: &BlockId, xt: &ExtrinsicFor) -> Result { + fn verify_transaction(&self, _at: &BlockId, xt: &ExtrinsicFor) -> Result { let encoded = xt.encode(); let uxt = UncheckedExtrinsic::decode(&mut encoded.as_slice()).ok_or_else(|| ErrorKind::InvalidExtrinsicFormat)?; if !uxt.is_signed() { @@ -191,7 +221,7 @@ impl transaction_pool::ChainApi for ChainApi where HashMap::default() } - fn is_ready(&self, at: &BlockId, known_nonces: &mut Self::Ready, xt: &VerifiedFor) -> Readiness { + fn is_ready(&self, at: &BlockId, known_nonces: &mut Self::Ready, xt: &VerifiedFor) -> Readiness { let sender = xt.verified.sender().clone(); trace!(target: "transaction-pool", "Checking readiness of {} (from {})", xt.verified.hash, sender); @@ -249,4 +279,3 @@ impl transaction_pool::ChainApi for ChainApi where Choice::RejectNew } } -