2019-01-07 11:33:07 +01:00
|
|
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
|
|
|
// This file is part of Parity Ethereum.
|
2016-02-05 13:40:41 +01:00
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
2016-02-05 13:40:41 +01:00
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
2016-02-05 13:40:41 +01:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
2019-01-07 11:33:07 +01:00
|
|
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
2016-02-05 13:40:41 +01:00
|
|
|
|
2016-01-10 14:05:39 +01:00
|
|
|
//! General error types for use in ethcore.
|
|
|
|
|
2018-04-09 16:14:33 +02:00
|
|
|
use std::{fmt, error};
|
2018-04-14 21:35:58 +02:00
|
|
|
use std::time::SystemTime;
|
2019-01-04 14:05:46 +01:00
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
use derive_more::{Display, From};
|
2018-01-14 22:43:28 +01:00
|
|
|
use ethereum_types::{H256, U256, Address, Bloom};
|
2019-01-04 14:05:46 +01:00
|
|
|
use ethkey::Error as EthkeyError;
|
2018-07-02 18:50:05 +02:00
|
|
|
use ethtrie::TrieError;
|
2019-01-04 14:05:46 +01:00
|
|
|
use rlp;
|
|
|
|
use snappy::InvalidInput;
|
2016-08-05 17:00:46 +02:00
|
|
|
use snapshot::Error as SnapshotError;
|
2019-01-04 14:05:46 +01:00
|
|
|
use types::BlockNumber;
|
2019-02-07 14:34:24 +01:00
|
|
|
use types::transaction::Error as TransactionError;
|
2019-01-04 14:05:46 +01:00
|
|
|
use unexpected::{Mismatch, OutOfBounds};
|
|
|
|
|
|
|
|
use engines::EngineError;
|
2016-08-05 17:00:46 +02:00
|
|
|
|
2017-07-12 13:09:17 +02:00
|
|
|
pub use executed::{ExecutionError, CallError};
|
2016-01-11 17:37:22 +01:00
|
|
|
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Errors concerning block processing.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[derive(Debug, Display, PartialEq, Clone, Eq)]
|
2016-01-10 14:05:39 +01:00
|
|
|
pub enum BlockError {
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Block has too many uncles.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Block has too many uncles. {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
TooManyUncles(OutOfBounds<usize>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Extra data is of an invalid length.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Extra block data too long. {}", _0)]
|
2016-01-10 14:05:39 +01:00
|
|
|
ExtraDataOutOfBounds(OutOfBounds<usize>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Seal is incorrect format.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Block seal in incorrect format: {}", _0)]
|
2016-01-10 14:05:39 +01:00
|
|
|
InvalidSealArity(Mismatch<usize>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Block has too much gas used.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Block has too much gas used. {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
TooMuchGasUsed(OutOfBounds<U256>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Uncles hash in header is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Block has invalid uncles hash: {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
InvalidUnclesHash(Mismatch<H256>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// An uncle is from a generation too old.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Uncle block is too old. {}", _0)]
|
2016-01-11 12:45:35 +01:00
|
|
|
UncleTooOld(OutOfBounds<BlockNumber>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// An uncle is from the same generation as the block.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Uncle from same generation as block. {}", _0)]
|
2016-01-11 12:45:35 +01:00
|
|
|
UncleIsBrother(OutOfBounds<BlockNumber>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// An uncle is already in the chain.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Uncle {} already in chain", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
UncleInChain(H256),
|
2017-07-10 13:36:42 +02:00
|
|
|
/// An uncle is included twice.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Uncle {} already in the header", _0)]
|
2017-07-10 13:36:42 +02:00
|
|
|
DuplicateUncle(H256),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// An uncle has a parent not in the chain.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Uncle {} has a parent not in the chain", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
UncleParentNotInChain(H256),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// State root header field is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid state root in header: {}", _0)]
|
2016-01-14 19:03:48 +01:00
|
|
|
InvalidStateRoot(Mismatch<H256>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Gas used header field is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid gas used in header: {}", _0)]
|
2016-01-14 19:03:48 +01:00
|
|
|
InvalidGasUsed(Mismatch<U256>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Transactions root header field is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid transactions root in header: {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
InvalidTransactionsRoot(Mismatch<H256>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Difficulty is out of range; this can be used as an looser error prior to getting a definitive
|
|
|
|
/// value for difficulty. This error needs only provide bounds of which it is out.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Difficulty out of bounds: {}", _0)]
|
2016-02-03 12:18:12 +01:00
|
|
|
DifficultyOutOfBounds(OutOfBounds<U256>),
|
|
|
|
/// Difficulty header field is invalid; this is a strong error used after getting a definitive
|
|
|
|
/// value for difficulty (which is provided).
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid block difficulty: {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
InvalidDifficulty(Mismatch<U256>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Seal element of type H256 (max_hash for Ethash, but could be something else for
|
|
|
|
/// other seal engines) is out of bounds.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Seal element out of bounds: {}", _0)]
|
2016-02-03 12:18:12 +01:00
|
|
|
MismatchedH256SealElement(Mismatch<H256>),
|
|
|
|
/// Proof-of-work aspect of seal, which we assume is a 256-bit value, is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Block has invalid PoW: {}", _0)]
|
2016-02-03 12:18:12 +01:00
|
|
|
InvalidProofOfWork(OutOfBounds<U256>),
|
2016-05-21 00:13:16 +02:00
|
|
|
/// Some low-level aspect of the seal is incorrect.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Block has invalid seal.")]
|
2016-05-03 17:23:53 +02:00
|
|
|
InvalidSeal,
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Gas limit header field is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid gas limit: {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
InvalidGasLimit(OutOfBounds<U256>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Receipts trie root header field is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid receipts trie root in header: {}", _0)]
|
2016-02-03 12:18:12 +01:00
|
|
|
InvalidReceiptsRoot(Mismatch<H256>),
|
|
|
|
/// Timestamp header field is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid timestamp in header: {}", _0)]
|
|
|
|
InvalidTimestamp(OutOfBoundsTime),
|
2017-12-21 15:01:05 +01:00
|
|
|
/// Timestamp header field is too far in future.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Future timestamp in header: {}", _0)]
|
|
|
|
TemporarilyInvalid(OutOfBoundsTime),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Log bloom header field is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid log bloom in header: {}", _0)]
|
2019-03-06 15:30:35 +01:00
|
|
|
InvalidLogBloom(Box<Mismatch<Bloom>>),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Number field of header is invalid.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Invalid number in header: {}", _0)]
|
2016-01-27 14:09:32 +01:00
|
|
|
InvalidNumber(Mismatch<BlockNumber>),
|
|
|
|
/// Block number isn't sensible.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Implausible block number. {}", _0)]
|
2016-01-27 14:09:32 +01:00
|
|
|
RidiculousNumber(OutOfBounds<BlockNumber>),
|
2019-02-12 15:16:23 +01:00
|
|
|
/// Timestamp header overflowed
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Timestamp overflow")]
|
2019-02-12 15:16:23 +01:00
|
|
|
TimestampOverflow,
|
2017-06-28 09:10:57 +02:00
|
|
|
/// Too many transactions from a particular address.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Too many transactions from: {}", _0)]
|
2017-06-28 09:10:57 +02:00
|
|
|
TooManyTransactions(Address),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Parent given is unknown.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Unknown parent: {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
UnknownParent(H256),
|
2016-02-03 12:18:12 +01:00
|
|
|
/// Uncle parent given is unknown.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Unknown uncle parent: {}", _0)]
|
2016-01-10 19:47:32 +01:00
|
|
|
UnknownUncleParent(H256),
|
2017-05-17 12:41:33 +02:00
|
|
|
/// No transition to epoch number.
|
2019-05-06 15:06:20 +02:00
|
|
|
#[display(fmt = "Unknown transition to epoch number: {}", _0)]
|
2017-05-17 12:41:33 +02:00
|
|
|
UnknownEpochTransition(u64),
|
2016-01-10 14:05:39 +01:00
|
|
|
}
|
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
/// Newtype for Display impl to show seconds
|
|
|
|
#[derive(Debug, Clone, From, PartialEq, Eq)]
|
|
|
|
pub struct OutOfBoundsTime(OutOfBounds<SystemTime>);
|
2016-05-21 00:13:16 +02:00
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
impl fmt::Display for OutOfBoundsTime {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
let seconds = self.0
|
|
|
|
.map(|st| st.elapsed().unwrap_or_default().as_secs());
|
|
|
|
f.write_fmt(format_args!("{}", seconds))
|
2016-05-21 00:13:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-19 11:52:54 +02:00
|
|
|
impl error::Error for BlockError {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
"Block error"
|
|
|
|
}
|
2016-01-10 23:37:09 +01:00
|
|
|
}
|
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
/// Queue error
|
|
|
|
#[derive(Debug, Display, From)]
|
|
|
|
pub enum QueueError {
|
|
|
|
/// Queue is full
|
|
|
|
#[display(fmt = "Queue is full ({})", _0)]
|
|
|
|
Full(usize),
|
|
|
|
/// Io channel error
|
|
|
|
#[display(fmt = "Io channel error: {}", _0)]
|
|
|
|
Channel(::io::IoError)
|
|
|
|
}
|
2018-08-24 10:42:24 +02:00
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
impl error::Error for QueueError {
|
|
|
|
fn source(&self) -> Option<&(error::Error + 'static)> {
|
|
|
|
match self {
|
|
|
|
QueueError::Channel(e) => Some(e),
|
|
|
|
_ => None,
|
2018-08-24 10:42:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
/// Block import Error
|
|
|
|
#[derive(Debug, Display)]
|
|
|
|
pub enum ImportError {
|
|
|
|
/// Already in the block chain.
|
|
|
|
#[display(fmt = "Block already in chain")]
|
|
|
|
AlreadyInChain,
|
|
|
|
/// Already in the block queue
|
|
|
|
#[display(fmt = "block already in the block queue")]
|
|
|
|
AlreadyQueued,
|
|
|
|
/// Already marked as bad from a previous import (could mean parent is bad)
|
|
|
|
#[display(fmt = "block known to be bad")]
|
|
|
|
KnownBad,
|
2016-05-21 00:13:16 +02:00
|
|
|
}
|
2018-04-19 11:52:54 +02:00
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
impl error::Error for ImportError {}
|
|
|
|
|
2017-07-12 13:09:17 +02:00
|
|
|
/// Api-level error for transaction import
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum TransactionImportError {
|
|
|
|
/// Transaction error
|
|
|
|
Transaction(TransactionError),
|
|
|
|
/// Other error
|
|
|
|
Other(String),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Error> for TransactionImportError {
|
|
|
|
fn from(e: Error) -> Self {
|
|
|
|
match e {
|
2019-05-06 15:06:20 +02:00
|
|
|
Error::Transaction(transaction_error) => TransactionImportError::Transaction(transaction_error),
|
2017-07-12 13:09:17 +02:00
|
|
|
_ => TransactionImportError::Other(format!("other block import error: {:?}", e)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-05-21 00:13:16 +02:00
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
/// Ethcore Result
|
|
|
|
pub type EthcoreResult<T> = Result<T, Error>;
|
|
|
|
|
|
|
|
/// Ethcore Error
|
|
|
|
#[derive(Debug, Display, From)]
|
|
|
|
pub enum Error {
|
|
|
|
/// Error concerning block import.
|
|
|
|
#[display(fmt = "Import error: {}", _0)]
|
|
|
|
Import(ImportError),
|
|
|
|
/// Io channel queue error
|
|
|
|
#[display(fmt = "Queue error: {}", _0)]
|
|
|
|
Queue(QueueError),
|
|
|
|
/// Io create error
|
|
|
|
#[display(fmt = "Io error: {}", _0)]
|
|
|
|
Io(::io::IoError),
|
|
|
|
/// Error concerning the Rust standard library's IO subsystem.
|
|
|
|
#[display(fmt = "Std Io error: {}", _0)]
|
|
|
|
StdIo(::std::io::Error),
|
|
|
|
/// Error concerning TrieDBs.
|
|
|
|
#[display(fmt = "Trie error: {}", _0)]
|
|
|
|
Trie(TrieError),
|
|
|
|
/// Error concerning EVM code execution.
|
|
|
|
#[display(fmt = "Execution error: {}", _0)]
|
|
|
|
Execution(ExecutionError),
|
|
|
|
/// Error concerning block processing.
|
|
|
|
#[display(fmt = "Block error: {}", _0)]
|
|
|
|
Block(BlockError),
|
|
|
|
/// Error concerning transaction processing.
|
|
|
|
#[display(fmt = "Transaction error: {}", _0)]
|
|
|
|
Transaction(TransactionError),
|
|
|
|
/// Snappy error
|
|
|
|
#[display(fmt = "Snappy error: {}", _0)]
|
|
|
|
Snappy(InvalidInput),
|
|
|
|
/// Consensus vote error.
|
|
|
|
#[display(fmt = "Engine error: {}", _0)]
|
|
|
|
Engine(EngineError),
|
|
|
|
/// Ethkey error."
|
|
|
|
#[display(fmt = "Ethkey error: {}", _0)]
|
|
|
|
Ethkey(EthkeyError),
|
|
|
|
/// RLP decoding errors
|
|
|
|
#[display(fmt = "Decoder error: {}", _0)]
|
|
|
|
Decoder(rlp::DecoderError),
|
|
|
|
/// Snapshot error.
|
|
|
|
#[display(fmt = "Snapshot error {}", _0)]
|
|
|
|
Snapshot(SnapshotError),
|
|
|
|
/// PoW hash is invalid or out of date.
|
|
|
|
#[display(fmt = "PoW hash is invalid or out of date.")]
|
|
|
|
PowHashInvalid,
|
|
|
|
/// The value of the nonce or mishash is invalid.
|
|
|
|
#[display(fmt = "The value of the nonce or mishash is invalid.")]
|
|
|
|
PowInvalid,
|
|
|
|
/// Unknown engine given
|
|
|
|
#[display(fmt = "Unknown engine name ({})", _0)]
|
|
|
|
UnknownEngineName(String),
|
|
|
|
/// A convenient variant for String.
|
|
|
|
#[display(fmt = "{}", _0)]
|
|
|
|
Msg(String),
|
|
|
|
}
|
2018-07-02 11:04:48 +02:00
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
impl error::Error for Error {
|
|
|
|
fn source(&self) -> Option<&(error::Error + 'static)> {
|
|
|
|
match self {
|
|
|
|
Error::Io(e) => Some(e),
|
|
|
|
Error::StdIo(e) => Some(e),
|
|
|
|
Error::Trie(e) => Some(e),
|
|
|
|
Error::Execution(e) => Some(e),
|
|
|
|
Error::Block(e) => Some(e),
|
|
|
|
Error::Transaction(e) => Some(e),
|
|
|
|
Error::Snappy(e) => Some(e),
|
|
|
|
Error::Engine(e) => Some(e),
|
|
|
|
Error::Ethkey(e) => Some(e),
|
|
|
|
Error::Decoder(e) => Some(e),
|
|
|
|
Error::Snapshot(e) => Some(e),
|
|
|
|
_ => None,
|
2018-04-19 11:52:54 +02:00
|
|
|
}
|
2019-05-06 15:06:20 +02:00
|
|
|
}
|
|
|
|
}
|
2016-01-10 14:05:39 +01:00
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
impl From<String> for Error {
|
|
|
|
fn from(s: String) -> Self {
|
|
|
|
Error::Msg(s)
|
2016-01-11 17:37:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-06 15:06:20 +02:00
|
|
|
impl From<&str> for Error {
|
|
|
|
fn from(s: &str) -> Self {
|
|
|
|
Error::Msg(s.into())
|
2016-08-05 17:00:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-03 18:35:48 +02:00
|
|
|
impl<E> From<Box<E>> for Error where Error: From<E> {
|
|
|
|
fn from(err: Box<E>) -> Error {
|
|
|
|
Error::from(*err)
|
|
|
|
}
|
|
|
|
}
|