github.com/ethereum/go-ethereum@v1.16.1/internal/ethapi/errors.go (about)

     1  // Copyright 2024 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 ethapi
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  
    23  	"github.com/ethereum/go-ethereum/accounts/abi"
    24  	"github.com/ethereum/go-ethereum/common/hexutil"
    25  	"github.com/ethereum/go-ethereum/core"
    26  	"github.com/ethereum/go-ethereum/core/vm"
    27  )
    28  
    29  // revertError is an API error that encompasses an EVM revert with JSON error
    30  // code and a binary data blob.
    31  type revertError struct {
    32  	error
    33  	reason string // revert reason hex encoded
    34  }
    35  
    36  // ErrorCode returns the JSON error code for a revert.
    37  // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
    38  func (e *revertError) ErrorCode() int {
    39  	return 3
    40  }
    41  
    42  // ErrorData returns the hex encoded revert reason.
    43  func (e *revertError) ErrorData() interface{} {
    44  	return e.reason
    45  }
    46  
    47  // newRevertError creates a revertError instance with the provided revert data.
    48  func newRevertError(revert []byte) *revertError {
    49  	err := vm.ErrExecutionReverted
    50  
    51  	reason, errUnpack := abi.UnpackRevert(revert)
    52  	if errUnpack == nil {
    53  		err = fmt.Errorf("%w: %v", vm.ErrExecutionReverted, reason)
    54  	}
    55  	return &revertError{
    56  		error:  err,
    57  		reason: hexutil.Encode(revert),
    58  	}
    59  }
    60  
    61  // TxIndexingError is an API error that indicates the transaction indexing is not
    62  // fully finished yet with JSON error code and a binary data blob.
    63  type TxIndexingError struct{}
    64  
    65  // NewTxIndexingError creates a TxIndexingError instance.
    66  func NewTxIndexingError() *TxIndexingError { return &TxIndexingError{} }
    67  
    68  // Error implement error interface, returning the error message.
    69  func (e *TxIndexingError) Error() string {
    70  	return "transaction indexing is in progress"
    71  }
    72  
    73  // ErrorCode returns the JSON error code for a revert.
    74  // See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
    75  func (e *TxIndexingError) ErrorCode() int {
    76  	return -32000 // to be decided
    77  }
    78  
    79  // ErrorData returns the hex encoded revert reason.
    80  func (e *TxIndexingError) ErrorData() interface{} { return "transaction indexing is in progress" }
    81  
    82  type callError struct {
    83  	Message string `json:"message"`
    84  	Code    int    `json:"code"`
    85  	Data    string `json:"data,omitempty"`
    86  }
    87  
    88  type invalidTxError struct {
    89  	Message string `json:"message"`
    90  	Code    int    `json:"code"`
    91  }
    92  
    93  func (e *invalidTxError) Error() string  { return e.Message }
    94  func (e *invalidTxError) ErrorCode() int { return e.Code }
    95  
    96  const (
    97  	errCodeNonceTooHigh            = -38011
    98  	errCodeNonceTooLow             = -38010
    99  	errCodeIntrinsicGas            = -38013
   100  	errCodeInsufficientFunds       = -38014
   101  	errCodeBlockGasLimitReached    = -38015
   102  	errCodeBlockNumberInvalid      = -38020
   103  	errCodeBlockTimestampInvalid   = -38021
   104  	errCodeSenderIsNotEOA          = -38024
   105  	errCodeMaxInitCodeSizeExceeded = -38025
   106  	errCodeClientLimitExceeded     = -38026
   107  	errCodeInternalError           = -32603
   108  	errCodeInvalidParams           = -32602
   109  	errCodeReverted                = -32000
   110  	errCodeVMError                 = -32015
   111  )
   112  
   113  func txValidationError(err error) *invalidTxError {
   114  	if err == nil {
   115  		return nil
   116  	}
   117  	switch {
   118  	case errors.Is(err, core.ErrNonceTooHigh):
   119  		return &invalidTxError{Message: err.Error(), Code: errCodeNonceTooHigh}
   120  	case errors.Is(err, core.ErrNonceTooLow):
   121  		return &invalidTxError{Message: err.Error(), Code: errCodeNonceTooLow}
   122  	case errors.Is(err, core.ErrSenderNoEOA):
   123  		return &invalidTxError{Message: err.Error(), Code: errCodeSenderIsNotEOA}
   124  	case errors.Is(err, core.ErrFeeCapVeryHigh):
   125  		return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams}
   126  	case errors.Is(err, core.ErrTipVeryHigh):
   127  		return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams}
   128  	case errors.Is(err, core.ErrTipAboveFeeCap):
   129  		return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams}
   130  	case errors.Is(err, core.ErrFeeCapTooLow):
   131  		return &invalidTxError{Message: err.Error(), Code: errCodeInvalidParams}
   132  	case errors.Is(err, core.ErrInsufficientFunds):
   133  		return &invalidTxError{Message: err.Error(), Code: errCodeInsufficientFunds}
   134  	case errors.Is(err, core.ErrIntrinsicGas):
   135  		return &invalidTxError{Message: err.Error(), Code: errCodeIntrinsicGas}
   136  	case errors.Is(err, core.ErrInsufficientFundsForTransfer):
   137  		return &invalidTxError{Message: err.Error(), Code: errCodeInsufficientFunds}
   138  	case errors.Is(err, core.ErrMaxInitCodeSizeExceeded):
   139  		return &invalidTxError{Message: err.Error(), Code: errCodeMaxInitCodeSizeExceeded}
   140  	}
   141  	return &invalidTxError{
   142  		Message: err.Error(),
   143  		Code:    errCodeInternalError,
   144  	}
   145  }
   146  
   147  type invalidParamsError struct{ message string }
   148  
   149  func (e *invalidParamsError) Error() string  { return e.message }
   150  func (e *invalidParamsError) ErrorCode() int { return errCodeInvalidParams }
   151  
   152  type clientLimitExceededError struct{ message string }
   153  
   154  func (e *clientLimitExceededError) Error() string  { return e.message }
   155  func (e *clientLimitExceededError) ErrorCode() int { return errCodeClientLimitExceeded }
   156  
   157  type invalidBlockNumberError struct{ message string }
   158  
   159  func (e *invalidBlockNumberError) Error() string  { return e.message }
   160  func (e *invalidBlockNumberError) ErrorCode() int { return errCodeBlockNumberInvalid }
   161  
   162  type invalidBlockTimestampError struct{ message string }
   163  
   164  func (e *invalidBlockTimestampError) Error() string  { return e.message }
   165  func (e *invalidBlockTimestampError) ErrorCode() int { return errCodeBlockTimestampInvalid }
   166  
   167  type blockGasLimitReachedError struct{ message string }
   168  
   169  func (e *blockGasLimitReachedError) Error() string  { return e.message }
   170  func (e *blockGasLimitReachedError) ErrorCode() int { return errCodeBlockGasLimitReached }