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  }