github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/core/vm/errors.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "errors" 21 "fmt" 22 "math" 23 ) 24 25 // List evm execution errors 26 var ( 27 ErrOutOfGas = errors.New("out of gas") 28 ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") 29 ErrDepth = errors.New("max call depth exceeded") 30 ErrInsufficientBalance = errors.New("insufficient balance for transfer") 31 ErrContractAddressCollision = errors.New("contract address collision") 32 ErrExecutionReverted = errors.New("execution reverted") 33 ErrMaxCodeSizeExceeded = errors.New("max code size exceeded") 34 ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded") 35 ErrInvalidJump = errors.New("invalid jump destination") 36 ErrWriteProtection = errors.New("write protection") 37 ErrReturnDataOutOfBounds = errors.New("return data out of bounds") 38 ErrGasUintOverflow = errors.New("gas uint64 overflow") 39 ErrInvalidCode = errors.New("invalid code: must not begin with 0xef") 40 ErrNonceUintOverflow = errors.New("nonce uint64 overflow") 41 42 // errStopToken is an internal token indicating interpreter loop termination, 43 // never returned to outside callers. 44 errStopToken = errors.New("stop token") 45 ) 46 47 // ErrStackUnderflow wraps an evm error when the items on the stack less 48 // than the minimal requirement. 49 type ErrStackUnderflow struct { 50 stackLen int 51 required int 52 } 53 54 func (e *ErrStackUnderflow) Error() string { 55 return fmt.Sprintf("stack underflow (%d <=> %d)", e.stackLen, e.required) 56 } 57 58 // ErrStackOverflow wraps an evm error when the items on the stack exceeds 59 // the maximum allowance. 60 type ErrStackOverflow struct { 61 stackLen int 62 limit int 63 } 64 65 func (e *ErrStackOverflow) Error() string { 66 return fmt.Sprintf("stack limit reached %d (%d)", e.stackLen, e.limit) 67 } 68 69 // ErrInvalidOpCode wraps an evm error when an invalid opcode is encountered. 70 type ErrInvalidOpCode struct { 71 opcode OpCode 72 } 73 74 func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode: %s", e.opcode) } 75 76 // rpcError is the same interface as the one defined in rpc/errors.go 77 // but we do not want to depend on rpc package here so we redefine it. 78 // 79 // It's used to ensure that the VMError implements the RPC error interface. 80 type rpcError interface { 81 Error() string // returns the message 82 ErrorCode() int // returns the code 83 } 84 85 var _ rpcError = (*VMError)(nil) 86 87 // VMError wraps a VM error with an additional stable error code. The error 88 // field is the original error that caused the VM error and must be one of the 89 // VM error defined at the top of this file. 90 // 91 // If the error is not one of the known error above, the error code will be 92 // set to VMErrorCodeUnknown. 93 type VMError struct { 94 error 95 code int 96 } 97 98 func VMErrorFromErr(err error) error { 99 if err == nil { 100 return nil 101 } 102 103 return &VMError{ 104 error: err, 105 code: vmErrorCodeFromErr(err), 106 } 107 } 108 109 func (e *VMError) Error() string { 110 return e.error.Error() 111 } 112 113 func (e *VMError) Unwrap() error { 114 return e.error 115 } 116 117 func (e *VMError) ErrorCode() int { 118 return e.code 119 } 120 121 const ( 122 // We start the error code at 1 so that we can use 0 later for some possible extension. There 123 // is no unspecified value for the code today because it should always be set to a valid value 124 // that could be VMErrorCodeUnknown if the error is not mapped to a known error code. 125 126 VMErrorCodeOutOfGas = 1 + iota 127 VMErrorCodeCodeStoreOutOfGas 128 VMErrorCodeDepth 129 VMErrorCodeInsufficientBalance 130 VMErrorCodeContractAddressCollision 131 VMErrorCodeExecutionReverted 132 VMErrorCodeMaxCodeSizeExceeded 133 VMErrorCodeInvalidJump 134 VMErrorCodeWriteProtection 135 VMErrorCodeReturnDataOutOfBounds 136 VMErrorCodeGasUintOverflow 137 VMErrorCodeInvalidCode 138 VMErrorCodeNonceUintOverflow 139 VMErrorCodeStackUnderflow 140 VMErrorCodeStackOverflow 141 VMErrorCodeInvalidOpCode 142 143 // VMErrorCodeUnknown explicitly marks an error as unknown, this is useful when error is converted 144 // from an actual `error` in which case if the mapping is not known, we can use this value to indicate that. 145 VMErrorCodeUnknown = math.MaxInt - 1 146 ) 147 148 func vmErrorCodeFromErr(err error) int { 149 switch { 150 case errors.Is(err, ErrOutOfGas): 151 return VMErrorCodeOutOfGas 152 case errors.Is(err, ErrCodeStoreOutOfGas): 153 return VMErrorCodeCodeStoreOutOfGas 154 case errors.Is(err, ErrDepth): 155 return VMErrorCodeDepth 156 case errors.Is(err, ErrInsufficientBalance): 157 return VMErrorCodeInsufficientBalance 158 case errors.Is(err, ErrContractAddressCollision): 159 return VMErrorCodeContractAddressCollision 160 case errors.Is(err, ErrExecutionReverted): 161 return VMErrorCodeExecutionReverted 162 case errors.Is(err, ErrMaxCodeSizeExceeded): 163 return VMErrorCodeMaxCodeSizeExceeded 164 case errors.Is(err, ErrInvalidJump): 165 return VMErrorCodeInvalidJump 166 case errors.Is(err, ErrWriteProtection): 167 return VMErrorCodeWriteProtection 168 case errors.Is(err, ErrReturnDataOutOfBounds): 169 return VMErrorCodeReturnDataOutOfBounds 170 case errors.Is(err, ErrGasUintOverflow): 171 return VMErrorCodeGasUintOverflow 172 case errors.Is(err, ErrInvalidCode): 173 return VMErrorCodeInvalidCode 174 case errors.Is(err, ErrNonceUintOverflow): 175 return VMErrorCodeNonceUintOverflow 176 177 default: 178 // Dynamic errors 179 if v := (*ErrStackUnderflow)(nil); errors.As(err, &v) { 180 return VMErrorCodeStackUnderflow 181 } 182 183 if v := (*ErrStackOverflow)(nil); errors.As(err, &v) { 184 return VMErrorCodeStackOverflow 185 } 186 187 if v := (*ErrInvalidOpCode)(nil); errors.As(err, &v) { 188 return VMErrorCodeInvalidOpCode 189 } 190 191 return VMErrorCodeUnknown 192 } 193 }