From 2cab49e42be0dd7c0974773569e24b8580ac86e1 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 11 Apr 2018 12:02:20 +0100 Subject: [PATCH 01/12] WIP --- Cargo.lock | 1 + ethcore/Cargo.toml | 1 + ethcore/src/error.rs | 198 ++++++++++++------------------------------- ethcore/src/lib.rs | 6 ++ 4 files changed, 61 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71ad5fc0bb6..a7661fc3ab3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -494,6 +494,7 @@ dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "common-types 0.1.0", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-contract 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ethcore/Cargo.toml b/ethcore/Cargo.toml index 0ffb7034a35..cd057d51a70 100644 --- a/ethcore/Cargo.toml +++ b/ethcore/Cargo.toml @@ -20,6 +20,7 @@ fetch = { path = "../util/fetch" } hashdb = { path = "../util/hashdb" } memorydb = { path = "../util/memorydb" } patricia-trie = { path = "../util/patricia_trie" } +error-chain = { version = "0.11", default-features = false } ethcore-io = { path = "../util/io" } ethcore-logger = { path = "../logger" } ethcore-miner = { path = "../miner" } diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index defb301dcbe..714a5d65e16 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -201,80 +201,60 @@ impl From for TransactionImportError { } } -#[derive(Debug)] -/// General error type which should be capable of representing all errors in ethcore. -pub enum Error { - /// Client configuration error. - Client(ClientError), - /// Database error. - Database(kvdb::Error), - /// Error concerning a utility. - Util(UtilError), - /// Error concerning block processing. - Block(BlockError), - /// Unknown engine given. - UnknownEngineName(String), - /// Error concerning EVM code execution. - Execution(ExecutionError), - /// Error concerning transaction processing. - Transaction(TransactionError), - /// Error concerning block import. - Import(ImportError), - /// PoW hash is invalid or out of date. - PowHashInvalid, - /// The value of the nonce or mishash is invalid. - PowInvalid, - /// Error concerning TrieDBs - Trie(TrieError), - /// Io crate error. - Io(IoError), - /// Standard io error. - StdIo(::std::io::Error), - /// Snappy error. - Snappy(InvalidInput), - /// Snapshot error. - Snapshot(SnapshotError), - /// Consensus vote error. - Engine(EngineError), - /// Ethkey error. - Ethkey(EthkeyError), - /// Account Provider error. - AccountProvider(AccountsError), -} +error_chain! { + links { + Database(kvdb::Error, kvdb::ErrorKind) #[doc = "Database error."] + Util(UtilError, util_error::ErrorKind #[doc = "Error concerning a utility"]) + } + + foreign_links { + Io(IoError) #[doc = "Io create error"]; + StdIo(::std::io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."]; + Trie(TrieError) #[doc = "Error concerning TrieDBs."]; + Execution(ExecutionError) #[doc = "Error concerning EVM code execution."]; + Block(BlockError) #[doc = "Error concerning block processing."]; + Transaction(TransactionError) #[doc = "Error concerning transaction processing."]; + Import(ImportError) #[doc = "Error concerning block import." ]; + Snappy(InvalidInput) #[doc = "Snappy error."]; + Engine(EngineError) #[doc = "Consensus vote error."]; + Ethkey(EthkeyError) #[doc = "Ethkey error."]; + AccountProvider(AccountsError) #[doc = "Account Provider error"]; + } -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Error::Client(ref err) => err.fmt(f), - Error::Database(ref err) => err.fmt(f), - Error::Util(ref err) => err.fmt(f), - Error::Io(ref err) => err.fmt(f), - Error::Block(ref err) => err.fmt(f), - Error::Execution(ref err) => err.fmt(f), - Error::Transaction(ref err) => err.fmt(f), - Error::Import(ref err) => err.fmt(f), - Error::UnknownEngineName(ref name) => - f.write_fmt(format_args!("Unknown engine name ({})", name)), - Error::PowHashInvalid => f.write_str("Invalid or out of date PoW hash."), - Error::PowInvalid => f.write_str("Invalid nonce or mishash"), - Error::Trie(ref err) => err.fmt(f), - Error::StdIo(ref err) => err.fmt(f), - Error::Snappy(ref err) => err.fmt(f), - Error::Snapshot(ref err) => err.fmt(f), - Error::Engine(ref err) => err.fmt(f), - Error::Ethkey(ref err) => err.fmt(f), - Error::AccountProvider(ref err) => err.fmt(f), + errors { + #[doc = "Client configuration error."] + Client(err: ClientError) { + description("Client configuration error.") + display("Client configuration error {}", err) + } + + #[doc = "Snapshot error."] + Snapshot(err: SnapshotError) { + description("Snapshot error.") + display("Snapshot error {}", err) + } + + #[doc = "PoW hash is invalid or out of date."] + PowHashInvalid { + description("PoW hash is invalid or out of date.") + display("PoW hash is invalid or out of date.") + } + + #[doc = "The value of the nonce or mishash is invalid."] + PowInvalid { + description("The value of the nonce or mishash is invalid.") + display("The value of the nonce or mishash is invalid.") } - } -} -impl error::Error for Error { - fn description(&self) -> &str { - // improve description - "ethcore error" + #[doc = "Unknown engine given"] + UnknownEngineName(name: String) { + description("Unknown engine name") + display("Unknown engine name ({})", name) + } } } + /// Result of import block operation. pub type ImportResult = Result; @@ -287,66 +267,12 @@ impl From for Error { } } -impl From for Error { - fn from(err: kvdb::Error) -> Error { - Error::Database(err) - } -} - -impl From for Error { - fn from(err: TransactionError) -> Error { - Error::Transaction(err) - } -} - -impl From for Error { - fn from(err: ImportError) -> Error { - Error::Import(err) - } -} - -impl From for Error { - fn from(err: BlockError) -> Error { - Error::Block(err) - } -} - -impl From for Error { - fn from(err: ExecutionError) -> Error { - Error::Execution(err) - } -} - impl From<::rlp::DecoderError> for Error { fn from(err: ::rlp::DecoderError) -> Error { Error::Util(UtilError::from(err)) } } -impl From for Error { - fn from(err: UtilError) -> Error { - Error::Util(err) - } -} - -impl From for Error { - fn from(err: IoError) -> Error { - Error::Io(err) - } -} - -impl From for Error { - fn from(err: TrieError) -> Error { - Error::Trie(err) - } -} - -impl From<::std::io::Error> for Error { - fn from(err: ::std::io::Error) -> Error { - Error::StdIo(err) - } -} - impl From for Error { fn from(err: BlockImportError) -> Error { match err { @@ -357,11 +283,11 @@ impl From for Error { } } -impl From<::snappy::InvalidInput> for Error { - fn from(err: ::snappy::InvalidInput) -> Error { - Error::Snappy(err) - } -} +// impl From<::snappy::InvalidInput> for Error { +// fn from(err: ::snappy::InvalidInput) -> Error { +// Error::Snappy(err) +// } +// } impl From for Error { fn from(err: SnapshotError) -> Error { @@ -374,24 +300,6 @@ impl From for Error { } } -impl From for Error { - fn from(err: EngineError) -> Error { - Error::Engine(err) - } -} - -impl From for Error { - fn from(err: EthkeyError) -> Error { - Error::Ethkey(err) - } -} - -impl From for Error { - fn from(err: AccountsError) -> Error { - Error::AccountProvider(err) - } -} - impl From> for Error where Error: From { fn from(err: Box) -> Error { Error::from(*err) diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index c71a266f740..9dc4199c4f1 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -54,6 +54,10 @@ //! cargo build --release //! ``` +// Recursion limit required because of +// error_chain foreign_links. +#![recursion_limit="128"] + extern crate bloomchain; extern crate bn; extern crate byteorder; @@ -103,6 +107,8 @@ extern crate ethabi; extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; +#[macro_use] +extern crate error_chain; #[macro_use] extern crate rlp_derive; From 3c6a3a42d830ff499d0f8af530638d1669e1a2cf Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 11 Apr 2018 15:19:34 +0100 Subject: [PATCH 02/12] Convert Ethcore error to use error_chain --- ethcore/src/engines/mod.rs | 8 ++- ethcore/src/error.rs | 95 +++++++++++++++++--------------- ethcore/src/executed.rs | 8 ++- ethcore/transaction/src/error.rs | 8 ++- ethkey/src/error.rs | 8 ++- 5 files changed, 80 insertions(+), 47 deletions(-) diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 65fa13b54e8..379610f559e 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -37,7 +37,7 @@ pub use self::tendermint::Tendermint; use std::sync::{Weak, Arc}; use std::collections::{BTreeMap, HashMap}; -use std::fmt; +use std::{fmt, error}; use self::epoch::PendingTransition; @@ -102,6 +102,12 @@ impl fmt::Display for EngineError { } } +impl error::Error for EngineError { + fn description(&self) -> &str { + "Engine error" + } +} + /// Seal type. #[derive(Debug, PartialEq, Eq)] pub enum Seal { diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 714a5d65e16..31095cfe264 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -19,7 +19,7 @@ use std::{fmt, error}; use kvdb; use ethereum_types::{H256, U256, Address, Bloom}; -use util_error::UtilError; +use util_error::{self, UtilError}; use snappy::InvalidInput; use unexpected::{Mismatch, OutOfBounds}; use trie::TrieError; @@ -140,28 +140,38 @@ impl fmt::Display for BlockError { } } -#[derive(Debug, Clone, Copy, PartialEq)] -/// Import to the block queue result -pub enum ImportError { - /// Already in the block chain. - AlreadyInChain, - /// Already in the block queue. - AlreadyQueued, - /// Already marked as bad from a previous import (could mean parent is bad). - KnownBad, +impl error::Error for BlockError { + fn description(&self) -> &str { + "Block error" + } } -impl fmt::Display for ImportError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let msg = match *self { - ImportError::AlreadyInChain => "block already in chain", - ImportError::AlreadyQueued => "block already in the block queue", - ImportError::KnownBad => "block known to be bad", - }; +error_chain! { + types { + ImportError, ImportErrorKind, ImportErrorResultExt, ImportErrorResult; + } + + errors { + #[doc = "Already in the block chain."] + AlreadyInChain { + description("Block already in chain") + display("Block already in chain") + } + + #[doc = "Already in the block queue"] + AlreadyQueued { + description("block already in the block queue") + display("block already in the block queue") + } - f.write_fmt(format_args!("Block import error ({})", msg)) + #[doc = "Already marked as bad from a previous import (could mean parent is bad)."] + KnownBad { + description("block known to be bad") + display("block known to be bad") + } } } + /// Error dedicated to import block function #[derive(Debug)] pub enum BlockImportError { @@ -175,9 +185,9 @@ pub enum BlockImportError { impl From for BlockImportError { fn from(e: Error) -> Self { - match e { - Error::Block(block_error) => BlockImportError::Block(block_error), - Error::Import(import_error) => BlockImportError::Import(import_error), + match *e.kind() { + ErrorKind::Block(block_error) => BlockImportError::Block(block_error), + ErrorKind::Import(import_error) => BlockImportError::Import(import_error), _ => BlockImportError::Other(format!("other block import error: {:?}", e)), } } @@ -194,8 +204,8 @@ pub enum TransactionImportError { impl From for TransactionImportError { fn from(e: Error) -> Self { - match e { - Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error), + match *e.kind() { + ErrorKind::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error), _ => TransactionImportError::Other(format!("other block import error: {:?}", e)), } } @@ -203,8 +213,9 @@ impl From for TransactionImportError { error_chain! { links { - Database(kvdb::Error, kvdb::ErrorKind) #[doc = "Database error."] - Util(UtilError, util_error::ErrorKind #[doc = "Error concerning a utility"]) + Database(kvdb::Error, kvdb::ErrorKind) #[doc = "Database error."]; + Util(UtilError, util_error::ErrorKind) #[doc = "Error concerning a utility"]; + Import(ImportError, ImportErrorKind) #[doc = "Error concerning block import." ]; } foreign_links { @@ -214,11 +225,9 @@ error_chain! { Execution(ExecutionError) #[doc = "Error concerning EVM code execution."]; Block(BlockError) #[doc = "Error concerning block processing."]; Transaction(TransactionError) #[doc = "Error concerning transaction processing."]; - Import(ImportError) #[doc = "Error concerning block import." ]; Snappy(InvalidInput) #[doc = "Snappy error."]; Engine(EngineError) #[doc = "Consensus vote error."]; Ethkey(EthkeyError) #[doc = "Ethkey error."]; - AccountProvider(AccountsError) #[doc = "Account Provider error"]; } errors { @@ -234,6 +243,12 @@ error_chain! { display("Snapshot error {}", err) } + #[doc = "Account Provider error."] + AccountProvider(err: AccountsError) { + description("Account Provider error.") + display("Account Provider error {}", err) + } + #[doc = "PoW hash is invalid or out of date."] PowHashInvalid { description("PoW hash is invalid or out of date.") @@ -256,46 +271,40 @@ error_chain! { /// Result of import block operation. -pub type ImportResult = Result; +pub type ImportResult = Result; impl From for Error { fn from(err: ClientError) -> Error { match err { - ClientError::Trie(err) => Error::Trie(err), - _ => Error::Client(err) + ClientError::Trie(err) => ErrorKind::Trie(err).into(), + _ => ErrorKind::Client(err).into() } } } impl From<::rlp::DecoderError> for Error { fn from(err: ::rlp::DecoderError) -> Error { - Error::Util(UtilError::from(err)) + ErrorKind::Util(UtilError::from(err)).into() } } impl From for Error { fn from(err: BlockImportError) -> Error { match err { - BlockImportError::Block(e) => Error::Block(e), - BlockImportError::Import(e) => Error::Import(e), - BlockImportError::Other(s) => Error::Util(UtilError::from(s)), + BlockImportError::Block(e) => ErrorKind::Block(e).into(), + BlockImportError::Import(e) => ErrorKind::Import(e).into(), + BlockImportError::Other(s) => ErrorKind::Util(UtilError::from(s)).into(), } } } -// impl From<::snappy::InvalidInput> for Error { -// fn from(err: ::snappy::InvalidInput) -> Error { -// Error::Snappy(err) -// } -// } - impl From for Error { fn from(err: SnapshotError) -> Error { match err { - SnapshotError::Io(err) => Error::StdIo(err), - SnapshotError::Trie(err) => Error::Trie(err), + SnapshotError::Io(err) => ErrorKind::StdIo(err).into(), + SnapshotError::Trie(err) => ErrorKind::Trie(err).into(), SnapshotError::Decoder(err) => err.into(), - other => Error::Snapshot(other), + other => ErrorKind::Snapshot(other).into(), } } } diff --git a/ethcore/src/executed.rs b/ethcore/src/executed.rs index a7872093264..9ffd673154d 100644 --- a/ethcore/src/executed.rs +++ b/ethcore/src/executed.rs @@ -24,7 +24,7 @@ use trace::{VMTrace, FlatTrace}; use log_entry::LogEntry; use state_diff::StateDiff; -use std::fmt; +use std::{fmt, error}; /// Transaction execution receipt. #[derive(Debug, PartialEq, Clone)] @@ -148,6 +148,12 @@ impl fmt::Display for ExecutionError { } } +impl error::Error for ExecutionError { + fn description(&self) -> &str { + "Transaction execution error" + } +} + /// Result of executing the transaction. #[derive(PartialEq, Debug, Clone)] pub enum CallError { diff --git a/ethcore/transaction/src/error.rs b/ethcore/transaction/src/error.rs index 4578b88acd0..e38dc3ac675 100644 --- a/ethcore/transaction/src/error.rs +++ b/ethcore/transaction/src/error.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::fmt; +use std::{fmt, error}; use ethereum_types::U256; use ethkey; @@ -112,3 +112,9 @@ impl fmt::Display for Error { } } +impl error::Error for Error { + fn description(&self) -> &str { + "Transaction error" + } +} + diff --git a/ethkey/src/error.rs b/ethkey/src/error.rs index 0ac2d221a9d..c7faf677880 100644 --- a/ethkey/src/error.rs +++ b/ethkey/src/error.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::fmt; +use std::{fmt, error}; #[derive(Debug)] /// Crypto error @@ -51,6 +51,12 @@ impl fmt::Display for Error { } } +impl error::Error for Error { + fn description(&self) -> &str { + "Crypto error" + } +} + impl Into for Error { fn into(self) -> String { format!("{}", self) From 20f4822a39376b2e524ad983799968235bfc6690 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 11 Apr 2018 18:28:26 +0100 Subject: [PATCH 03/12] Use error_chain for ImportError and BlockImportError --- ethcore/src/client/client.rs | 10 +++--- ethcore/src/error.rs | 50 ++++++++++++++------------ ethcore/src/miner/miner.rs | 4 +-- ethcore/src/verification/queue/kind.rs | 4 +-- ethcore/src/verification/queue/mod.rs | 8 ++--- 5 files changed, 41 insertions(+), 35 deletions(-) diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index a8ce3f65c3c..448bdb2058d 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -49,7 +49,7 @@ use client::{ }; use encoded; use engines::{EthEngine, EpochTransition}; -use error::{ImportError, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; +use error::{ImportErrorKind, BlockImportErrorKind, ExecutionError, CallError, BlockError, ImportResult, Error as EthcoreError}; use vm::{EnvInfo, LastHashes}; use evm::Schedule; use executive::{Executive, Executed, TransactOptions, contract_address}; @@ -1397,11 +1397,11 @@ impl ImportBlock for Client { { if self.chain.read().is_known(&unverified.hash()) { - return Err(BlockImportError::Import(ImportError::AlreadyInChain)); + bail!(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain)); } let status = self.block_status(BlockId::Hash(unverified.parent_hash())); if status == BlockStatus::Unknown || status == BlockStatus::Pending { - return Err(BlockImportError::Block(BlockError::UnknownParent(unverified.parent_hash()))); + bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(unverified.parent_hash()))); } } Ok(self.importer.block_queue.import(unverified)?) @@ -1412,11 +1412,11 @@ impl ImportBlock for Client { // check block order let header = BlockView::new(&block_bytes).header_view(); if self.chain.read().is_known(&header.hash()) { - return Err(BlockImportError::Import(ImportError::AlreadyInChain)); + bail!(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain)); } let status = self.block_status(BlockId::Hash(header.parent_hash())); if status == BlockStatus::Unknown || status == BlockStatus::Pending { - return Err(BlockImportError::Block(BlockError::UnknownParent(header.parent_hash()))); + bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(header.parent_hash()))); } } diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 31095cfe264..ee51d1413dc 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -172,23 +172,34 @@ error_chain! { } } -/// Error dedicated to import block function -#[derive(Debug)] -pub enum BlockImportError { - /// Import error - Import(ImportError), - /// Block error - Block(BlockError), - /// Other error - Other(String), +error_chain! { + types { + BlockImportError, BlockImportErrorKind, BlockImportErrorResultExt; + } + + links { + Import(ImportError, ImportErrorKind) #[doc = "Import error"]; + } + + foreign_links { + Block(BlockError) #[doc = "Block error"]; + } + + errors { + #[doc = "Other error"] + Other(err: String) { + description("Other error") + display("Other error {}", err) + } + } } impl From for BlockImportError { fn from(e: Error) -> Self { match *e.kind() { - ErrorKind::Block(block_error) => BlockImportError::Block(block_error), - ErrorKind::Import(import_error) => BlockImportError::Import(import_error), - _ => BlockImportError::Other(format!("other block import error: {:?}", e)), + ErrorKind::Block(block_error) => BlockImportErrorKind::Block(block_error).into(), + ErrorKind::Import(import_error) => BlockImportErrorKind::Import(import_error.into()).into(), + _ => BlockImportErrorKind::Other(format!("other block import error: {:?}", e)).into(), } } } @@ -228,6 +239,7 @@ error_chain! { Snappy(InvalidInput) #[doc = "Snappy error."]; Engine(EngineError) #[doc = "Consensus vote error."]; Ethkey(EthkeyError) #[doc = "Ethkey error."]; + AccountProvider(AccountsError) #[doc = "Account Provider error"]; } errors { @@ -243,12 +255,6 @@ error_chain! { display("Snapshot error {}", err) } - #[doc = "Account Provider error."] - AccountProvider(err: AccountsError) { - description("Account Provider error.") - display("Account Provider error {}", err) - } - #[doc = "PoW hash is invalid or out of date."] PowHashInvalid { description("PoW hash is invalid or out of date.") @@ -290,10 +296,10 @@ impl From<::rlp::DecoderError> for Error { impl From for Error { fn from(err: BlockImportError) -> Error { - match err { - BlockImportError::Block(e) => ErrorKind::Block(e).into(), - BlockImportError::Import(e) => ErrorKind::Import(e).into(), - BlockImportError::Other(s) => ErrorKind::Util(UtilError::from(s)).into(), + match *err.kind() { + BlockImportErrorKind::Block(e) => ErrorKind::Block(e).into(), + BlockImportErrorKind::Import(e) => ErrorKind::Import(e).into(), + BlockImportErrorKind::Other(s) => ErrorKind::Util(UtilError::from(s)).into(), } } } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 755294637b8..a308f26d5a7 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -24,7 +24,7 @@ use ethereum_types::{H256, U256, Address}; use parking_lot::{Mutex, RwLock}; use bytes::Bytes; use engines::{EthEngine, Seal}; -use error::{ExecutionError, Error}; +use error::{ExecutionError, Error, ErrorKind}; use ethcore_miner::banning_queue::{BanningTransactionQueue, Threshold}; use ethcore_miner::local_transactions::{Status as LocalTransactionStatus}; use ethcore_miner::transaction_queue::{ @@ -1182,7 +1182,7 @@ impl MinerService for Miner { }) } else { warn!(target: "miner", "Submitted solution rejected: Block unknown or out of date."); - Err(Error::PowHashInvalid) + Err(ErrorKind::PowHashInvalid) }; result.and_then(|sealed| { let n = sealed.header().number(); diff --git a/ethcore/src/verification/queue/kind.rs b/ethcore/src/verification/queue/kind.rs index 898435eb260..799c2991634 100644 --- a/ethcore/src/verification/queue/kind.rs +++ b/ethcore/src/verification/queue/kind.rs @@ -69,7 +69,7 @@ pub mod blocks { use super::{Kind, BlockLike}; use engines::EthEngine; - use error::{Error, BlockError}; + use error::{Error, ErrorKind, BlockError}; use header::Header; use verification::{PreverifiedBlock, verify_block_basic, verify_block_unordered}; @@ -88,7 +88,7 @@ pub mod blocks { fn create(input: Self::Input, engine: &EthEngine) -> Result { match verify_block_basic(&input.header, &input.bytes, engine) { Ok(()) => Ok(input), - Err(Error::Block(BlockError::TemporarilyInvalid(oob))) => { + Err(Error(ErrorKind::Block(BlockError::TemporarilyInvalid(oob)), _)) => { debug!(target: "client", "Block received too early {}: {:?}", input.hash(), oob); Err(BlockError::TemporarilyInvalid(oob).into()) }, diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index b6e60d042ae..2c03c7f655d 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -472,17 +472,17 @@ impl VerificationQueue { let h = input.hash(); { if self.processing.read().contains_key(&h) { - return Err(ImportError::AlreadyQueued.into()); + bail!(ErrorKind::Import(ImportErrorKind::AlreadyQueued)); } let mut bad = self.verification.bad.lock(); if bad.contains(&h) { - return Err(ImportError::KnownBad.into()); + bail!(ErrorKind::Import(ImportErrorKind::KnownBad)); } if bad.contains(&input.parent_hash()) { bad.insert(h.clone()); - return Err(ImportError::KnownBad.into()); + bail!(ErrorKind::Import(ImportErrorKind::KnownBad)); } } @@ -502,7 +502,7 @@ impl VerificationQueue { Err(err) => { match err { // Don't mark future blocks as bad. - Error::Block(BlockError::TemporarilyInvalid(_)) => {}, + Error(ErrorKind::Block(BlockError::TemporarilyInvalid(_)), _) => {}, _ => { self.verification.bad.lock().insert(h.clone()); } From 8eaace28a64a43034c8eb779dc36029501bd6da1 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 11 Apr 2018 20:06:52 +0100 Subject: [PATCH 04/12] Fix error pattern matches for error_chain in miner --- ethcore/src/miner/miner.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index a308f26d5a7..bb8f60d94fd 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -436,7 +436,7 @@ impl Miner { let start = Instant::now(); // Check whether transaction type is allowed for sender let result = match self.engine.machine().verify_transaction(&tx, open_block.header(), chain) { - Err(Error::Transaction(TransactionError::NotAllowed)) => { + Err(Error(ErrorKind::Transaction(TransactionError::NotAllowed), _)) => { Err(TransactionError::NotAllowed.into()) } _ => { @@ -462,7 +462,7 @@ impl Miner { } trace!(target: "miner", "Adding tx {:?} took {:?}", hash, took); match result { - Err(Error::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, gas })) => { + Err(Error(ErrorKind::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, gas }), _)) => { debug!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?} (limit: {:?}, used: {:?}, gas: {:?})", hash, gas_limit, gas_used, gas); // Penalize transaction if it's above current gas limit @@ -478,12 +478,12 @@ impl Miner { }, // Invalid nonce error can happen only if previous transaction is skipped because of gas limit. // If there is errornous state of transaction queue it will be fixed when next block is imported. - Err(Error::Execution(ExecutionError::InvalidNonce { expected, got })) => { + Err(Error(ErrorKind::Execution(ExecutionError::InvalidNonce { expected, got }), _)) => { debug!(target: "miner", "Skipping adding transaction to block because of invalid nonce: {:?} (expected: {:?}, got: {:?})", hash, expected, got); }, // already have transaction - ignore - Err(Error::Transaction(TransactionError::AlreadyImported)) => {}, - Err(Error::Transaction(TransactionError::NotAllowed)) => { + Err(Error(ErrorKind::Transaction(TransactionError::AlreadyImported), _)) => {}, + Err(Error(ErrorKind::Transaction(TransactionError::NotAllowed), _)) => { non_allowed_transactions.insert(hash); debug!(target: "miner", "Skipping non-allowed transaction for sender {:?}", @@ -705,7 +705,7 @@ impl Miner { let hash = tx.hash(); if client.transaction_block(TransactionId::Hash(hash)).is_some() { debug!(target: "miner", "Rejected tx {:?}: already in the blockchain", hash); - return Err(Error::Transaction(TransactionError::AlreadyImported)); + bail!(ErrorKind::Transaction(TransactionError::AlreadyImported)); } match self.engine.verify_transaction_basic(&tx, &best_block_header) .and_then(|_| self.engine.verify_transaction_unordered(tx, &best_block_header)) @@ -1178,11 +1178,11 @@ impl MinerService for Miner { trace!(target: "miner", "Submitted block {}={}={} with seal {:?}", block_hash, b.hash(), b.header().bare_hash(), seal); b.lock().try_seal(&*self.engine, seal).or_else(|(e, _)| { warn!(target: "miner", "Mined solution rejected: {}", e); - Err(Error::PowInvalid) + Err(ErrorKind::PowInvalid.into()) }) } else { warn!(target: "miner", "Submitted solution rejected: Block unknown or out of date."); - Err(ErrorKind::PowHashInvalid) + Err(ErrorKind::PowHashInvalid.into()) }; result.and_then(|sealed| { let n = sealed.header().number(); From 14adc20d0c86286d3297a386d94d5e9b64cd7aa7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 11 Apr 2018 20:19:35 +0100 Subject: [PATCH 05/12] Implement explicit From for AccountsError --- ethcore/src/error.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index ee51d1413dc..b0eb838d616 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -239,7 +239,7 @@ error_chain! { Snappy(InvalidInput) #[doc = "Snappy error."]; Engine(EngineError) #[doc = "Consensus vote error."]; Ethkey(EthkeyError) #[doc = "Ethkey error."]; - AccountProvider(AccountsError) #[doc = "Account Provider error"]; + // AccountProvider(AccountsError) #[doc = "Account Provider error"]; } errors { @@ -255,6 +255,12 @@ error_chain! { display("Snapshot error {}", err) } + #[doc = "Account Provider error"] + AccountProvider(err: AccountsError) { + description("Accounts Provider error") + display("Accounts Provider error {}", err) + } + #[doc = "PoW hash is invalid or out of date."] PowHashInvalid { description("PoW hash is invalid or out of date.") @@ -288,9 +294,15 @@ impl From for Error { } } +impl From for Error { + fn from(err: AccountsError) -> Error { + ErrorKind::AccountProvider(err).into() + } +} + impl From<::rlp::DecoderError> for Error { fn from(err: ::rlp::DecoderError) -> Error { - ErrorKind::Util(UtilError::from(err)).into() + UtilError::from(err).into() } } @@ -299,7 +311,7 @@ impl From for Error { match *err.kind() { BlockImportErrorKind::Block(e) => ErrorKind::Block(e).into(), BlockImportErrorKind::Import(e) => ErrorKind::Import(e).into(), - BlockImportErrorKind::Other(s) => ErrorKind::Util(UtilError::from(s)).into(), + BlockImportErrorKind::Other(s) => UtilError::from(s).into(), } } } From 0137d53cc05c3eabb1f66fb822e252b405c60a1c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 12 Apr 2018 13:49:32 +0100 Subject: [PATCH 06/12] Fix pattern matches for ErrorKinds --- ethcore/src/error.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index b0eb838d616..e9df2b619aa 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -196,9 +196,9 @@ error_chain! { impl From for BlockImportError { fn from(e: Error) -> Self { - match *e.kind() { - ErrorKind::Block(block_error) => BlockImportErrorKind::Block(block_error).into(), - ErrorKind::Import(import_error) => BlockImportErrorKind::Import(import_error.into()).into(), + match e { + Error(ErrorKind::Block(block_error), _) => BlockImportErrorKind::Block(block_error).into(), + Error(ErrorKind::Import(import_error), _) => BlockImportErrorKind::Import(import_error.into()).into(), _ => BlockImportErrorKind::Other(format!("other block import error: {:?}", e)).into(), } } @@ -215,8 +215,8 @@ pub enum TransactionImportError { impl From for TransactionImportError { fn from(e: Error) -> Self { - match *e.kind() { - ErrorKind::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error), + match e { + Error(ErrorKind::Transaction(transaction_error), _) => TransactionImportError::Transaction(transaction_error), _ => TransactionImportError::Other(format!("other block import error: {:?}", e)), } } @@ -239,7 +239,6 @@ error_chain! { Snappy(InvalidInput) #[doc = "Snappy error."]; Engine(EngineError) #[doc = "Consensus vote error."]; Ethkey(EthkeyError) #[doc = "Ethkey error."]; - // AccountProvider(AccountsError) #[doc = "Account Provider error"]; } errors { @@ -308,10 +307,11 @@ impl From<::rlp::DecoderError> for Error { impl From for Error { fn from(err: BlockImportError) -> Error { - match *err.kind() { - BlockImportErrorKind::Block(e) => ErrorKind::Block(e).into(), - BlockImportErrorKind::Import(e) => ErrorKind::Import(e).into(), - BlockImportErrorKind::Other(s) => UtilError::from(s).into(), + match err { + BlockImportError(BlockImportErrorKind::Block(e), _) => ErrorKind::Block(e).into(), + BlockImportError(BlockImportErrorKind::Import(e), _) => ErrorKind::Import(e).into(), + BlockImportError(BlockImportErrorKind::Other(s), _) => UtilError::from(s).into(), + _ => ErrorKind::Msg(format!("other block import error: {:?}", err)).into(), } } } From 2f1af7614ebceb0117df8f8b04610bc5a22989bd Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 12 Apr 2018 14:56:50 +0100 Subject: [PATCH 07/12] Handle ethcore error_chain in light client --- Cargo.lock | 1 + ethcore/light/Cargo.toml | 1 + ethcore/light/src/client/header_chain.rs | 15 +++++++-------- ethcore/light/src/lib.rs | 2 ++ 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7661fc3ab3..75780991822 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -599,6 +599,7 @@ name = "ethcore-light" version = "1.11.0" dependencies = [ "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.11.0", "ethcore-bytes 0.1.0", "ethcore-io 1.11.0", diff --git a/ethcore/light/Cargo.toml b/ethcore/light/Cargo.toml index 9de1ceb9e7a..ba76dc3b104 100644 --- a/ethcore/light/Cargo.toml +++ b/ethcore/light/Cargo.toml @@ -35,6 +35,7 @@ keccak-hash = { path = "../../util/hash" } triehash = { path = "../../util/triehash" } kvdb = { path = "../../util/kvdb" } memory-cache = { path = "../../util/memory_cache" } +error-chain = { version = "0.11", default-features = false } [dev-dependencies] kvdb-memorydb = { path = "../../util/kvdb-memorydb" } diff --git a/ethcore/light/src/client/header_chain.rs b/ethcore/light/src/client/header_chain.rs index 84b7916eef8..0fee5ba6f40 100644 --- a/ethcore/light/src/client/header_chain.rs +++ b/ethcore/light/src/client/header_chain.rs @@ -31,7 +31,7 @@ use std::sync::Arc; use cht; use ethcore::block_status::BlockStatus; -use ethcore::error::{Error, BlockImportError, BlockError}; +use ethcore::error::{Error, ErrorKind, BlockImportError, BlockImportErrorKind, BlockError}; use ethcore::encoded; use ethcore::header::Header; use ethcore::ids::BlockId; @@ -260,7 +260,7 @@ impl HeaderChain { let best_block = { let era = match candidates.get(&curr.best_num) { Some(era) => era, - None => return Err(Error::Database("Database corrupt: highest block referenced but no data.".into())), + None => bail!(ErrorKind::Database("Database corrupt: highest block referenced but no data.".into())), }; let best = &era.candidates[0]; @@ -332,8 +332,7 @@ impl HeaderChain { // instantiate genesis epoch data if it doesn't exist. if let None = chain.db.get(col, LAST_CANONICAL_TRANSITION)? { - let genesis_data = spec.genesis_epoch_data() - .map_err(|s| Error::Database(s.into()))?; + let genesis_data = spec.genesis_epoch_data()?; { let mut batch = chain.db.transaction(); @@ -411,7 +410,7 @@ impl HeaderChain { .and_then(|entry| entry.candidates.iter().find(|c| c.hash == parent_hash)) .map(|c| c.total_difficulty) .ok_or_else(|| BlockError::UnknownParent(parent_hash)) - .map_err(BlockImportError::Block)? + .map_err(BlockImportErrorKind::Block)? }; parent_td + *header.difficulty() @@ -580,7 +579,7 @@ impl HeaderChain { } else { let msg = format!("header of block #{} not found in DB ; database in an \ inconsistent state", h_num); - return Err(Error::Database(msg.into())); + bail!(ErrorKind::Database(msg.into())); }; let decoded = header.decode(); @@ -590,7 +589,7 @@ impl HeaderChain { .ok_or_else(|| { let msg = format!("entry for era #{} not found in DB ; database \ in an inconsistent state", h_num); - Error::Database(msg.into()) + ErrorKind::Database(msg.into()) })?; ::rlp::decode(&bytes) }; @@ -600,7 +599,7 @@ impl HeaderChain { .ok_or_else(|| { let msg = "no candidate matching block found in DB ; database in an \ inconsistent state"; - Error::Database(msg.into()) + ErrorKind::Database(msg.into()) })? .total_difficulty; diff --git a/ethcore/light/src/lib.rs b/ethcore/light/src/lib.rs index 1ffe0079c18..9723854b8d5 100644 --- a/ethcore/light/src/lib.rs +++ b/ethcore/light/src/lib.rs @@ -80,6 +80,8 @@ extern crate keccak_hash as hash; extern crate triehash; extern crate kvdb; extern crate memory_cache; +#[macro_use] +extern crate error_chain; #[cfg(test)] extern crate kvdb_memorydb; From 843d0574e34e3a7e4a3788c0f91b786b8a196ce7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 12 Apr 2018 15:02:21 +0100 Subject: [PATCH 08/12] Explicitly define Result type to avoid shadowing --- ethcore/src/error.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index e9df2b619aa..718337aa121 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -223,6 +223,10 @@ impl From for TransactionImportError { } error_chain! { + types { + Error, ErrorKind, ErrorResultExt, EthcoreResult; + } + links { Database(kvdb::Error, kvdb::ErrorKind) #[doc = "Database error."]; Util(UtilError, util_error::ErrorKind) #[doc = "Error concerning a utility"]; @@ -282,7 +286,7 @@ error_chain! { /// Result of import block operation. -pub type ImportResult = Result; +pub type ImportResult = EthcoreResult; impl From for Error { fn from(err: ClientError) -> Error { From dde009b5325fe3e3cc88a4faca3e7b3064ca1271 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 12 Apr 2018 15:53:43 +0100 Subject: [PATCH 09/12] Fix remaining Error pattern matches --- ethcore/src/client/mod.rs | 2 +- ethcore/sync/src/block_sync.rs | 14 +++++++------- ethcore/sync/src/chain.rs | 8 ++++---- parity/blockchain.rs | 8 ++++---- rpc/src/v1/helpers/errors.rs | 10 +++++----- rpc/src/v1/types/transaction.rs | 2 +- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 2ae3436aa98..0a53a1f8dd2 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -48,7 +48,7 @@ pub use types::call_analytics::CallAnalytics; pub use executive::{Executed, Executive, TransactOptions}; pub use vm::{LastHashes, EnvInfo}; -pub use error::{BlockImportError, TransactionImportError}; +pub use error::{BlockImportError, BlockImportErrorKind, TransactionImportError}; pub use verification::VerifierType; mod traits; diff --git a/ethcore/sync/src/block_sync.rs b/ethcore/sync/src/block_sync.rs index 5cf81b2e86d..ff289b5dc69 100644 --- a/ethcore/sync/src/block_sync.rs +++ b/ethcore/sync/src/block_sync.rs @@ -25,9 +25,9 @@ use ethereum_types::H256; use rlp::UntrustedRlp; use ethcore::views::{BlockView}; use ethcore::header::{BlockNumber, Header as BlockHeader}; -use ethcore::client::{BlockStatus, BlockId, BlockImportError}; +use ethcore::client::{BlockStatus, BlockId, BlockImportError, BlockImportErrorKind}; use ethcore::block::Block; -use ethcore::error::{ImportError, BlockError}; +use ethcore::error::{ImportErrorKind, BlockError}; use sync_io::SyncIo; use blocks::BlockCollection; @@ -502,11 +502,11 @@ impl BlockDownloader { }; match result { - Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => { trace!(target: "sync", "Block already in chain {:?}", h); self.block_imported(&h, number, &parent); }, - Err(BlockImportError::Import(ImportError::AlreadyQueued)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyQueued), _)) => { trace!(target: "sync", "Block already queued {:?}", h); self.block_imported(&h, number, &parent); }, @@ -515,14 +515,14 @@ impl BlockDownloader { imported.insert(h.clone()); self.block_imported(&h, number, &parent); }, - Err(BlockImportError::Block(BlockError::UnknownParent(_))) if allow_out_of_order => { + Err(BlockImportError(BlockImportErrorKind::Block(BlockError::UnknownParent(_)), _)) if allow_out_of_order => { break; }, - Err(BlockImportError::Block(BlockError::UnknownParent(_))) => { + Err(BlockImportError(BlockImportErrorKind::Block(BlockError::UnknownParent(_)), _)) => { trace!(target: "sync", "Unknown new block parent, restarting sync"); break; }, - Err(BlockImportError::Block(BlockError::TemporarilyInvalid(_))) => { + Err(BlockImportError(BlockImportErrorKind::Block(BlockError::TemporarilyInvalid(_)), _)) => { debug!(target: "sync", "Block temporarily invalid, restarting sync"); break; }, diff --git a/ethcore/sync/src/chain.rs b/ethcore/sync/src/chain.rs index b2494e1f038..e1a8a7269ea 100644 --- a/ethcore/sync/src/chain.rs +++ b/ethcore/sync/src/chain.rs @@ -101,7 +101,7 @@ use bytes::Bytes; use rlp::{UntrustedRlp, RlpStream, DecoderError, Encodable}; use network::{self, PeerId, PacketId}; use ethcore::header::{BlockNumber, Header as BlockHeader}; -use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockImportError, BlockQueueInfo}; +use ethcore::client::{BlockChainClient, BlockStatus, BlockId, BlockChainInfo, BlockImportError, BlockImportErrorKind, BlockQueueInfo}; use ethcore::error::*; use ethcore::snapshot::{ManifestData, RestorationStatus}; use transaction::PendingTransaction; @@ -942,10 +942,10 @@ impl ChainSync { return Ok(()); } match io.chain().import_block(block_rlp.as_raw().to_vec()) { - Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => { trace!(target: "sync", "New block already in chain {:?}", h); }, - Err(BlockImportError::Import(ImportError::AlreadyQueued)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyQueued), _)) => { trace!(target: "sync", "New block already queued {:?}", h); }, Ok(_) => { @@ -954,7 +954,7 @@ impl ChainSync { self.new_blocks.mark_as_known(&header.hash(), header.number()); trace!(target: "sync", "New block queued {:?} ({})", h, header.number()); }, - Err(BlockImportError::Block(BlockError::UnknownParent(p))) => { + Err(BlockImportError(BlockImportErrorKind::Block(BlockError::UnknownParent(p)), _)) => { unknown = true; trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h); }, diff --git a/parity/blockchain.rs b/parity/blockchain.rs index c2c6f2aa5cf..4a45478a9c8 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -26,9 +26,9 @@ use ethereum_types::{U256, H256, Address}; use bytes::ToPretty; use rlp::PayloadInfo; use ethcore::account_provider::AccountProvider; -use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockImportError, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock}; +use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockImportError, BlockImportErrorKind, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock}; use ethcore::db::NUM_COLUMNS; -use ethcore::error::ImportError; +use ethcore::error::ImportErrorKind; use ethcore::miner::Miner; use ethcore::verification::queue::VerifierSettings; use ethcore_service::ClientService; @@ -268,7 +268,7 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> { } match client.import_header(header) { - Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => { trace!("Skipping block already in chain."); } Err(e) => { @@ -438,7 +438,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> { let do_import = |bytes| { while client.queue_info().is_full() { sleep(Duration::from_secs(1)); } match client.import_block(bytes) { - Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => { trace!("Skipping block already in chain."); } Err(e) => { diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index 6e8836c20d4..977ee84cad4 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -19,7 +19,7 @@ use std::fmt; use ethcore::account_provider::{SignError as AccountError}; -use ethcore::error::{Error as EthcoreError, CallError}; +use ethcore::error::{Error as EthcoreError, ErrorKind, CallError}; use jsonrpc_core::{futures, Error, ErrorCode, Value}; use rlp::DecoderError; use transaction::Error as TransactionError; @@ -306,10 +306,10 @@ pub fn private_message_block_id_not_supported() -> Error { } } -pub fn transaction_message(error: TransactionError) -> String { +pub fn transaction_message(error: &TransactionError) -> String { use self::TransactionError::*; - match error { + match *error { AlreadyImported => "Transaction with the same hash was already imported.".into(), Old => "Transaction nonce is too low. Try incrementing the nonce.".into(), TooCheapToReplace => { @@ -330,7 +330,7 @@ pub fn transaction_message(error: TransactionError) -> String { GasLimitExceeded { limit, got } => { format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got) }, - InvalidSignature(sig) => format!("Invalid signature: {}", sig), + InvalidSignature(ref sig) => format!("Invalid signature: {}", sig), InvalidChainId => "Invalid chain id.".into(), InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(), SenderBanned => "Sender is banned in local queue.".into(), @@ -342,7 +342,7 @@ pub fn transaction_message(error: TransactionError) -> String { pub fn transaction>(error: T) -> Error { let error = error.into(); - if let EthcoreError::Transaction(e) = error { + if let ErrorKind::Transaction(ref e) = *error.kind() { Error { code: ErrorCode::ServerError(codes::TRANSACTION_ERROR), message: transaction_message(e), diff --git a/rpc/src/v1/types/transaction.rs b/rpc/src/v1/types/transaction.rs index c5dd63624f5..99a14670e2d 100644 --- a/rpc/src/v1/types/transaction.rs +++ b/rpc/src/v1/types/transaction.rs @@ -255,7 +255,7 @@ impl LocalTransactionStatus { Future => LocalTransactionStatus::Future, Mined(tx) => LocalTransactionStatus::Mined(Transaction::from_signed(tx, block_number, eip86_transition)), Dropped(tx) => LocalTransactionStatus::Dropped(Transaction::from_signed(tx, block_number, eip86_transition)), - Rejected(tx, err) => LocalTransactionStatus::Rejected(Transaction::from_signed(tx, block_number, eip86_transition), errors::transaction_message(err)), + Rejected(tx, err) => LocalTransactionStatus::Rejected(Transaction::from_signed(tx, block_number, eip86_transition), errors::transaction_message(&err)), Replaced(tx, gas_price, hash) => LocalTransactionStatus::Replaced(Transaction::from_signed(tx, block_number, eip86_transition), gas_price.into(), hash.into()), Invalid(tx) => LocalTransactionStatus::Invalid(Transaction::from_signed(tx, block_number, eip86_transition)), Canceled(tx) => LocalTransactionStatus::Canceled(Transaction::from_pending(tx, block_number, eip86_transition)), From 59acab48abfff6d9e8f322bbb3d40307e55e02b7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 12 Apr 2018 16:18:25 +0100 Subject: [PATCH 10/12] Fix tab space formatting --- ethcore/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index 718337aa121..accb0156184 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -264,7 +264,7 @@ error_chain! { display("Accounts Provider error {}", err) } - #[doc = "PoW hash is invalid or out of date."] + #[doc = "PoW hash is invalid or out of date."] PowHashInvalid { description("PoW hash is invalid or out of date.") display("PoW hash is invalid or out of date.") From c62ab95d84f6daad5d4becd0422606671f908da2 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 13 Apr 2018 08:57:23 +0100 Subject: [PATCH 11/12] Helps if the tests compile --- ethcore/src/engines/authority_round/mod.rs | 8 ++++---- ethcore/src/engines/tendermint/mod.rs | 18 +++++++++--------- ethcore/src/ethereum/ethash.rs | 18 +++++++++--------- ethcore/src/snapshot/tests/proof_of_work.rs | 4 ++-- ethcore/src/snapshot/tests/state.rs | 4 ++-- ethcore/src/verification/queue/mod.rs | 2 +- ethcore/src/verification/verification.rs | 9 +++++---- 7 files changed, 32 insertions(+), 31 deletions(-) diff --git a/ethcore/src/engines/authority_round/mod.rs b/ethcore/src/engines/authority_round/mod.rs index 8282e5738a8..6c8ede3df4f 100644 --- a/ethcore/src/engines/authority_round/mod.rs +++ b/ethcore/src/engines/authority_round/mod.rs @@ -1335,7 +1335,7 @@ mod tests { use transaction::{Action, Transaction}; use engines::{Seal, Engine, EngineError, EthEngine}; use engines::validator_set::TestSet; - use error::Error; + use error::{Error, ErrorKind}; use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep}; #[test] @@ -1838,7 +1838,7 @@ mod tests { ]); assert!(match engine.verify_block_family(&header, &parent_header) { - Err(Error::Engine(EngineError::InsufficientProof(ref s))) + Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) if s.contains("invalid step") => true, _ => false, }); @@ -1852,7 +1852,7 @@ mod tests { ]); assert!(match engine.verify_block_family(&header, &parent_header) { - Err(Error::Engine(EngineError::InsufficientProof(ref s))) + Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) if s.contains("invalid empty step proof") => true, _ => false, }); @@ -1867,7 +1867,7 @@ mod tests { ]); assert!(match engine.verify_block_family(&header, &parent_header) { - Err(Error::Engine(EngineError::InsufficientProof(ref s))) + Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) if s.contains("invalid empty step proof") => true, _ => false, }); diff --git a/ethcore/src/engines/tendermint/mod.rs b/ethcore/src/engines/tendermint/mod.rs index 011e3f8d425..94c6be27c53 100644 --- a/ethcore/src/engines/tendermint/mod.rs +++ b/ethcore/src/engines/tendermint/mod.rs @@ -778,7 +778,7 @@ mod tests { use ethereum_types::Address; use bytes::Bytes; use block::*; - use error::{Error, BlockError}; + use error::{Error, ErrorKind, BlockError}; use header::Header; use client::ChainInfo; use miner::MinerService; @@ -865,7 +865,7 @@ mod tests { let verify_result = engine.verify_block_basic(&header); match verify_result { - Err(Error::Block(BlockError::InvalidSealArity(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::InvalidSealArity(_)), _)) => {}, Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -895,7 +895,7 @@ mod tests { header.set_seal(seal); // Bad proposer. match engine.verify_block_external(&header) { - Err(Error::Engine(EngineError::NotProposer(_))) => {}, + Err(Error(ErrorKind::Engine(EngineError::NotProposer(_)), _)) => {}, _ => panic!(), } @@ -905,7 +905,7 @@ mod tests { header.set_seal(seal); // Not authority. match engine.verify_block_external(&header) { - Err(Error::Engine(EngineError::NotAuthorized(_))) => {}, + Err(Error(ErrorKind::Engine(EngineError::NotAuthorized(_)), _)) => {}, _ => panic!(), }; engine.stop(); @@ -935,7 +935,7 @@ mod tests { // One good signature is not enough. match engine.verify_block_external(&header) { - Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {}, + Err(Error(ErrorKind::Engine(EngineError::BadSealFieldSize(_)), _)) => {}, _ => panic!(), } @@ -955,7 +955,7 @@ mod tests { // One good and one bad signature. match engine.verify_block_external(&header) { - Err(Error::Engine(EngineError::NotAuthorized(_))) => {}, + Err(Error(ErrorKind::Engine(EngineError::NotAuthorized(_)), _)) => {}, _ => panic!(), }; engine.stop(); @@ -1102,7 +1102,7 @@ mod tests { } else if *s == signature0 { Ok(voter) } else { - Err(Error::Ethkey(EthkeyError::InvalidSignature)) + Err(ErrorKind::Ethkey(EthkeyError::InvalidSignature).into()) } } }, @@ -1110,7 +1110,7 @@ mod tests { // One good signature is not enough. match epoch_verifier.verify_light(&header) { - Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {}, + Err(Error(ErrorKind::Engine(EngineError::BadSealFieldSize(_)), _)) => {}, _ => panic!(), } @@ -1127,7 +1127,7 @@ mod tests { // One good and one bad signature. match epoch_verifier.verify_light(&header) { - Err(Error::Ethkey(EthkeyError::InvalidSignature)) => {}, + Err(Error(ErrorKind::Ethkey(EthkeyError::InvalidSignature), _)) => {}, _ => panic!(), }; diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 41ab777d4a7..4671ff5923f 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -488,7 +488,7 @@ mod tests { use ethereum_types::{H64, H256, U256, Address}; use block::*; use test_helpers::get_temp_state_db; - use error::{BlockError, Error}; + use error::{BlockError, Error, ErrorKind}; use header::Header; use spec::Spec; use engines::Engine; @@ -640,7 +640,7 @@ mod tests { let verify_result = engine.verify_block_basic(&header); match verify_result { - Err(Error::Block(BlockError::InvalidSealArity(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::InvalidSealArity(_)), _)) => {}, Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -655,7 +655,7 @@ mod tests { let verify_result = engine.verify_block_basic(&header); match verify_result { - Err(Error::Block(BlockError::DifficultyOutOfBounds(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::DifficultyOutOfBounds(_)), _)) => {}, Err(_) => { panic!("should be block difficulty error (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -671,7 +671,7 @@ mod tests { let verify_result = engine.verify_block_basic(&header); match verify_result { - Err(Error::Block(BlockError::InvalidProofOfWork(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::InvalidProofOfWork(_)), _)) => {}, Err(_) => { panic!("should be invalid proof of work error (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -685,7 +685,7 @@ mod tests { let verify_result = engine.verify_block_unordered(&header); match verify_result { - Err(Error::Block(BlockError::InvalidSealArity(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::InvalidSealArity(_)), _)) => {}, Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -710,7 +710,7 @@ mod tests { let verify_result = engine.verify_block_unordered(&header); match verify_result { - Err(Error::Block(BlockError::MismatchedH256SealElement(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::MismatchedH256SealElement(_)), _)) => {}, Err(_) => { panic!("should be invalid 256-bit seal fail (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -726,7 +726,7 @@ mod tests { let verify_result = engine.verify_block_unordered(&header); match verify_result { - Err(Error::Block(BlockError::InvalidProofOfWork(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::InvalidProofOfWork(_)), _)) => {}, Err(_) => { panic!("should be invalid proof-of-work fail (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -741,7 +741,7 @@ mod tests { let verify_result = engine.verify_block_family(&header, &parent_header); match verify_result { - Err(Error::Block(BlockError::RidiculousNumber(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::RidiculousNumber(_)), _)) => {}, Err(_) => { panic!("should be invalid block number fail (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } @@ -758,7 +758,7 @@ mod tests { let verify_result = engine.verify_block_family(&header, &parent_header); match verify_result { - Err(Error::Block(BlockError::InvalidDifficulty(_))) => {}, + Err(Error(ErrorKind::Block(BlockError::InvalidDifficulty(_)), _)) => {}, Err(_) => { panic!("should be invalid difficulty fail (got {:?})", verify_result); }, _ => { panic!("Should be error, got Ok"); }, } diff --git a/ethcore/src/snapshot/tests/proof_of_work.rs b/ethcore/src/snapshot/tests/proof_of_work.rs index e41b61e6e06..ae1805e85bd 100644 --- a/ethcore/src/snapshot/tests/proof_of_work.rs +++ b/ethcore/src/snapshot/tests/proof_of_work.rs @@ -19,7 +19,7 @@ use std::sync::Arc; use std::sync::atomic::AtomicBool; use tempdir::TempDir; -use error::Error; +use error::{Error, ErrorKind}; use blockchain::generator::{BlockGenerator, BlockBuilder}; use blockchain::BlockChain; @@ -141,7 +141,7 @@ fn checks_flag() { let mut rebuilder = SNAPSHOT_MODE.rebuilder(chain, db.clone(), &manifest).unwrap(); match rebuilder.feed(&chunk, engine.as_ref(), &AtomicBool::new(false)) { - Err(Error::Snapshot(SnapshotError::RestorationAborted)) => {} + Err(Error(ErrorKind::Snapshot(SnapshotError::RestorationAborted), _)) => {} _ => panic!("Wrong result on abort flag set") } } diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index f61c799933c..f17fa7dde5a 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -26,7 +26,7 @@ use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder}; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use super::helpers::{compare_dbs, StateProducer}; -use error::Error; +use error::{Error, ErrorKind}; use rand::{XorShiftRng, SeedableRng}; use ethereum_types::H256; @@ -189,7 +189,7 @@ fn checks_flag() { let chunk = ::snappy::decompress(&raw).unwrap(); match rebuilder.feed(&chunk, &flag) { - Err(Error::Snapshot(SnapshotError::RestorationAborted)) => {}, + Err(Error(ErrorKind::Snapshot(SnapshotError::RestorationAborted), _)) => {}, _ => panic!("unexpected result when feeding with flag off"), } } diff --git a/ethcore/src/verification/queue/mod.rs b/ethcore/src/verification/queue/mod.rs index 2c03c7f655d..a500cac6aa9 100644 --- a/ethcore/src/verification/queue/mod.rs +++ b/ethcore/src/verification/queue/mod.rs @@ -773,7 +773,7 @@ mod tests { match duplicate_import { Err(e) => { match e { - Error::Import(ImportError::AlreadyQueued) => {}, + Error(ErrorKind::Import(ImportErrorKind::AlreadyQueued), _) => {}, _ => { panic!("must return AlreadyQueued error"); } } } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index e50eb79194d..f38fd095da4 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -357,6 +357,7 @@ mod tests { use hash::keccak; use engines::EthEngine; use error::BlockError::*; + use error::ErrorKind; use ethkey::{Random, Generator}; use spec::{CommonParams, Spec}; use test_helpers::{create_test_block_with_data, create_test_block}; @@ -371,7 +372,7 @@ mod tests { fn check_fail(result: Result<(), Error>, e: BlockError) { match result { - Err(Error::Block(ref error)) if *error == e => (), + Err(Error(ErrorKind::Block(ref error), _)) if *error == e => (), Err(other) => panic!("Block verification failed.\nExpected: {:?}\nGot: {:?}", e, other), Ok(_) => panic!("Block verification failed.\nExpected: {:?}\nGot: Ok", e), } @@ -380,8 +381,8 @@ mod tests { fn check_fail_timestamp(result: Result<(), Error>, temp: bool) { let name = if temp { "TemporarilyInvalid" } else { "InvalidTimestamp" }; match result { - Err(Error::Block(BlockError::InvalidTimestamp(_))) if !temp => (), - Err(Error::Block(BlockError::TemporarilyInvalid(_))) if temp => (), + Err(Error(ErrorKind::Block(BlockError::InvalidTimestamp(_)), _)) if !temp => (), + Err(Error(ErrorKind::Block(BlockError::TemporarilyInvalid(_)), _)) if temp => (), Err(other) => panic!("Block verification failed.\nExpected: {}\nGot: {:?}", name, other), Ok(_) => panic!("Block verification failed.\nExpected: {}\nGot: Ok", name), } @@ -716,7 +717,7 @@ mod tests { header.set_gas_limit(0.into()); header.set_difficulty("0000000000000000000000000000000000000000000000000000000000020000".parse::().unwrap()); match family_test(&create_test_block(&header), engine, &bc) { - Err(Error::Block(InvalidGasLimit(_))) => {}, + Err(Error(ErrorKind::Block(InvalidGasLimit(_)), _)) => {}, Err(_) => { panic!("should be invalid difficulty fail"); }, _ => { panic!("Should be error, got Ok"); }, } From 0bf4e65c27285449e608a8245c37ff2728669113 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 16 Apr 2018 11:02:47 +0100 Subject: [PATCH 12/12] Fix error chain matching after merge --- ethcore/src/lib.rs | 2 ++ ethcore/src/miner/miner.rs | 8 ++++---- ethcore/sync/src/light_sync/mod.rs | 6 +++--- parity/blockchain.rs | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index 1552ec60872..659a9abc1e0 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -116,6 +116,8 @@ extern crate ethabi_derive; #[macro_use] extern crate ethabi_contract; #[macro_use] +extern crate error_chain; +#[macro_use] extern crate log; #[macro_use] extern crate lazy_static; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 0e6f63d1b6c..76a011343fb 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -21,7 +21,7 @@ use std::sync::Arc; use ansi_term::Colour; use bytes::Bytes; use engines::{EthEngine, Seal}; -use error::{Error, ExecutionError}; +use error::{Error, ErrorKind, ExecutionError}; use ethcore_miner::gas_pricer::GasPricer; use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy}; use ethcore_miner::work_notify::NotifyWork; @@ -393,7 +393,7 @@ impl Miner { // Re-verify transaction again vs current state. let result = client.verify_signed(&transaction) - .map_err(Error::Transaction) + .map_err(|e| e.into()) .and_then(|_| { open_block.push_transaction(transaction, None) }); @@ -440,8 +440,8 @@ impl Miner { debug!(target: "miner", "Skipping adding transaction to block because of invalid nonce: {:?} (expected: {:?}, got: {:?})", hash, expected, got); }, // already have transaction - ignore - Err(Error::Transaction(transaction::Error::AlreadyImported)) => {}, - Err(Error::Transaction(transaction::Error::NotAllowed)) => { + Err(Error(ErrorKind::Transaction(transaction::Error::AlreadyImported), _)) => {}, + Err(Error(ErrorKind::Transaction(transaction::Error::NotAllowed), _)) => { not_allowed_transactions.insert(hash); debug!(target: "miner", "Skipping non-allowed transaction for sender {:?}", hash); }, diff --git a/ethcore/sync/src/light_sync/mod.rs b/ethcore/sync/src/light_sync/mod.rs index 0f6660e179f..9fa669817ae 100644 --- a/ethcore/sync/src/light_sync/mod.rs +++ b/ethcore/sync/src/light_sync/mod.rs @@ -427,7 +427,7 @@ impl LightSync { // handles request dispatch, block import, state machine transitions, and timeouts. fn maintain_sync(&self, ctx: &BasicContext) { - use ethcore::error::{BlockImportError, ImportError}; + use ethcore::error::{BlockImportError, BlockImportErrorKind, ImportErrorKind}; const DRAIN_AMOUNT: usize = 128; @@ -457,10 +457,10 @@ impl LightSync { for header in sink.drain(..) { match client.queue_header(header) { Ok(_) => {} - Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => { trace!(target: "sync", "Block already in chain. Continuing."); }, - Err(BlockImportError::Import(ImportError::AlreadyQueued)) => { + Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyQueued), _)) => { trace!(target: "sync", "Block already queued. Continuing."); }, Err(e) => { diff --git a/parity/blockchain.rs b/parity/blockchain.rs index 9716b7bbbba..8f0942437f6 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -27,7 +27,7 @@ use bytes::ToPretty; use rlp::PayloadInfo; use ethcore::account_provider::AccountProvider; use ethcore::client::{Mode, DatabaseCompactionProfile, VMType, BlockImportError, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock}; -use ethcore::error::ImportError; +use ethcore::error::{ImportErrorKind, BlockImportErrorKind}; use ethcore::miner::Miner; use ethcore::verification::queue::VerifierSettings; use ethcore_service::ClientService;