github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/evm/types/errors.go (about)

     1  package types
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  type ErrorCode uint16
     9  
    10  // internal error codes
    11  const ( // code reserved for no error
    12  	ErrCodeNoError ErrorCode = 0
    13  
    14  	// covers all other validation codes that doesn't have an specific code
    15  	ValidationErrCodeMisc ErrorCode = 100
    16  
    17  	// general execution error returned for cases that don't have an specific code
    18  	ExecutionErrCodeMisc ErrorCode = 400
    19  )
    20  
    21  // geth evm core errors (reserved range: [201-300) )
    22  const (
    23  	// the nonce of the tx is lower than the expected
    24  	ValidationErrCodeNonceTooLow ErrorCode = iota + 201
    25  	// the nonce of the tx is higher than the expected
    26  	ValidationErrCodeNonceTooHigh
    27  	// tx sender account has reached to the maximum nonce
    28  	ValidationErrCodeNonceMax
    29  	// not enough gas is available on the block to include this transaction
    30  	ValidationErrCodeGasLimitReached
    31  	// the transaction sender doesn't have enough funds for transfer(topmost call only).
    32  	ValidationErrCodeInsufficientFundsForTransfer
    33  	// creation transaction provides the init code bigger than init code size limit.
    34  	ValidationErrCodeMaxInitCodeSizeExceeded
    35  	// the total cost of executing a transaction is higher than the balance of the user's account.
    36  	ValidationErrCodeInsufficientFunds
    37  	// overflow detected when calculating the gas usage
    38  	ValidationErrCodeGasUintOverflow
    39  	// the transaction is specified to use less gas than required to start the invocation.
    40  	ValidationErrCodeIntrinsicGas
    41  	// the transaction is not supported in the current network configuration.
    42  	ValidationErrCodeTxTypeNotSupported
    43  	// tip was set to higher than the total fee cap
    44  	ValidationErrCodeTipAboveFeeCap
    45  	// an extremely big numbers is set for the tip field
    46  	ValidationErrCodeTipVeryHigh
    47  	// an extremely big numbers is set for the fee cap field
    48  	ValidationErrCodeFeeCapVeryHigh
    49  	// the transaction fee cap is less than the base fee of the block
    50  	ValidationErrCodeFeeCapTooLow
    51  	// the sender of a transaction is a contract
    52  	ValidationErrCodeSenderNoEOA
    53  	// the transaction fee cap is less than the blob gas fee of the block.
    54  	ValidationErrCodeBlobFeeCapTooLow
    55  )
    56  
    57  // evm execution errors (reserved range: [301-400) )
    58  const (
    59  	// execution ran out of gas
    60  	ExecutionErrCodeOutOfGas ErrorCode = iota + 301
    61  	// contract creation code storage out of gas
    62  	ExecutionErrCodeCodeStoreOutOfGas
    63  	// max call depth exceeded
    64  	ExecutionErrCodeDepth
    65  	// insufficient balance for transfer
    66  	ExecutionErrCodeInsufficientBalance
    67  	// contract address collision"
    68  	ExecutionErrCodeContractAddressCollision
    69  	// execution reverted
    70  	ExecutionErrCodeExecutionReverted
    71  	// max initcode size exceeded
    72  	ExecutionErrCodeMaxInitCodeSizeExceeded
    73  	// max code size exceeded
    74  	ExecutionErrCodeMaxCodeSizeExceeded
    75  	// invalid jump destination
    76  	ExecutionErrCodeInvalidJump
    77  	// write protection
    78  	ExecutionErrCodeWriteProtection
    79  	// return data out of bounds
    80  	ExecutionErrCodeReturnDataOutOfBounds
    81  	// gas uint64 overflow
    82  	ExecutionErrCodeGasUintOverflow
    83  	// invalid code: must not begin with 0xef
    84  	ExecutionErrCodeInvalidCode
    85  	// nonce uint64 overflow
    86  	ExecutionErrCodeNonceUintOverflow
    87  )
    88  
    89  var (
    90  	// ErrInvalidBalance is returned when an invalid balance is provided for transfer (e.g. negative)
    91  	ErrInvalidBalance = errors.New("invalid balance for transfer")
    92  
    93  	// ErrInsufficientComputation is returned when not enough computation is
    94  	// left in the context of flow transaction to execute the evm operation.
    95  	ErrInsufficientComputation = errors.New("insufficient computation")
    96  
    97  	// ErrUnAuthroizedMethodCall method call, usually emited when calls are called on EOA accounts
    98  	ErrUnAuthroizedMethodCall = errors.New("unauthroized method call")
    99  
   100  	// ErrInternalDirecCallFailed is returned when a withdraw or deposit internal call has failed.
   101  	ErrInternalDirectCallFailed = errors.New("internal direct call execution failed")
   102  
   103  	// ErrWithdrawBalanceRounding is returned when withdraw call has a balance that could
   104  	// yeild to rounding error, i.e. the balance contains fractions smaller than 10^8 Flow (smallest unit allowed to transfer).
   105  	ErrWithdrawBalanceRounding = errors.New("withdraw failed! the balance is susceptible to the rounding error")
   106  
   107  	// ErrUnexpectedEmptyResult is returned when a result is expected to be returned by the emulator
   108  	// but nil has been returned. This should never happen and is a safety error.
   109  	ErrUnexpectedEmptyResult = errors.New("unexpected empty result has been returned")
   110  
   111  	// ErrInsufficientTotalSupply is returned when flow token
   112  	// is withdraw request is there but not enough balance is on EVM vault
   113  	// this should never happen but its a saftey measure to protect Flow against EVM issues.
   114  	ErrInsufficientTotalSupply = NewFatalError(errors.New("insufficient total supply"))
   115  
   116  	// ErrNotImplemented is a fatal error when something is called that is not implemented
   117  	ErrNotImplemented = NewFatalError(errors.New("a functionality is called that is not implemented"))
   118  )
   119  
   120  // StateError is a non-fatal error, returned when a state operation
   121  // has failed (e.g. reaching storage interaction limit)
   122  type StateError struct {
   123  	err error
   124  }
   125  
   126  // NewStateError returns a new StateError
   127  func NewStateError(rootCause error) StateError {
   128  	return StateError{
   129  		err: rootCause,
   130  	}
   131  }
   132  
   133  // Unwrap unwraps the underlying evm error
   134  func (err StateError) Unwrap() error {
   135  	return err.err
   136  }
   137  
   138  func (err StateError) Error() string {
   139  	return fmt.Sprintf("state error: %v", err.err)
   140  }
   141  
   142  // IsAStateError returns true if the error or any underlying errors
   143  // is a state error
   144  func IsAStateError(err error) bool {
   145  	return errors.As(err, &StateError{})
   146  }
   147  
   148  // FatalError is used for any error that is not user related and something
   149  // unusual has happend. Usually we stop the node when this happens
   150  // given it might have a non-deterministic root.
   151  type FatalError struct {
   152  	err error
   153  }
   154  
   155  // NewFatalError returns a new FatalError
   156  func NewFatalError(rootCause error) FatalError {
   157  	return FatalError{
   158  		err: rootCause,
   159  	}
   160  }
   161  
   162  // Unwrap unwraps the underlying fatal error
   163  func (err FatalError) Unwrap() error {
   164  	return err.err
   165  }
   166  
   167  func (err FatalError) Error() string {
   168  	return fmt.Sprintf("fatal error: %v", err.err)
   169  }
   170  
   171  // IsAFatalError returns true if the error or underlying error
   172  // is of fatal type.
   173  func IsAFatalError(err error) bool {
   174  	return errors.As(err, &FatalError{})
   175  }
   176  
   177  // IsAInsufficientTotalSupplyError returns true if the
   178  // error type is InsufficientTotalSupplyError
   179  func IsAInsufficientTotalSupplyError(err error) bool {
   180  	return errors.Is(err, ErrInsufficientTotalSupply)
   181  }
   182  
   183  // IsWithdrawBalanceRoundingError returns true if the error type is
   184  // ErrWithdrawBalanceRounding
   185  func IsWithdrawBalanceRoundingError(err error) bool {
   186  	return errors.Is(err, ErrWithdrawBalanceRounding)
   187  }
   188  
   189  // IsAUnAuthroizedMethodCallError returns true if the error type is
   190  // UnAuthroizedMethodCallError
   191  func IsAUnAuthroizedMethodCallError(err error) bool {
   192  	return errors.Is(err, ErrUnAuthroizedMethodCall)
   193  }
   194  
   195  // BackendError is a non-fatal error wraps errors returned from the backend
   196  type BackendError struct {
   197  	err error
   198  }
   199  
   200  // NewBackendError returns a new BackendError
   201  func NewBackendError(rootCause error) BackendError {
   202  	return BackendError{
   203  		err: rootCause,
   204  	}
   205  }
   206  
   207  // Unwrap unwraps the underlying evm error
   208  func (err BackendError) Unwrap() error {
   209  	return err.err
   210  }
   211  
   212  func (err BackendError) Error() string {
   213  	return fmt.Sprintf("backend error: %v", err.err)
   214  }
   215  
   216  // IsABackendError returns true if the error or
   217  // any underlying errors is a backend error
   218  func IsABackendError(err error) bool {
   219  	return errors.As(err, &BackendError{})
   220  }