Move ethcore::Error to error_chain (#8386)

* WIP

* Convert Ethcore error to use error_chain

* Use error_chain for ImportError and BlockImportError

* Fix error pattern matches for error_chain in miner

* Implement explicit From for AccountsError

* Fix pattern matches for ErrorKinds

* Handle ethcore error_chain in light client

* Explicitly define Result type to avoid shadowing

* Fix remaining Error pattern matches

* Fix tab space formatting

* Helps if the tests compile

* Fix error chain matching after merge
This commit is contained in:
Andrew Jones 2018-04-19 10:52:54 +01:00 committed by Afri Schoedon
parent 2257bc8e2f
commit 14361cc7b1
27 changed files with 249 additions and 274 deletions

2
Cargo.lock generated
View File

@ -512,6 +512,7 @@ dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0", "common-types 0.1.0",
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "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 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-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)", "ethabi-derive 5.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -613,6 +614,7 @@ name = "ethcore-light"
version = "1.11.0" version = "1.11.0"
dependencies = [ dependencies = [
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "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 1.11.0",
"ethcore-bytes 0.1.0", "ethcore-bytes 0.1.0",
"ethcore-io 1.11.0", "ethcore-io 1.11.0",

View File

@ -20,6 +20,7 @@ fetch = { path = "../util/fetch" }
hashdb = { path = "../util/hashdb" } hashdb = { path = "../util/hashdb" }
memorydb = { path = "../util/memorydb" } memorydb = { path = "../util/memorydb" }
patricia-trie = { path = "../util/patricia_trie" } patricia-trie = { path = "../util/patricia_trie" }
error-chain = { version = "0.11", default-features = false }
ethcore-io = { path = "../util/io" } ethcore-io = { path = "../util/io" }
ethcore-logger = { path = "../logger" } ethcore-logger = { path = "../logger" }
ethcore-miner = { path = "../miner" } ethcore-miner = { path = "../miner" }

View File

@ -35,6 +35,7 @@ keccak-hash = { path = "../../util/hash" }
triehash = { path = "../../util/triehash" } triehash = { path = "../../util/triehash" }
kvdb = { path = "../../util/kvdb" } kvdb = { path = "../../util/kvdb" }
memory-cache = { path = "../../util/memory_cache" } memory-cache = { path = "../../util/memory_cache" }
error-chain = { version = "0.11", default-features = false }
[dev-dependencies] [dev-dependencies]
kvdb-memorydb = { path = "../../util/kvdb-memorydb" } kvdb-memorydb = { path = "../../util/kvdb-memorydb" }

View File

@ -31,7 +31,7 @@ use std::sync::Arc;
use cht; use cht;
use ethcore::block_status::BlockStatus; use ethcore::block_status::BlockStatus;
use ethcore::error::{Error, BlockImportError, BlockError}; use ethcore::error::{Error, ErrorKind, BlockImportError, BlockImportErrorKind, BlockError};
use ethcore::encoded; use ethcore::encoded;
use ethcore::header::Header; use ethcore::header::Header;
use ethcore::ids::BlockId; use ethcore::ids::BlockId;
@ -260,7 +260,7 @@ impl HeaderChain {
let best_block = { let best_block = {
let era = match candidates.get(&curr.best_num) { let era = match candidates.get(&curr.best_num) {
Some(era) => era, 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]; let best = &era.candidates[0];
@ -332,8 +332,7 @@ impl HeaderChain {
// instantiate genesis epoch data if it doesn't exist. // instantiate genesis epoch data if it doesn't exist.
if let None = chain.db.get(col, LAST_CANONICAL_TRANSITION)? { if let None = chain.db.get(col, LAST_CANONICAL_TRANSITION)? {
let genesis_data = spec.genesis_epoch_data() let genesis_data = spec.genesis_epoch_data()?;
.map_err(|s| Error::Database(s.into()))?;
{ {
let mut batch = chain.db.transaction(); let mut batch = chain.db.transaction();
@ -411,7 +410,7 @@ impl HeaderChain {
.and_then(|entry| entry.candidates.iter().find(|c| c.hash == parent_hash)) .and_then(|entry| entry.candidates.iter().find(|c| c.hash == parent_hash))
.map(|c| c.total_difficulty) .map(|c| c.total_difficulty)
.ok_or_else(|| BlockError::UnknownParent(parent_hash)) .ok_or_else(|| BlockError::UnknownParent(parent_hash))
.map_err(BlockImportError::Block)? .map_err(BlockImportErrorKind::Block)?
}; };
parent_td + *header.difficulty() parent_td + *header.difficulty()
@ -580,7 +579,7 @@ impl HeaderChain {
} else { } else {
let msg = format!("header of block #{} not found in DB ; database in an \ let msg = format!("header of block #{} not found in DB ; database in an \
inconsistent state", h_num); inconsistent state", h_num);
return Err(Error::Database(msg.into())); bail!(ErrorKind::Database(msg.into()));
}; };
let decoded = header.decode(); let decoded = header.decode();
@ -590,7 +589,7 @@ impl HeaderChain {
.ok_or_else(|| { .ok_or_else(|| {
let msg = format!("entry for era #{} not found in DB ; database \ let msg = format!("entry for era #{} not found in DB ; database \
in an inconsistent state", h_num); in an inconsistent state", h_num);
Error::Database(msg.into()) ErrorKind::Database(msg.into())
})?; })?;
::rlp::decode(&bytes) ::rlp::decode(&bytes)
}; };
@ -600,7 +599,7 @@ impl HeaderChain {
.ok_or_else(|| { .ok_or_else(|| {
let msg = "no candidate matching block found in DB ; database in an \ let msg = "no candidate matching block found in DB ; database in an \
inconsistent state"; inconsistent state";
Error::Database(msg.into()) ErrorKind::Database(msg.into())
})? })?
.total_difficulty; .total_difficulty;

View File

@ -80,6 +80,8 @@ extern crate keccak_hash as hash;
extern crate triehash; extern crate triehash;
extern crate kvdb; extern crate kvdb;
extern crate memory_cache; extern crate memory_cache;
#[macro_use]
extern crate error_chain;
#[cfg(test)] #[cfg(test)]
extern crate kvdb_memorydb; extern crate kvdb_memorydb;

View File

@ -49,7 +49,7 @@ use client::{
}; };
use encoded; use encoded;
use engines::{EthEngine, EpochTransition}; 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 vm::{EnvInfo, LastHashes};
use evm::Schedule; use evm::Schedule;
use executive::{Executive, Executed, TransactOptions, contract_address}; use executive::{Executive, Executed, TransactOptions, contract_address};
@ -1417,11 +1417,11 @@ impl ImportBlock for Client {
{ {
if self.chain.read().is_known(&unverified.hash()) { 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())); let status = self.block_status(BlockId::Hash(unverified.parent_hash()));
if status == BlockStatus::Unknown || status == BlockStatus::Pending { 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)?) Ok(self.importer.block_queue.import(unverified)?)
@ -1432,11 +1432,11 @@ impl ImportBlock for Client {
// check block order // check block order
let header = view!(BlockView, &block_bytes).header_view(); let header = view!(BlockView, &block_bytes).header_view();
if self.chain.read().is_known(&header.hash()) { 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())); let status = self.block_status(BlockId::Hash(header.parent_hash()));
if status == BlockStatus::Unknown || status == BlockStatus::Pending { if status == BlockStatus::Unknown || status == BlockStatus::Pending {
return Err(BlockImportError::Block(BlockError::UnknownParent(header.parent_hash()))); bail!(BlockImportErrorKind::Block(BlockError::UnknownParent(header.parent_hash())));
} }
} }

View File

@ -48,7 +48,7 @@ pub use types::call_analytics::CallAnalytics;
pub use executive::{Executed, Executive, TransactOptions}; pub use executive::{Executed, Executive, TransactOptions};
pub use vm::{LastHashes, EnvInfo}; pub use vm::{LastHashes, EnvInfo};
pub use error::{BlockImportError, TransactionImportError}; pub use error::{BlockImportError, BlockImportErrorKind, TransactionImportError};
pub use verification::VerifierType; pub use verification::VerifierType;
mod traits; mod traits;

View File

@ -1339,7 +1339,7 @@ mod tests {
use transaction::{Action, Transaction}; use transaction::{Action, Transaction};
use engines::{Seal, Engine, EngineError, EthEngine}; use engines::{Seal, Engine, EngineError, EthEngine};
use engines::validator_set::TestSet; use engines::validator_set::TestSet;
use error::Error; use error::{Error, ErrorKind};
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep}; use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep};
#[test] #[test]
@ -1842,7 +1842,7 @@ mod tests {
]); ]);
assert!(match engine.verify_block_family(&header, &parent_header) { 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, if s.contains("invalid step") => true,
_ => false, _ => false,
}); });
@ -1856,7 +1856,7 @@ mod tests {
]); ]);
assert!(match engine.verify_block_family(&header, &parent_header) { 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, if s.contains("invalid empty step proof") => true,
_ => false, _ => false,
}); });
@ -1871,7 +1871,7 @@ mod tests {
]); ]);
assert!(match engine.verify_block_family(&header, &parent_header) { 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, if s.contains("invalid empty step proof") => true,
_ => false, _ => false,
}); });

View File

@ -37,7 +37,7 @@ pub use self::tendermint::Tendermint;
use std::sync::{Weak, Arc}; use std::sync::{Weak, Arc};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::fmt; use std::{fmt, error};
use self::epoch::PendingTransition; 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. /// Seal type.
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum Seal { pub enum Seal {

View File

@ -768,7 +768,7 @@ mod tests {
use ethereum_types::Address; use ethereum_types::Address;
use bytes::Bytes; use bytes::Bytes;
use block::*; use block::*;
use error::{Error, BlockError}; use error::{Error, ErrorKind, BlockError};
use header::Header; use header::Header;
use client::ChainInfo; use client::ChainInfo;
use miner::MinerService; use miner::MinerService;
@ -855,7 +855,7 @@ mod tests {
let verify_result = engine.verify_block_basic(&header); let verify_result = engine.verify_block_basic(&header);
match verify_result { 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); }, Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -885,7 +885,7 @@ mod tests {
header.set_seal(seal); header.set_seal(seal);
// Bad proposer. // Bad proposer.
match engine.verify_block_external(&header) { match engine.verify_block_external(&header) {
Err(Error::Engine(EngineError::NotProposer(_))) => {}, Err(Error(ErrorKind::Engine(EngineError::NotProposer(_)), _)) => {},
_ => panic!(), _ => panic!(),
} }
@ -895,7 +895,7 @@ mod tests {
header.set_seal(seal); header.set_seal(seal);
// Not authority. // Not authority.
match engine.verify_block_external(&header) { match engine.verify_block_external(&header) {
Err(Error::Engine(EngineError::NotAuthorized(_))) => {}, Err(Error(ErrorKind::Engine(EngineError::NotAuthorized(_)), _)) => {},
_ => panic!(), _ => panic!(),
}; };
engine.stop(); engine.stop();
@ -925,7 +925,7 @@ mod tests {
// One good signature is not enough. // One good signature is not enough.
match engine.verify_block_external(&header) { match engine.verify_block_external(&header) {
Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {}, Err(Error(ErrorKind::Engine(EngineError::BadSealFieldSize(_)), _)) => {},
_ => panic!(), _ => panic!(),
} }
@ -945,7 +945,7 @@ mod tests {
// One good and one bad signature. // One good and one bad signature.
match engine.verify_block_external(&header) { match engine.verify_block_external(&header) {
Err(Error::Engine(EngineError::NotAuthorized(_))) => {}, Err(Error(ErrorKind::Engine(EngineError::NotAuthorized(_)), _)) => {},
_ => panic!(), _ => panic!(),
}; };
engine.stop(); engine.stop();
@ -1092,7 +1092,7 @@ mod tests {
} else if *s == signature0 { } else if *s == signature0 {
Ok(voter) Ok(voter)
} else { } else {
Err(Error::Ethkey(EthkeyError::InvalidSignature)) Err(ErrorKind::Ethkey(EthkeyError::InvalidSignature).into())
} }
} }
}, },
@ -1100,7 +1100,7 @@ mod tests {
// One good signature is not enough. // One good signature is not enough.
match epoch_verifier.verify_light(&header) { match epoch_verifier.verify_light(&header) {
Err(Error::Engine(EngineError::BadSealFieldSize(_))) => {}, Err(Error(ErrorKind::Engine(EngineError::BadSealFieldSize(_)), _)) => {},
_ => panic!(), _ => panic!(),
} }
@ -1117,7 +1117,7 @@ mod tests {
// One good and one bad signature. // One good and one bad signature.
match epoch_verifier.verify_light(&header) { match epoch_verifier.verify_light(&header) {
Err(Error::Ethkey(EthkeyError::InvalidSignature)) => {}, Err(Error(ErrorKind::Ethkey(EthkeyError::InvalidSignature), _)) => {},
_ => panic!(), _ => panic!(),
}; };

View File

@ -20,7 +20,7 @@ use std::{fmt, error};
use std::time::SystemTime; use std::time::SystemTime;
use kvdb; use kvdb;
use ethereum_types::{H256, U256, Address, Bloom}; use ethereum_types::{H256, U256, Address, Bloom};
use util_error::UtilError; use util_error::{self, UtilError};
use snappy::InvalidInput; use snappy::InvalidInput;
use unexpected::{Mismatch, OutOfBounds}; use unexpected::{Mismatch, OutOfBounds};
use trie::TrieError; use trie::TrieError;
@ -147,45 +147,66 @@ impl fmt::Display for BlockError {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq)] impl error::Error for BlockError {
/// Import to the block queue result fn description(&self) -> &str {
pub enum ImportError { "Block error"
/// 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 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",
};
f.write_fmt(format_args!("Block import error ({})", msg))
} }
} }
/// Error dedicated to import block function
#[derive(Debug)] error_chain! {
pub enum BlockImportError { types {
/// Import error ImportError, ImportErrorKind, ImportErrorResultExt, ImportErrorResult;
Import(ImportError), }
/// Block error
Block(BlockError), errors {
/// Other error #[doc = "Already in the block chain."]
Other(String), 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")
}
#[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_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<Error> for BlockImportError { impl From<Error> for BlockImportError {
fn from(e: Error) -> Self { fn from(e: Error) -> Self {
match e { match e {
Error::Block(block_error) => BlockImportError::Block(block_error), Error(ErrorKind::Block(block_error), _) => BlockImportErrorKind::Block(block_error).into(),
Error::Import(import_error) => BlockImportError::Import(import_error), Error(ErrorKind::Import(import_error), _) => BlockImportErrorKind::Import(import_error.into()).into(),
_ => BlockImportError::Other(format!("other block import error: {:?}", e)), _ => BlockImportErrorKind::Other(format!("other block import error: {:?}", e)).into(),
} }
} }
} }
@ -202,203 +223,121 @@ pub enum TransactionImportError {
impl From<Error> for TransactionImportError { impl From<Error> for TransactionImportError {
fn from(e: Error) -> Self { fn from(e: Error) -> Self {
match e { match e {
Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error), Error(ErrorKind::Transaction(transaction_error), _) => TransactionImportError::Transaction(transaction_error),
_ => TransactionImportError::Other(format!("other block import error: {:?}", e)), _ => TransactionImportError::Other(format!("other block import error: {:?}", e)),
} }
} }
} }
#[derive(Debug)] error_chain! {
/// General error type which should be capable of representing all errors in ethcore. types {
pub enum Error { Error, ErrorKind, ErrorResultExt, EthcoreResult;
/// 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),
}
impl fmt::Display for Error { links {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { Database(kvdb::Error, kvdb::ErrorKind) #[doc = "Database error."];
match *self { Util(UtilError, util_error::ErrorKind) #[doc = "Error concerning a utility"];
Error::Client(ref err) => err.fmt(f), Import(ImportError, ImportErrorKind) #[doc = "Error concerning block import." ];
Error::Database(ref err) => err.fmt(f), }
Error::Util(ref err) => err.fmt(f),
Error::Io(ref err) => err.fmt(f), foreign_links {
Error::Block(ref err) => err.fmt(f), Io(IoError) #[doc = "Io create error"];
Error::Execution(ref err) => err.fmt(f), StdIo(::std::io::Error) #[doc = "Error concerning the Rust standard library's IO subsystem."];
Error::Transaction(ref err) => err.fmt(f), Trie(TrieError) #[doc = "Error concerning TrieDBs."];
Error::Import(ref err) => err.fmt(f), Execution(ExecutionError) #[doc = "Error concerning EVM code execution."];
Error::UnknownEngineName(ref name) => Block(BlockError) #[doc = "Error concerning block processing."];
f.write_fmt(format_args!("Unknown engine name ({})", name)), Transaction(TransactionError) #[doc = "Error concerning transaction processing."];
Error::PowHashInvalid => f.write_str("Invalid or out of date PoW hash."), Snappy(InvalidInput) #[doc = "Snappy error."];
Error::PowInvalid => f.write_str("Invalid nonce or mishash"), Engine(EngineError) #[doc = "Consensus vote error."];
Error::Trie(ref err) => err.fmt(f), Ethkey(EthkeyError) #[doc = "Ethkey error."];
Error::StdIo(ref err) => err.fmt(f), }
Error::Snappy(ref err) => err.fmt(f),
Error::Snapshot(ref err) => err.fmt(f), errors {
Error::Engine(ref err) => err.fmt(f), #[doc = "Client configuration error."]
Error::Ethkey(ref err) => err.fmt(f), Client(err: ClientError) {
Error::AccountProvider(ref err) => err.fmt(f), description("Client configuration error.")
display("Client configuration error {}", err)
}
#[doc = "Snapshot error."]
Snapshot(err: SnapshotError) {
description("Snapshot error.")
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.")
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.")
}
#[doc = "Unknown engine given"]
UnknownEngineName(name: String) {
description("Unknown engine name")
display("Unknown engine name ({})", name)
} }
} }
} }
impl error::Error for Error {
fn description(&self) -> &str {
// improve description
"ethcore error"
}
}
/// Result of import block operation. /// Result of import block operation.
pub type ImportResult = Result<H256, Error>; pub type ImportResult = EthcoreResult<H256>;
impl From<ClientError> for Error { impl From<ClientError> for Error {
fn from(err: ClientError) -> Error { fn from(err: ClientError) -> Error {
match err { match err {
ClientError::Trie(err) => Error::Trie(err), ClientError::Trie(err) => ErrorKind::Trie(err).into(),
_ => Error::Client(err) _ => ErrorKind::Client(err).into()
} }
} }
} }
impl From<kvdb::Error> for Error { impl From<AccountsError> for Error {
fn from(err: kvdb::Error) -> Error { fn from(err: AccountsError) -> Error {
Error::Database(err) ErrorKind::AccountProvider(err).into()
} }
} }
impl From<TransactionError> for Error {
fn from(err: TransactionError) -> Error {
Error::Transaction(err)
}
}
impl From<ImportError> for Error {
fn from(err: ImportError) -> Error {
Error::Import(err)
}
}
impl From<BlockError> for Error {
fn from(err: BlockError) -> Error {
Error::Block(err)
}
}
impl From<ExecutionError> for Error {
fn from(err: ExecutionError) -> Error {
Error::Execution(err)
}
}
impl From<::rlp::DecoderError> for Error { impl From<::rlp::DecoderError> for Error {
fn from(err: ::rlp::DecoderError) -> Error { fn from(err: ::rlp::DecoderError) -> Error {
Error::Util(UtilError::from(err)) UtilError::from(err).into()
}
}
impl From<UtilError> for Error {
fn from(err: UtilError) -> Error {
Error::Util(err)
}
}
impl From<IoError> for Error {
fn from(err: IoError) -> Error {
Error::Io(err)
}
}
impl From<TrieError> 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<BlockImportError> for Error { impl From<BlockImportError> for Error {
fn from(err: BlockImportError) -> Error { fn from(err: BlockImportError) -> Error {
match err { match err {
BlockImportError::Block(e) => Error::Block(e), BlockImportError(BlockImportErrorKind::Block(e), _) => ErrorKind::Block(e).into(),
BlockImportError::Import(e) => Error::Import(e), BlockImportError(BlockImportErrorKind::Import(e), _) => ErrorKind::Import(e).into(),
BlockImportError::Other(s) => Error::Util(UtilError::from(s)), BlockImportError(BlockImportErrorKind::Other(s), _) => UtilError::from(s).into(),
_ => ErrorKind::Msg(format!("other block import error: {:?}", err)).into(),
} }
} }
} }
impl From<::snappy::InvalidInput> for Error {
fn from(err: ::snappy::InvalidInput) -> Error {
Error::Snappy(err)
}
}
impl From<SnapshotError> for Error { impl From<SnapshotError> for Error {
fn from(err: SnapshotError) -> Error { fn from(err: SnapshotError) -> Error {
match err { match err {
SnapshotError::Io(err) => Error::StdIo(err), SnapshotError::Io(err) => ErrorKind::StdIo(err).into(),
SnapshotError::Trie(err) => Error::Trie(err), SnapshotError::Trie(err) => ErrorKind::Trie(err).into(),
SnapshotError::Decoder(err) => err.into(), SnapshotError::Decoder(err) => err.into(),
other => Error::Snapshot(other), other => ErrorKind::Snapshot(other).into(),
} }
} }
} }
impl From<EngineError> for Error {
fn from(err: EngineError) -> Error {
Error::Engine(err)
}
}
impl From<EthkeyError> for Error {
fn from(err: EthkeyError) -> Error {
Error::Ethkey(err)
}
}
impl From<AccountsError> for Error {
fn from(err: AccountsError) -> Error {
Error::AccountProvider(err)
}
}
impl<E> From<Box<E>> for Error where Error: From<E> { impl<E> From<Box<E>> for Error where Error: From<E> {
fn from(err: Box<E>) -> Error { fn from(err: Box<E>) -> Error {
Error::from(*err) Error::from(*err)

View File

@ -488,7 +488,7 @@ mod tests {
use ethereum_types::{H64, H256, U256, Address}; use ethereum_types::{H64, H256, U256, Address};
use block::*; use block::*;
use test_helpers::get_temp_state_db; use test_helpers::get_temp_state_db;
use error::{BlockError, Error}; use error::{BlockError, Error, ErrorKind};
use header::Header; use header::Header;
use spec::Spec; use spec::Spec;
use engines::Engine; use engines::Engine;
@ -640,7 +640,7 @@ mod tests {
let verify_result = engine.verify_block_basic(&header); let verify_result = engine.verify_block_basic(&header);
match verify_result { 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); }, Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -655,7 +655,7 @@ mod tests {
let verify_result = engine.verify_block_basic(&header); let verify_result = engine.verify_block_basic(&header);
match verify_result { match verify_result {
Err(Error::Block(BlockError::DifficultyOutOfBounds(_))) => {}, Err(Error(ErrorKind::Block(BlockError::DifficultyOutOfBounds(_)), _)) => {},
Err(_) => { panic!("should be block difficulty error (got {:?})", verify_result); }, Err(_) => { panic!("should be block difficulty error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -671,7 +671,7 @@ mod tests {
let verify_result = engine.verify_block_basic(&header); let verify_result = engine.verify_block_basic(&header);
match verify_result { 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); }, Err(_) => { panic!("should be invalid proof of work error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -685,7 +685,7 @@ mod tests {
let verify_result = engine.verify_block_unordered(&header); let verify_result = engine.verify_block_unordered(&header);
match verify_result { 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); }, Err(_) => { panic!("should be block seal-arity mismatch error (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -710,7 +710,7 @@ mod tests {
let verify_result = engine.verify_block_unordered(&header); let verify_result = engine.verify_block_unordered(&header);
match verify_result { 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); }, Err(_) => { panic!("should be invalid 256-bit seal fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -726,7 +726,7 @@ mod tests {
let verify_result = engine.verify_block_unordered(&header); let verify_result = engine.verify_block_unordered(&header);
match verify_result { 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); }, Err(_) => { panic!("should be invalid proof-of-work fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -741,7 +741,7 @@ mod tests {
let verify_result = engine.verify_block_family(&header, &parent_header); let verify_result = engine.verify_block_family(&header, &parent_header);
match verify_result { 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); }, Err(_) => { panic!("should be invalid block number fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }
@ -758,7 +758,7 @@ mod tests {
let verify_result = engine.verify_block_family(&header, &parent_header); let verify_result = engine.verify_block_family(&header, &parent_header);
match verify_result { match verify_result {
Err(Error::Block(BlockError::InvalidDifficulty(_))) => {}, Err(Error(ErrorKind::Block(BlockError::InvalidDifficulty(_)), _)) => {},
Err(_) => { panic!("should be invalid difficulty fail (got {:?})", verify_result); }, Err(_) => { panic!("should be invalid difficulty fail (got {:?})", verify_result); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }

View File

@ -24,7 +24,7 @@ use trace::{VMTrace, FlatTrace};
use log_entry::LogEntry; use log_entry::LogEntry;
use state_diff::StateDiff; use state_diff::StateDiff;
use std::fmt; use std::{fmt, error};
/// Transaction execution receipt. /// Transaction execution receipt.
#[derive(Debug, PartialEq, Clone)] #[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. /// Result of executing the transaction.
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub enum CallError { pub enum CallError {

View File

@ -54,6 +54,10 @@
//! cargo build --release //! cargo build --release
//! ``` //! ```
// Recursion limit required because of
// error_chain foreign_links.
#![recursion_limit="128"]
extern crate bloomchain; extern crate bloomchain;
extern crate bn; extern crate bn;
extern crate byteorder; extern crate byteorder;
@ -112,6 +116,8 @@ extern crate ethabi_derive;
#[macro_use] #[macro_use]
extern crate ethabi_contract; extern crate ethabi_contract;
#[macro_use] #[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log; extern crate log;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;

View File

@ -21,7 +21,7 @@ use std::sync::Arc;
use ansi_term::Colour; use ansi_term::Colour;
use bytes::Bytes; use bytes::Bytes;
use engines::{EthEngine, Seal}; use engines::{EthEngine, Seal};
use error::{Error, ExecutionError}; use error::{Error, ErrorKind, ExecutionError};
use ethcore_miner::gas_pricer::GasPricer; use ethcore_miner::gas_pricer::GasPricer;
use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy}; use ethcore_miner::pool::{self, TransactionQueue, VerifiedTransaction, QueueStatus, PrioritizationStrategy};
use ethcore_miner::work_notify::NotifyWork; use ethcore_miner::work_notify::NotifyWork;
@ -393,7 +393,7 @@ impl Miner {
// Re-verify transaction again vs current state. // Re-verify transaction again vs current state.
let result = client.verify_signed(&transaction) let result = client.verify_signed(&transaction)
.map_err(Error::Transaction) .map_err(|e| e.into())
.and_then(|_| { .and_then(|_| {
open_block.push_transaction(transaction, None) open_block.push_transaction(transaction, None)
}); });
@ -411,7 +411,7 @@ impl Miner {
debug!(target: "miner", "Adding tx {:?} took {} ms", hash, took_ms(&took)); debug!(target: "miner", "Adding tx {:?} took {} ms", hash, took_ms(&took));
match result { 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); 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 // Penalize transaction if it's above current gas limit
@ -436,12 +436,12 @@ impl Miner {
}, },
// Invalid nonce error can happen only if previous transaction is skipped because of gas limit. // 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. // 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); debug!(target: "miner", "Skipping adding transaction to block because of invalid nonce: {:?} (expected: {:?}, got: {:?})", hash, expected, got);
}, },
// already have transaction - ignore // already have transaction - ignore
Err(Error::Transaction(transaction::Error::AlreadyImported)) => {}, Err(Error(ErrorKind::Transaction(transaction::Error::AlreadyImported), _)) => {},
Err(Error::Transaction(transaction::Error::NotAllowed)) => { Err(Error(ErrorKind::Transaction(transaction::Error::NotAllowed), _)) => {
not_allowed_transactions.insert(hash); not_allowed_transactions.insert(hash);
debug!(target: "miner", "Skipping non-allowed transaction for sender {:?}", hash); debug!(target: "miner", "Skipping non-allowed transaction for sender {:?}", hash);
}, },
@ -981,11 +981,11 @@ impl miner::MinerService for Miner {
trace!(target: "miner", "Submitted block {}={}={} with seal {:?}", block_hash, b.hash(), b.header().bare_hash(), seal); 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, _)| { b.lock().try_seal(&*self.engine, seal).or_else(|(e, _)| {
warn!(target: "miner", "Mined solution rejected: {}", e); warn!(target: "miner", "Mined solution rejected: {}", e);
Err(Error::PowInvalid) Err(ErrorKind::PowInvalid.into())
}) })
} else { } else {
warn!(target: "miner", "Submitted solution rejected: Block unknown or out of date."); warn!(target: "miner", "Submitted solution rejected: Block unknown or out of date.");
Err(Error::PowHashInvalid) Err(ErrorKind::PowHashInvalid.into())
}; };
result.and_then(|sealed| { result.and_then(|sealed| {

View File

@ -19,7 +19,7 @@
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use tempdir::TempDir; use tempdir::TempDir;
use error::Error; use error::{Error, ErrorKind};
use blockchain::generator::{BlockGenerator, BlockBuilder}; use blockchain::generator::{BlockGenerator, BlockBuilder};
use blockchain::BlockChain; use blockchain::BlockChain;
@ -141,7 +141,7 @@ fn checks_flag() {
let mut rebuilder = SNAPSHOT_MODE.rebuilder(chain, db.clone(), &manifest).unwrap(); let mut rebuilder = SNAPSHOT_MODE.rebuilder(chain, db.clone(), &manifest).unwrap();
match rebuilder.feed(&chunk, engine.as_ref(), &AtomicBool::new(false)) { 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") _ => panic!("Wrong result on abort flag set")
} }
} }

View File

@ -26,7 +26,7 @@ use snapshot::{chunk_state, Error as SnapshotError, Progress, StateRebuilder};
use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter};
use super::helpers::{compare_dbs, StateProducer}; use super::helpers::{compare_dbs, StateProducer};
use error::Error; use error::{Error, ErrorKind};
use rand::{XorShiftRng, SeedableRng}; use rand::{XorShiftRng, SeedableRng};
use ethereum_types::H256; use ethereum_types::H256;
@ -189,7 +189,7 @@ fn checks_flag() {
let chunk = ::snappy::decompress(&raw).unwrap(); let chunk = ::snappy::decompress(&raw).unwrap();
match rebuilder.feed(&chunk, &flag) { match rebuilder.feed(&chunk, &flag) {
Err(Error::Snapshot(SnapshotError::RestorationAborted)) => {}, Err(Error(ErrorKind::Snapshot(SnapshotError::RestorationAborted), _)) => {},
_ => panic!("unexpected result when feeding with flag off"), _ => panic!("unexpected result when feeding with flag off"),
} }
} }

View File

@ -69,7 +69,7 @@ pub mod blocks {
use super::{Kind, BlockLike}; use super::{Kind, BlockLike};
use engines::EthEngine; use engines::EthEngine;
use error::{Error, BlockError}; use error::{Error, ErrorKind, BlockError};
use header::Header; use header::Header;
use verification::{PreverifiedBlock, verify_block_basic, verify_block_unordered}; use verification::{PreverifiedBlock, verify_block_basic, verify_block_unordered};
@ -88,7 +88,7 @@ pub mod blocks {
fn create(input: Self::Input, engine: &EthEngine) -> Result<Self::Unverified, Error> { fn create(input: Self::Input, engine: &EthEngine) -> Result<Self::Unverified, Error> {
match verify_block_basic(&input.header, &input.bytes, engine) { match verify_block_basic(&input.header, &input.bytes, engine) {
Ok(()) => Ok(input), 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); debug!(target: "client", "Block received too early {}: {:?}", input.hash(), oob);
Err(BlockError::TemporarilyInvalid(oob).into()) Err(BlockError::TemporarilyInvalid(oob).into())
}, },

View File

@ -472,17 +472,17 @@ impl<K: Kind> VerificationQueue<K> {
let h = input.hash(); let h = input.hash();
{ {
if self.processing.read().contains_key(&h) { if self.processing.read().contains_key(&h) {
return Err(ImportError::AlreadyQueued.into()); bail!(ErrorKind::Import(ImportErrorKind::AlreadyQueued));
} }
let mut bad = self.verification.bad.lock(); let mut bad = self.verification.bad.lock();
if bad.contains(&h) { if bad.contains(&h) {
return Err(ImportError::KnownBad.into()); bail!(ErrorKind::Import(ImportErrorKind::KnownBad));
} }
if bad.contains(&input.parent_hash()) { if bad.contains(&input.parent_hash()) {
bad.insert(h.clone()); bad.insert(h.clone());
return Err(ImportError::KnownBad.into()); bail!(ErrorKind::Import(ImportErrorKind::KnownBad));
} }
} }
@ -502,7 +502,7 @@ impl<K: Kind> VerificationQueue<K> {
Err(err) => { Err(err) => {
match err { match err {
// Don't mark future blocks as bad. // Don't mark future blocks as bad.
Error::Block(BlockError::TemporarilyInvalid(_)) => {}, Error(ErrorKind::Block(BlockError::TemporarilyInvalid(_)), _) => {},
_ => { _ => {
self.verification.bad.lock().insert(h.clone()); self.verification.bad.lock().insert(h.clone());
} }
@ -773,7 +773,7 @@ mod tests {
match duplicate_import { match duplicate_import {
Err(e) => { Err(e) => {
match e { match e {
Error::Import(ImportError::AlreadyQueued) => {}, Error(ErrorKind::Import(ImportErrorKind::AlreadyQueued), _) => {},
_ => { panic!("must return AlreadyQueued error"); } _ => { panic!("must return AlreadyQueued error"); }
} }
} }

View File

@ -358,6 +358,7 @@ mod tests {
use hash::keccak; use hash::keccak;
use engines::EthEngine; use engines::EthEngine;
use error::BlockError::*; use error::BlockError::*;
use error::ErrorKind;
use ethkey::{Random, Generator}; use ethkey::{Random, Generator};
use spec::{CommonParams, Spec}; use spec::{CommonParams, Spec};
use test_helpers::{create_test_block_with_data, create_test_block}; use test_helpers::{create_test_block_with_data, create_test_block};
@ -372,7 +373,7 @@ mod tests {
fn check_fail(result: Result<(), Error>, e: BlockError) { fn check_fail(result: Result<(), Error>, e: BlockError) {
match result { 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), Err(other) => panic!("Block verification failed.\nExpected: {:?}\nGot: {:?}", e, other),
Ok(_) => panic!("Block verification failed.\nExpected: {:?}\nGot: Ok", e), Ok(_) => panic!("Block verification failed.\nExpected: {:?}\nGot: Ok", e),
} }
@ -381,8 +382,8 @@ mod tests {
fn check_fail_timestamp(result: Result<(), Error>, temp: bool) { fn check_fail_timestamp(result: Result<(), Error>, temp: bool) {
let name = if temp { "TemporarilyInvalid" } else { "InvalidTimestamp" }; let name = if temp { "TemporarilyInvalid" } else { "InvalidTimestamp" };
match result { match result {
Err(Error::Block(BlockError::InvalidTimestamp(_))) if !temp => (), Err(Error(ErrorKind::Block(BlockError::InvalidTimestamp(_)), _)) if !temp => (),
Err(Error::Block(BlockError::TemporarilyInvalid(_))) if temp => (), Err(Error(ErrorKind::Block(BlockError::TemporarilyInvalid(_)), _)) if temp => (),
Err(other) => panic!("Block verification failed.\nExpected: {}\nGot: {:?}", name, other), Err(other) => panic!("Block verification failed.\nExpected: {}\nGot: {:?}", name, other),
Ok(_) => panic!("Block verification failed.\nExpected: {}\nGot: Ok", name), Ok(_) => panic!("Block verification failed.\nExpected: {}\nGot: Ok", name),
} }
@ -716,7 +717,7 @@ mod tests {
header.set_gas_limit(0.into()); header.set_gas_limit(0.into());
header.set_difficulty("0000000000000000000000000000000000000000000000000000000000020000".parse::<U256>().unwrap()); header.set_difficulty("0000000000000000000000000000000000000000000000000000000000020000".parse::<U256>().unwrap());
match family_test(&create_test_block(&header), engine, &bc) { 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"); }, Err(_) => { panic!("should be invalid difficulty fail"); },
_ => { panic!("Should be error, got Ok"); }, _ => { panic!("Should be error, got Ok"); },
} }

View File

@ -25,9 +25,9 @@ use ethereum_types::H256;
use rlp::Rlp; use rlp::Rlp;
use ethcore::views::BlockView; use ethcore::views::BlockView;
use ethcore::header::{BlockNumber, Header as BlockHeader}; 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::block::Block;
use ethcore::error::{ImportError, BlockError}; use ethcore::error::{ImportErrorKind, BlockError};
use sync_io::SyncIo; use sync_io::SyncIo;
use blocks::BlockCollection; use blocks::BlockCollection;
@ -502,11 +502,11 @@ impl BlockDownloader {
}; };
match result { match result {
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => {
trace!(target: "sync", "Block already in chain {:?}", h); trace!(target: "sync", "Block already in chain {:?}", h);
self.block_imported(&h, number, &parent); self.block_imported(&h, number, &parent);
}, },
Err(BlockImportError::Import(ImportError::AlreadyQueued)) => { Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyQueued), _)) => {
trace!(target: "sync", "Block already queued {:?}", h); trace!(target: "sync", "Block already queued {:?}", h);
self.block_imported(&h, number, &parent); self.block_imported(&h, number, &parent);
}, },
@ -515,14 +515,14 @@ impl BlockDownloader {
imported.insert(h.clone()); imported.insert(h.clone());
self.block_imported(&h, number, &parent); 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; break;
}, },
Err(BlockImportError::Block(BlockError::UnknownParent(_))) => { Err(BlockImportError(BlockImportErrorKind::Block(BlockError::UnknownParent(_)), _)) => {
trace!(target: "sync", "Unknown new block parent, restarting sync"); trace!(target: "sync", "Unknown new block parent, restarting sync");
break; break;
}, },
Err(BlockImportError::Block(BlockError::TemporarilyInvalid(_))) => { Err(BlockImportError(BlockImportErrorKind::Block(BlockError::TemporarilyInvalid(_)), _)) => {
debug!(target: "sync", "Block temporarily invalid, restarting sync"); debug!(target: "sync", "Block temporarily invalid, restarting sync");
break; break;
}, },

View File

@ -101,7 +101,7 @@ use bytes::Bytes;
use rlp::{Rlp, RlpStream, DecoderError, Encodable}; use rlp::{Rlp, RlpStream, DecoderError, Encodable};
use network::{self, PeerId, PacketId}; use network::{self, PeerId, PacketId};
use ethcore::header::{BlockNumber, Header as BlockHeader}; 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::error::*;
use ethcore::snapshot::{ManifestData, RestorationStatus}; use ethcore::snapshot::{ManifestData, RestorationStatus};
use transaction::SignedTransaction; use transaction::SignedTransaction;
@ -943,10 +943,10 @@ impl ChainSync {
return Ok(()); return Ok(());
} }
match io.chain().import_block(block_rlp.as_raw().to_vec()) { 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); 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); trace!(target: "sync", "New block already queued {:?}", h);
}, },
Ok(_) => { Ok(_) => {
@ -955,7 +955,7 @@ impl ChainSync {
self.new_blocks.mark_as_known(&header.hash(), header.number()); self.new_blocks.mark_as_known(&header.hash(), header.number());
trace!(target: "sync", "New block queued {:?} ({})", h, 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; unknown = true;
trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h); trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h);
}, },

View File

@ -427,7 +427,7 @@ impl<L: AsLightClient> LightSync<L> {
// handles request dispatch, block import, state machine transitions, and timeouts. // handles request dispatch, block import, state machine transitions, and timeouts.
fn maintain_sync(&self, ctx: &BasicContext) { fn maintain_sync(&self, ctx: &BasicContext) {
use ethcore::error::{BlockImportError, ImportError}; use ethcore::error::{BlockImportError, BlockImportErrorKind, ImportErrorKind};
const DRAIN_AMOUNT: usize = 128; const DRAIN_AMOUNT: usize = 128;
@ -457,10 +457,10 @@ impl<L: AsLightClient> LightSync<L> {
for header in sink.drain(..) { for header in sink.drain(..) {
match client.queue_header(header) { match client.queue_header(header) {
Ok(_) => {} Ok(_) => {}
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => {
trace!(target: "sync", "Block already in chain. Continuing."); 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."); trace!(target: "sync", "Block already queued. Continuing.");
}, },
Err(e) => { Err(e) => {

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::fmt; use std::{fmt, error};
use ethereum_types::U256; use ethereum_types::U256;
use ethkey; use ethkey;
@ -112,3 +112,9 @@ impl fmt::Display for Error {
} }
} }
impl error::Error for Error {
fn description(&self) -> &str {
"Transaction error"
}
}

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::fmt; use std::{fmt, error};
#[derive(Debug)] #[derive(Debug)]
/// Crypto error /// Crypto error
@ -51,6 +51,12 @@ impl fmt::Display for Error {
} }
} }
impl error::Error for Error {
fn description(&self) -> &str {
"Crypto error"
}
}
impl Into<String> for Error { impl Into<String> for Error {
fn into(self) -> String { fn into(self) -> String {
format!("{}", self) format!("{}", self)

View File

@ -27,7 +27,7 @@ use bytes::ToPretty;
use rlp::PayloadInfo; use rlp::PayloadInfo;
use ethcore::account_provider::AccountProvider; 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, Nonce, Balance, BlockChainClient, BlockId, BlockInfo, ImportBlock};
use ethcore::error::ImportError; use ethcore::error::{ImportErrorKind, BlockImportErrorKind};
use ethcore::miner::Miner; use ethcore::miner::Miner;
use ethcore::verification::queue::VerifierSettings; use ethcore::verification::queue::VerifierSettings;
use ethcore_service::ClientService; use ethcore_service::ClientService;
@ -257,7 +257,7 @@ fn execute_import_light(cmd: ImportBlockchain) -> Result<(), String> {
} }
match client.import_header(header) { match client.import_header(header) {
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => {
trace!("Skipping block already in chain."); trace!("Skipping block already in chain.");
} }
Err(e) => { Err(e) => {
@ -428,7 +428,7 @@ fn execute_import(cmd: ImportBlockchain) -> Result<(), String> {
let do_import = |bytes| { let do_import = |bytes| {
while client.queue_info().is_full() { sleep(Duration::from_secs(1)); } while client.queue_info().is_full() { sleep(Duration::from_secs(1)); }
match client.import_block(bytes) { match client.import_block(bytes) {
Err(BlockImportError::Import(ImportError::AlreadyInChain)) => { Err(BlockImportError(BlockImportErrorKind::Import(ImportErrorKind::AlreadyInChain), _)) => {
trace!("Skipping block already in chain."); trace!("Skipping block already in chain.");
} }
Err(e) => { Err(e) => {

View File

@ -19,7 +19,7 @@
use std::fmt; use std::fmt;
use ethcore::account_provider::{SignError as AccountError}; 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 jsonrpc_core::{futures, Error, ErrorCode, Value};
use rlp::DecoderError; use rlp::DecoderError;
use transaction::Error as TransactionError; 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::*; use self::TransactionError::*;
match error { match *error {
AlreadyImported => "Transaction with the same hash was already imported.".into(), AlreadyImported => "Transaction with the same hash was already imported.".into(),
Old => "Transaction nonce is too low. Try incrementing the nonce.".into(), Old => "Transaction nonce is too low. Try incrementing the nonce.".into(),
TooCheapToReplace => { TooCheapToReplace => {
@ -330,7 +330,7 @@ pub fn transaction_message(error: TransactionError) -> String {
GasLimitExceeded { limit, got } => { GasLimitExceeded { limit, got } => {
format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", 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(), InvalidChainId => "Invalid chain id.".into(),
InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(), InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(),
SenderBanned => "Sender is banned in local queue.".into(), SenderBanned => "Sender is banned in local queue.".into(),
@ -342,7 +342,7 @@ pub fn transaction_message(error: TransactionError) -> String {
pub fn transaction<T: Into<EthcoreError>>(error: T) -> Error { pub fn transaction<T: Into<EthcoreError>>(error: T) -> Error {
let error = error.into(); let error = error.into();
if let EthcoreError::Transaction(e) = error { if let ErrorKind::Transaction(ref e) = *error.kind() {
Error { Error {
code: ErrorCode::ServerError(codes::TRANSACTION_ERROR), code: ErrorCode::ServerError(codes::TRANSACTION_ERROR),
message: transaction_message(e), message: transaction_message(e),