diff --git a/ethcore/blockchain/src/blockchain.rs b/ethcore/blockchain/src/blockchain.rs index 06ff4f876b0..df9e16f49ca 100644 --- a/ethcore/blockchain/src/blockchain.rs +++ b/ethcore/blockchain/src/blockchain.rs @@ -595,7 +595,7 @@ impl BlockChain { let best_block_rlp = bc.block(&best_block_hash) .expect("Best block is from a known block hash; qed"); - // and write them + // and write them to the cache. let mut best_block = bc.best_block.write(); *best_block = BestBlock { total_difficulty: best_block_total_difficulty, diff --git a/ethcore/client-traits/src/lib.rs b/ethcore/client-traits/src/lib.rs index 7ff322ae6ff..48f6a2eedae 100644 --- a/ethcore/client-traits/src/lib.rs +++ b/ethcore/client-traits/src/lib.rs @@ -55,6 +55,7 @@ use trace::{ localized::LocalizedTrace, VMTrace, }; +use common_types::data_format::DataFormat; use vm::{LastHashes, Schedule}; use std::str::FromStr; @@ -510,34 +511,11 @@ pub trait ChainNotify: Send + Sync { fn transactions_received(&self, _txs: &[UnverifiedTransaction], _peer_id: usize) { // does nothing by default } - -#[derive(Debug, PartialEq)] -pub enum DataFormat { - Hex, - Binary, -} - -impl Default for DataFormat { - fn default() -> Self { - DataFormat::Binary - } -} - -impl FromStr for DataFormat { - type Err = String; - - fn from_str(s: &str) -> Result { - match s { - "binary" | "bin" => Ok(DataFormat::Binary), - "hex" => Ok(DataFormat::Hex), - x => Err(format!("Invalid format: {}", x)) - } - } } -/// Provides a method for exporting blocks -pub trait ExportBlocks { - /// Export blocks to destination, with the given from, to and format arguments. +/// Provides a method for importing/exporting blocks +pub trait ImportExportBlocks { + /// Export blocks to destination, with the given from, to and format argument. /// destination could be a file or stdout. /// if the format is hex, each block is written on a new line. /// for binary exports, all block data is written to the same line. @@ -548,18 +526,15 @@ pub trait ExportBlocks { to: BlockId, format: Option ) -> Result<(), String>; -} -/// Provides a method for importing blocks -pub trait ImportBlocks { - /// Import blocks from destination, with the given format arguments - /// source could be a file or stdout. - /// For hex imports, it attempts to read the blocks on a line by line basis. - /// For binary imports, it'll read the 8 byte rlp header in order to decode the block + /// Import blocks from destination, with the given format argument + /// Source could be a file or stdout. + /// For hex format imports, it attempts to read the blocks on a line by line basis. + /// For binary format imports, reads the 8 byte RLP header in order to decode the block /// length to be read. fn import_blocks<'a>( - &self, - source: Box, - format: Option - ) -> Result<(), String>; + &self, + source: Box, + format: Option + ) -> Result<(), String>; } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index c47426e48b3..3ce15116171 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -15,116 +15,129 @@ // along with Parity Ethereum. If not, see . use std::cmp; -use std::collections::{HashSet, BTreeMap, VecDeque}; -use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; +use std::collections::{BTreeMap, HashSet, VecDeque}; +use std::io::{BufRead, BufReader}; +use std::str::from_utf8; use std::sync::{Arc, Weak}; -use std::time::{Instant, Duration}; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering as AtomicOrdering}; +use std::time::{Duration, Instant}; -use account_state::state::StateInfo; -use blockchain::{BlockReceipts, BlockChain, BlockChainDB, BlockProvider, TreeRoute, TransactionAddress, ExtrasInsert, BlockNumberKey}; +use ansi_term::Colour; use bytes::Bytes; -use call_contract::{CallContract, RegistryInfo}; -use ethcore_miner::pool::VerifiedTransaction; -use ethereum_types::{H256, H264, Address, U256}; -use evm::Schedule; +use bytes::ToPretty; +use ethereum_types::{Address, H256, H264, U256}; use hash::keccak; -use io::IoChannel; +use hash_db::EMPTY_PREFIX; use itertools::Itertools; -use journaldb; -use kvdb::{DBValue, KeyValueDB, DBTransaction}; +use kvdb::{DBTransaction, DBValue, KeyValueDB}; use parking_lot::{Mutex, RwLock}; use rand::rngs::OsRng; -use trie::{TrieSpec, TrieFactory, Trie}; -use vm::{EnvInfo, LastHashes, CreateContractAddress}; -use hash_db::EMPTY_PREFIX; -use block::{LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock}; -use client::ancient_import::AncientVerifier; +use rlp::PayloadInfo; +use rustc_hex::FromHex; +use trie::{Trie, TrieFactory, TrieSpec}; + +use account_state::State; +use account_state::state::StateInfo; +use block::{ClosedBlock, Drain, enact_verified, LockedBlock, OpenBlock, SealedBlock}; +use blockchain::{ + BlockChain, + BlockChainDB, + BlockNumberKey, + BlockProvider, + BlockReceipts, + ExtrasInsert, + TransactionAddress, + TreeRoute +}; +// re-export +pub use blockchain::CacheSize as BlockChainCacheSize; +use call_contract::{CallContract, RegistryInfo}; use client::{ - ReopenBlock, PrepareOpenBlock, ImportSealedBlock, BroadcastProposalBlock, - Call, BlockProducer, SealedBlockImporter, EngineInfo, - ClientConfig, bad_blocks, + bad_blocks, BlockProducer, BroadcastProposalBlock, Call, + ClientConfig, EngineInfo, ImportSealedBlock, PrepareOpenBlock, + ReopenBlock, SealedBlockImporter, }; +use client::ancient_import::AncientVerifier; use client_traits::{ - BlockInfo, - ScheduleInfo, - StateClient, - BlockChainReset, - Nonce, - Balance, - ChainInfo, - TransactionInfo, - ImportBlock, AccountData, + BadBlocks, + Balance, BlockChain as BlockChainTrait, BlockChainClient, + BlockChainReset, + BlockInfo, + ChainInfo, + ChainNotify, + DatabaseRestore, + ImportBlock, + ImportExportBlocks, IoClient, - BadBlocks, + Nonce, ProvingBlockChainClient, + ScheduleInfo, + SnapshotClient, + SnapshotWriter, + StateClient, StateOrBlock, - ExportBlocks, - DataFormat, - ImportBlocks + Tick, + TransactionInfo }; +use db::{keys::BlockDetails, Readable, Writable}; use engine::Engine; +use ethcore_miner::pool::VerifiedTransaction; +use ethtrie::Layout; +use evm::Schedule; +use executive_state; +use io::IoChannel; +use journaldb; use machine::{ executed::Executed, - executive::{Executive, TransactOptions, contract_address}, + executive::{contract_address, Executive, TransactOptions}, transaction_ext::Transaction, }; -use trie_vm_factories::{Factories, VmFactory}; use miner::{Miner, MinerService}; use snapshot; use spec::Spec; -use account_state::State; -use executive_state; use state_db::StateDB; -use trace::{self, TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase}; +use trace::{self, Database as TraceDatabase, ImportRequest as TraceImportRequest, LocalizedTrace, TraceDB}; +use trie_vm_factories::{Factories, VmFactory}; use types::{ ancestry_action::AncestryAction, - BlockNumber, block::PreverifiedBlock, block_status::BlockStatus, blockchain_info::BlockChainInfo, - chain_notify::{NewBlocks, ChainRoute, ChainMessageType}, + BlockNumber, + call_analytics::CallAnalytics, + chain_notify::{ChainMessageType, ChainRoute, NewBlocks}, client_types::ClientReport, - import_route::ImportRoute, - io_message::ClientIoMessage, + client_types::Mode, encoded, engines::{ - ForkChoice, - SealingState, - MAX_UNCLE_AGE, epoch::{PendingTransition, Transition as EpochTransition}, + ForkChoice, machine::{AuxiliaryData, Call as MachineCall}, + MAX_UNCLE_AGE, + SealingState, }, - errors::{EngineError, ExecutionError, BlockError, EthcoreError, SnapshotError, ImportError, EthcoreResult}, - ids::{BlockId, TransactionId, UncleId, TraceId}, - transaction::{self, LocalizedTransaction, UnverifiedTransaction, SignedTransaction, Action, CallError}, + errors::{BlockError, EngineError, EthcoreError, EthcoreResult, ExecutionError, ImportError, SnapshotError}, filter::Filter, - log_entry::LocalizedLogEntry, - receipt::{Receipt, LocalizedReceipt}, header::Header, + ids::{BlockId, TraceId, TransactionId, UncleId}, + import_route::ImportRoute, + io_message::ClientIoMessage, + log_entry::LocalizedLogEntry, + pruning_info::PruningInfo, + receipt::{LocalizedReceipt, Receipt}, snapshot::{Progress, Snapshotting}, trace_filter::Filter as TraceFilter, - pruning_info::PruningInfo, - call_analytics::CallAnalytics, - client_types::Mode, + transaction::{self, Action, CallError, LocalizedTransaction, SignedTransaction, UnverifiedTransaction}, verification::{Unverified, VerificationQueueInfo as BlockQueueInfo}, }; - -use verification::queue::kind::BlockLike; -use verification::{Verifier, BlockQueue}; +use types::data_format::DataFormat; +use verification::{BlockQueue, Verifier}; use verification; -use ansi_term::Colour; -use ethtrie::Layout; -// re-export -pub use blockchain::CacheSize as BlockChainCacheSize; -use db::{Writable, Readable, keys::BlockDetails}; -use rlp::PayloadInfo; -use std::io::{BufReader, BufRead}; -use rustc_hex::FromHex; -use std::str::from_utf8; -use bytes::ToPretty; +use verification::queue::kind::BlockLike; +use vm::{CreateContractAddress, EnvInfo, LastHashes}; use_contract!(registry, "res/contracts/registrar.json"); @@ -2573,10 +2586,16 @@ impl SnapshotClient for Client { } -impl ExportBlocks for Client { - fn export_blocks<'a>(&self, mut out: Box, from: BlockId, to: BlockId, format: Option) -> Result<(), String> { - let from = self.block_number(from).ok_or("From block could not be found")?; - let to = self.block_number(to).ok_or("To block could not be found")?; +impl ImportExportBlocks for Client { + fn export_blocks<'a>( + &self, + mut out: Box, + from: BlockId, + to: BlockId, + format: Option + ) -> Result<(), String> { + let from = self.block_number(from).ok_or("Starting block could not be found")?; + let to = self.block_number(to).ok_or("End block could not be found")?; let format = format.unwrap_or_default(); for i in from..=to { @@ -2595,10 +2614,7 @@ impl ExportBlocks for Client { } Ok(()) } -} - -impl ImportBlocks for Client { fn import_blocks<'a>( &self, mut source: Box, @@ -2620,7 +2636,7 @@ impl ImportBlocks for Client { } }; - let do_import = |bytes| { + let do_import = |bytes: Vec| { let block = Unverified::from_rlp(bytes).map_err(|_| "Invalid block rlp")?; while self.queue_info().is_full() { std::thread::sleep(Duration::from_secs(1)); } match self.import_block(block) { @@ -2658,7 +2674,8 @@ impl ImportBlocks for Client { } DataFormat::Hex => { for line in BufReader::new(source).lines() { - let s = line.map_err(|err| format!("Error reading from the file/stream: {:?}", err))?; + let s = line + .map_err(|err| format!("Error reading from the file/stream: {:?}", err))?; let s = if first_read > 0 { from_utf8(&first_bytes) .map_err(|err| format!("Invalid UTF-8: {:?}", err))? @@ -2667,7 +2684,8 @@ impl ImportBlocks for Client { s }; first_read = 0; - let bytes = s.from_hex().map_err(|err| format!("Invalid hex in file/stream: {:?}", err))?; + let bytes = s.from_hex() + .map_err(|err| format!("Invalid hex in file/stream: {:?}", err))?; do_import(bytes)?; } } @@ -2756,26 +2774,29 @@ impl IoChannelQueue { #[cfg(test)] mod tests { - use ethereum_types::{H256, Address}; + use std::sync::Arc; + use std::sync::atomic::{AtomicBool, Ordering}; + use std::thread; + use std::time::Duration; + + use ethereum_types::{Address, H256}; + use hash::keccak; + use kvdb::DBTransaction; + + use blockchain::ExtrasInsert; use client_traits::{BlockChainClient, ChainInfo}; + use ethkey::KeyPair; + use test_helpers::{generate_dummy_client, generate_dummy_client_with_data, get_good_dummy_block_hash}; use types::{ encoded, engines::ForkChoice, ids::{BlockId, TransactionId}, - log_entry::{LogEntry, LocalizedLogEntry}, - receipt::{Receipt, LocalizedReceipt, TransactionOutcome}, - transaction::{Transaction, LocalizedTransaction, Action}, + log_entry::{LocalizedLogEntry, LogEntry}, + receipt::{LocalizedReceipt, Receipt, TransactionOutcome}, + transaction::{Action, LocalizedTransaction, Transaction}, }; - use test_helpers::{generate_dummy_client, get_good_dummy_block_hash, generate_dummy_client_with_data}; - use std::thread; - use std::time::Duration; - use std::sync::Arc; - use std::sync::atomic::{AtomicBool, Ordering}; - use kvdb::DBTransaction; - use blockchain::ExtrasInsert; - use hash::keccak; + use super::transaction_receipt; - use ethkey::KeyPair; #[test] fn should_not_cache_details_before_commit() { diff --git a/ethcore/types/src/data_format.rs b/ethcore/types/src/data_format.rs new file mode 100644 index 00000000000..8cfe5cf2be3 --- /dev/null +++ b/ethcore/types/src/data_format.rs @@ -0,0 +1,43 @@ +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. + +// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . + +//! Data format for importing/exporting blocks from disk +use std::str::FromStr; + +/// Format for importing/exporting blocks +#[derive(Debug, PartialEq)] +pub enum DataFormat { + Hex, + Binary, +} + +impl Default for DataFormat { + fn default() -> Self { + DataFormat::Binary + } +} + +impl FromStr for DataFormat { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "binary" | "bin" => Ok(DataFormat::Binary), + "hex" => Ok(DataFormat::Hex), + x => Err(format!("Invalid format: {}", x)) + } + } +} diff --git a/ethcore/types/src/lib.rs b/ethcore/types/src/lib.rs index 3b5f1f68ad6..d78995d0c15 100644 --- a/ethcore/types/src/lib.rs +++ b/ethcore/types/src/lib.rs @@ -84,6 +84,7 @@ pub mod trace_filter; pub mod transaction; pub mod tree_route; pub mod verification; +pub mod data_format; /// Type for block number. pub type BlockNumber = u64; diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 98920250056..8ca2ca3819b 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -26,7 +26,7 @@ use hash::{keccak, KECCAK_NULL_RLP}; use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; -use client_traits::{BlockChainReset, Nonce, Balance, BlockChainClient, ImportBlocks, ExportBlocks}; +use client_traits::{BlockChainReset, Nonce, Balance, BlockChainClient, ImportExportBlocks}; use ethcore::{ client::{DatabaseCompactionProfile, VMType}, miner::Miner, @@ -46,7 +46,8 @@ use types::{ errors::{ImportError, EthcoreError}, client_types::Mode, }; -use client_traits::DataFormat; +use types::data_format::DataFormat; +use verification::queue::VerifierSettings; #[derive(Debug, PartialEq)] pub enum BlockchainCmd { @@ -387,7 +388,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { let client = service.client(); - let instream: Box = match cmd.file_path { + let instream: Box = match cmd.file_path { Some(f) => Box::new(fs::File::open(&f).map_err(|_| format!("Cannot open given file: {}", f))?), None => Box::new(io::stdin()), }; @@ -536,7 +537,7 @@ fn execute_export(cmd: ExportBlockchain) -> Result<(), String> { )?; let client = service.client(); - let out: Box = match cmd.file_path { + let out: Box = match cmd.file_path { Some(f) => Box::new(fs::File::create(&f).map_err(|_| format!("Cannot write to file given: {}", f))?), None => Box::new(io::stdout()), }; diff --git a/parity/configuration.rs b/parity/configuration.rs index d86890fe8ca..38540fe03bd 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -48,7 +48,7 @@ use ethcore_private_tx::{ProviderConfig, EncryptorConfig}; use secretstore::{NodeSecretKey, Configuration as SecretStoreConfiguration, ContractAddress as SecretStoreContractAddress}; use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack}; use run::RunCmd; -use client_traits::DataFormat; +use types::data_format::DataFormat; use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, KillBlockchain, ExportState, ResetBlockchain}; use export_hardcoded_sync::ExportHsyncCmd; use presale::ImportWallet; @@ -1202,7 +1202,7 @@ mod tests { use parity_rpc::NetworkSettings; use updater::{UpdatePolicy, UpdateFilter, ReleaseTrack}; use types::ids::BlockId; - use client_traits::DataFormat; + use types::data_format::DataFormat; use account::{AccountCmd, NewAccount, ImportAccounts, ListAccounts}; use blockchain::{BlockchainCmd, ImportBlockchain, ExportBlockchain, ExportState}; use cli::Args;