From ebff010d16426ec7577a186f0d4c34c4b2eb96be Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 9 Nov 2016 23:25:54 +0100 Subject: [PATCH] partial implementation of provider for client types --- ethcore/light/src/provider.rs | 56 +++++++++++++++++++++++++++++-- ethcore/src/client/client.rs | 13 +++++-- ethcore/src/client/mod.rs | 11 +++--- ethcore/src/client/test_client.rs | 8 +++++ ethcore/src/client/traits.rs | 4 +++ ethcore/src/types/pruning_info.rs | 30 +++++++++++++++++ 6 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 ethcore/src/types/pruning_info.rs diff --git a/ethcore/light/src/provider.rs b/ethcore/light/src/provider.rs index b1625f95f..3cabe3feb 100644 --- a/ethcore/light/src/provider.rs +++ b/ethcore/light/src/provider.rs @@ -17,8 +17,11 @@ //! A provider for the LES protocol. This is typically a full node, who can //! give as much data as necessary to its peers. +use ethcore::client::BlockChainClient; use ethcore::transaction::SignedTransaction; use ethcore::blockchain_info::BlockChainInfo; + +use rlp::EMPTY_LIST_RLP; use util::{Bytes, H256}; use request; @@ -36,8 +39,9 @@ pub trait Provider: Send + Sync { /// Find the depth of a common ancestor between two blocks. fn reorg_depth(&self, a: &H256, b: &H256) -> Option; - /// Earliest state. - fn earliest_state(&self) -> Option; + /// Earliest block where state queries are available. + /// All states between this value and + fn earliest_state(&self) -> u64; /// Provide a list of headers starting at the requested block, /// possibly in reverse and skipping `skip` at a time. @@ -67,5 +71,53 @@ pub trait Provider: Send + Sync { fn header_proofs(&self, req: request::HeaderProofs) -> Vec; /// Provide pending transactions. + fn pending_transactions(&self) -> Vec; +} + +// TODO [rob] move into trait definition file after ethcore crate +// is split up. ideally `ethcore-light` will be between `ethcore-blockchain` +// and `ethcore-client` +impl Provider for T { + fn chain_info(&self) -> BlockChainInfo { + BlockChainClient::chain_info(self) + } + + fn reorg_depth(&self, a: &H256, b: &H256) -> Option { + self.tree_route.map(|route| route.index as u64) + } + + fn earliest_state(&self) -> u64 { + self.pruning_info().earliest_state + } + + fn block_headers(&self, req: request::Headers) -> Vec { + unimplemented!() + } + + fn block_bodies(&self, req: request::Bodies) -> Vec { + req.block_hashes.into_iter() + .map(|hash| self.block_body(hash.into())) + .map(|body| body.unwrap_or_else(|| EMPTY_LIST_RLP.into())) + .collect() + } + + fn receipts(&self, req: request::Receipts) -> Vec { + req.block_hashes.into_iter() + .map(|hash| self.block_receipts(&hash) + .map(|receipts| receips.unwrap_or_else(|| EMPTY_LIST_RLP.into())) + .collect() + } + + fn proofs(&self, req: request::StateProofs) -> Vec { + unimplemented!() + } + + fn code(&self, req: request::ContractCodes) -> Vec; + + fn header_proofs(&self, req: request::HeaderProofs) -> Vec { + // TODO: [rob] implement CHT stuff on `ethcore` side. + req.requests.into_iter().map(|_| EMPTY_LIST_RLP.into()).collect() + } + fn pending_transactions(&self) -> Vec; } \ No newline at end of file diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index ec59e01cf..72356e91d 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -52,7 +52,7 @@ use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute}; use client::{ BlockID, TransactionID, UncleID, TraceId, ClientConfig, BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics, BlockImportError, Mode, - ChainNotify, + ChainNotify, PruningInfo, }; use client::Error as ClientError; use env_info::EnvInfo; @@ -262,7 +262,7 @@ impl Client { } } - /// Register an action to be done if a mode change happens. + /// Register an action to be done if a mode change happens. pub fn on_mode_change(&self, f: F) where F: 'static + FnMut(&Mode) + Send { *self.on_mode_change.lock() = Some(Box::new(f)); } @@ -890,7 +890,7 @@ impl BlockChainClient for Client { trace!(target: "mode", "Making callback..."); f(&*mode) }, - _ => {} + _ => {} } } match new_mode { @@ -1226,6 +1226,13 @@ impl BlockChainClient for Client { self.uncle(id) .map(|header| self.engine.extra_info(&decode(&header))) } + + fn pruning_info(&self) -> PruningInfo { + PruningInfo { + earliest_chain: self.chain.read().first_block().unwrap_or(1), + earliest_state: self.state_db.lock().journal_db().earliest_era().unwrap_or(0), + } + } } impl MiningBlockChainClient for Client { diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 3898ab6cd..7eafbee36 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -25,18 +25,21 @@ mod client; pub use self::client::*; pub use self::config::{Mode, ClientConfig, DatabaseCompactionProfile, BlockChainConfig, VMType}; pub use self::error::Error; -pub use types::ids::*; pub use self::test_client::{TestBlockChainClient, EachBlockWith}; +pub use self::chain_notify::ChainNotify; +pub use self::traits::{BlockChainClient, MiningBlockChainClient}; + +pub use types::ids::*; pub use types::trace_filter::Filter as TraceFilter; +pub use types::pruning_info::PruningInfo; +pub use types::call_analytics::CallAnalytics; + pub use executive::{Executed, Executive, TransactOptions}; pub use env_info::{LastHashes, EnvInfo}; -pub use self::chain_notify::ChainNotify; -pub use types::call_analytics::CallAnalytics; pub use block_import_error::BlockImportError; pub use transaction_import::TransactionImportResult; pub use transaction_import::TransactionImportError; -pub use self::traits::{BlockChainClient, MiningBlockChainClient}; pub use verification::VerifierType; /// IPC interfaces diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 434edd3e8..713c55056 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -38,6 +38,7 @@ use evm::{Factory as EvmFactory, VMType, Schedule}; use miner::{Miner, MinerService, TransactionImportResult}; use spec::Spec; use types::mode::Mode; +use types::pruning_info::PruningInfo; use views::BlockView; use verification::queue::QueueInfo; @@ -650,4 +651,11 @@ impl BlockChainClient for TestBlockChainClient { fn mode(&self) -> Mode { Mode::Active } fn set_mode(&self, _: Mode) { unimplemented!(); } + + fn pruning_info(&self) -> PruningInfo { + PruningInfo { + earliest_chain: 1, + earlest_state: 1, + } + } } diff --git a/ethcore/src/client/traits.rs b/ethcore/src/client/traits.rs index 67092e986..2cbf52f6c 100644 --- a/ethcore/src/client/traits.rs +++ b/ethcore/src/client/traits.rs @@ -39,6 +39,7 @@ use types::call_analytics::CallAnalytics; use types::blockchain_info::BlockChainInfo; use types::block_status::BlockStatus; use types::mode::Mode; +use types::pruning_info::PruningInfo; #[ipc(client_ident="RemoteClient")] /// Blockchain database client. Owns and manages a blockchain and a block queue. @@ -241,6 +242,9 @@ pub trait BlockChainClient : Sync + Send { /// Returns engine-related extra info for `UncleID`. fn uncle_extra_info(&self, id: UncleID) -> Option>; + + /// Returns information about pruning/data availability. + fn pruning_info(&self) -> PruningInfo; } /// Extended client interface used for mining diff --git a/ethcore/src/types/pruning_info.rs b/ethcore/src/types/pruning_info.rs new file mode 100644 index 000000000..c49b7825b --- /dev/null +++ b/ethcore/src/types/pruning_info.rs @@ -0,0 +1,30 @@ +// Copyright 2015, 2016 Ethcore (UK) Ltd. +// This file is part of Parity. + +// Parity 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. + +// Parity 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 Parity. If not, see . + +//! Information about portions of the state and chain which the client may serve. +//! +//! Currently assumes that a client will store everything past a certain point +//! or everything. Will be extended in the future to support a definition +//! of which portions of the ancient chain and current state trie are stored as well. + +/// Client pruning info. See module-level docs for more details. +#[derive(Debug, Clone, Binary)] +pub struct PruningInfo { + /// The first block which everything can be served after. + pub earliest_chain: u64 + /// The first block where state requests may be served. + pub earliest_state: u64 +} \ No newline at end of file