//! General error types for use in ethcore. use util::*; use header::BlockNumber; use basic_types::LogBloom; #[derive(Debug, PartialEq, Eq)] pub struct Mismatch { pub expected: T, pub found: T, } #[derive(Debug, PartialEq, Eq)] pub struct OutOfBounds { pub min: Option, pub max: Option, pub found: T, } /// Result of executing the transaction. #[derive(PartialEq, Debug)] pub enum ExecutionError { /// Returned when there gas paid for transaction execution is /// lower than base gas required. NotEnoughBaseGas { required: U256, got: U256 }, /// Returned when block (gas_used + gas) > gas_limit. /// /// If gas =< gas_limit, upstream may try to execute the transaction /// in next block. BlockGasLimitReached { gas_limit: U256, gas_used: U256, gas: U256 }, /// Returned when transaction nonce does not match state nonce. InvalidNonce { expected: U256, got: U256 }, /// Returned when cost of transaction (value + gas_price * gas) exceeds /// current sender balance. NotEnoughCash { required: U512, got: U512 }, /// Returned when internal evm error occurs. Internal } #[derive(Debug)] pub enum TransactionError { InvalidGasLimit(OutOfBounds), } #[derive(Debug, PartialEq, Eq)] pub enum BlockError { TooManyUncles(OutOfBounds), UncleWrongGeneration, ExtraDataOutOfBounds(OutOfBounds), InvalidSealArity(Mismatch), TooMuchGasUsed(OutOfBounds), InvalidUnclesHash(Mismatch), UncleTooOld(OutOfBounds), UncleIsBrother(OutOfBounds), UncleInChain(H256), UncleParentNotInChain(H256), InvalidStateRoot(Mismatch), InvalidGasUsed(Mismatch), InvalidTransactionsRoot(Mismatch), InvalidDifficulty(Mismatch), InvalidGasLimit(OutOfBounds), InvalidReceiptsStateRoot(Mismatch), InvalidTimestamp(OutOfBounds), InvalidLogBloom(Mismatch), InvalidEthashDifficulty(Mismatch), InvalidBlockNonce(Mismatch), InvalidParentHash(Mismatch), InvalidNumber(OutOfBounds), UnknownParent(H256), UnknownUncleParent(H256), } #[derive(Debug)] pub enum ImportError { Bad(Option), AlreadyInChain, AlreadyQueued, } impl From for ImportError { fn from(err: Error) -> ImportError { ImportError::Bad(Some(err)) } } /// Result of import block operation. pub type ImportResult = Result<(), ImportError>; #[derive(Debug)] /// General error type which should be capable of representing all errors in ethcore. pub enum Error { Util(UtilError), Block(BlockError), UnknownEngineName(String), Execution(ExecutionError), Transaction(TransactionError), } impl From for Error { fn from(err: TransactionError) -> Error { Error::Transaction(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 for Error { fn from(err: CryptoError) -> Error { Error::Util(UtilError::Crypto(err)) } } impl From for Error { fn from(err: DecoderError) -> Error { Error::Util(UtilError::Decoder(err)) } } impl From for Error { fn from(err: UtilError) -> Error { Error::Util(err) } } impl From for Error { fn from(err: IoError) -> Error { Error::Util(From::from(err)) } } // TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted. /*#![feature(concat_idents)] macro_rules! assimilate { ($name:ident) => ( impl From for Error { fn from(err: concat_idents!($name, Error)) -> Error { Error:: $name (err) } } ) } assimilate!(FromHex); assimilate!(BaseData);*/