1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
//! VM errors use bigint::{Address, U256}; #[derive(Debug, Clone)] /// Errors when trying to validate the transaction. pub enum PreExecutionError { /// The caller is invalid. InvalidCaller, /// Nonce of the caller does not equal. InvalidNonce, /// Balance from the caller is insufficient. InsufficientBalance, /// Gas limit is smaller than the intrinsic gas required. InsufficientGasLimit, } #[derive(Debug, Clone)] /// Errors returned by an EVM memory. pub enum MemoryError { /// The index is too large for the implementation of the VM to /// handle. IndexNotSupported, } impl From<MemoryError> for MachineError { fn from(val: MemoryError) -> MachineError { MachineError::Memory(val) } } impl From<MemoryError> for EvalError { fn from(val: MemoryError) -> EvalError { EvalError::Machine(MachineError::Memory(val)) } } #[derive(Debug, Clone)] /// Errors returned by an EVM stack. pub enum StackError { /// Stack is overflowed (pushed more than 1024 items to the /// stack). Overflow, /// Stack is underflowed (poped an empty stack). Underflow, } impl From<StackError> for EvalError { fn from(val: StackError) -> EvalError { EvalError::Machine(MachineError::Stack(val)) } } #[derive(Debug, Clone)] /// Errors returned by an EVM PC. pub enum PCError { /// The opcode is invalid and the PC is not able to convert it to /// an instruction. InvalidOpcode, /// The index is too large for the implementation of the VM to /// handle. IndexNotSupported, /// PC jumped to an invalid jump destination. BadJumpDest, /// PC overflowed (tries to read the next opcode which is already /// the end of the code). Overflow, } impl From<PCError> for EvalError { fn from(val: PCError) -> EvalError { EvalError::Machine(MachineError::PC(val)) } } #[derive(Debug, Clone)] /// Errors returned when trying to step the instruction. pub enum EvalError { /// A runtime error. Non-recoverable. Machine(MachineError), /// The VM requires account of blockhash information to be /// committed. Recoverable after the required information is /// committed. Require(RequireError), } #[derive(Debug, Clone)] /// Errors returned by the a single machine of the VM. pub enum MachineError { /// VM memory error. Memory(MemoryError), /// VM stack error. Stack(StackError), /// VM PC error. PC(PCError), /// For instruction that requires reading a range, it is invalid. InvalidRange, /// Not enough gas to continue. EmptyGas, } impl From<MachineError> for EvalError { fn from(val: MachineError) -> EvalError { EvalError::Machine(val) } } #[derive(Debug, Clone)] /// Errors stating that the VM requires additional information to /// continue running. pub enum RequireError { /// Requires the account at address for the VM to continue /// running, this should usually be dealt by /// `vm.commit_account(AccountCommitment::Full { .. })` or /// `vm.commit_account(AccountCommitment::Nonexist(..))`. Account(Address), /// Requires the account code at address for the VM to continue /// running, this should usually be dealt by /// `vm.commit_account(AccountCommitment::Code { .. })`. AccountCode(Address), /// Requires the current value of the storage for the VM to /// continue running, this should usually be dealt by /// `vm.commit_account(AccountCommitment::Storage { .. }`. AccountStorage(Address, U256), /// Requires the blockhash for the VM to continue running, this /// should usually be dealt by `vm.commit_blockhash(..)`. Blockhash(U256), } impl From<RequireError> for EvalError { fn from(val: RequireError) -> EvalError { EvalError::Require(val) } } #[derive(Debug, Clone)] /// Errors returned when committing a new information. pub enum CommitError { /// The commitment is invalid. InvalidCommitment, /// The commitment has already been committed. AlreadyCommitted, }