// Copyright 2015, 2016 Parity Technologies (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 . //! Light client implementation. Stores data from light sync use std::sync::Arc; use ethcore::engines::Engine; use ethcore::ids::BlockId; use ethcore::block_import_error::BlockImportError; use ethcore::block_status::BlockStatus; use ethcore::verification::queue::{HeaderQueue, QueueInfo, Config as QueueConfig}; use ethcore::transaction::SignedTransaction; use ethcore::blockchain_info::BlockChainInfo; use ethcore::spec::Spec; use ethcore::service::ClientIoMessage; use io::IoChannel; use util::hash::{H256, H256FastMap}; use util::{Bytes, Mutex}; use provider::Provider; use request; use self::header_chain::HeaderChain; mod header_chain; /// Configuration for the light client. #[derive(Debug, Default, Clone)] pub struct Config { queue: QueueConfig, } /// Light client implementation. pub struct Client { queue: HeaderQueue, chain: HeaderChain, tx_pool: Mutex>, } impl Client { /// Create a new `Client`. pub fn new(config: Config, spec: &Spec, io_channel: IoChannel) -> Self { Client { queue: HeaderQueue::new(config.queue, spec.engine.clone(), io_channel, true), chain: HeaderChain::new(&::rlp::encode(&spec.genesis_header())), tx_pool: Mutex::new(Default::default()), } } /// Import a header as rlp-encoded bytes. pub fn import_header(&self, bytes: Bytes) -> Result { let header = ::rlp::decode(&bytes); self.queue.import(header).map_err(Into::into) } /// Import a local transaction. pub fn import_own_transaction(&self, tx: SignedTransaction) { self.tx_pool.lock().insert(tx.hash(), tx); } /// Fetch a vector of all pending transactions. pub fn pending_transactions(&self) -> Vec { self.tx_pool.lock().values().cloned().collect() } /// Inquire about the status of a given block (or header). pub fn status(&self, id: BlockId) -> BlockStatus { BlockStatus::Unknown } /// Get the header queue info. pub fn queue_info(&self) -> QueueInfo { self.queue.queue_info() } } // dummy implementation -- may draw from canonical cache further on. impl Provider for Client { fn chain_info(&self) -> BlockChainInfo { let best_block = self.chain.best_block(); let first_block = self.chain.first_block(); let genesis_hash = self.chain.genesis_hash(); BlockChainInfo { total_difficulty: best_block.total_difficulty, pending_total_difficulty: best_block.total_difficulty, genesis_hash: genesis_hash, best_block_hash: best_block.hash, best_block_number: best_block.number, ancient_block_hash: if first_block.is_some() { Some(genesis_hash) } else { None }, ancient_block_number: if first_block.is_some() { Some(0) } else { None }, first_block_hash: first_block.as_ref().map(|first| first.hash), first_block_number: first_block.as_ref().map(|first| first.number), } } fn reorg_depth(&self, _a: &H256, _b: &H256) -> Option { None } fn earliest_state(&self) -> Option { None } fn block_headers(&self, _req: request::Headers) -> Vec { Vec::new() } fn block_bodies(&self, _req: request::Bodies) -> Vec { Vec::new() } fn receipts(&self, _req: request::Receipts) -> Vec { Vec::new() } fn proofs(&self, _req: request::StateProofs) -> Vec { Vec::new() } fn contract_code(&self, _req: request::ContractCodes) -> Vec { Vec::new() } fn header_proofs(&self, _req: request::HeaderProofs) -> Vec { Vec::new() } fn pending_transactions(&self) -> Vec { Client::pending_transactions(self) } }