github.com/koko1123/flow-go-1@v0.29.6/fvm/errors/execution.go (about)

     1  package errors
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/onflow/cadence"
     7  	"github.com/onflow/cadence/runtime"
     8  
     9  	"github.com/koko1123/flow-go-1/model/flow"
    10  )
    11  
    12  // NewCadenceRuntimeError constructs a new CodedError which captures a
    13  // collection of errors provided by cadence runtime. It cover cadence errors
    14  // such as:
    15  //
    16  // NotDeclaredError, NotInvokableError, ArgumentCountError,
    17  // TransactionNotDeclaredError, ConditionError, RedeclarationError,
    18  // DereferenceError, OverflowError, UnderflowError, DivisionByZeroError,
    19  // DestroyedCompositeError,  ForceAssignmentToNonNilResourceError,
    20  // ForceNilError, TypeMismatchError, InvalidPathDomainError, OverwriteError,
    21  // CyclicLinkError, ArrayIndexOutOfBoundsError, ...
    22  //
    23  // The Cadence error might have occurred because of an inner fvm Error.
    24  func NewCadenceRuntimeError(err runtime.Error) CodedError {
    25  	return WrapCodedError(
    26  		ErrCodeCadenceRunTimeError,
    27  		err,
    28  		"cadence runtime error")
    29  }
    30  
    31  func IsCadenceRuntimeError(err error) bool {
    32  	return HasErrorCode(err, ErrCodeCadenceRunTimeError)
    33  }
    34  
    35  // NewTransactionFeeDeductionFailedError constructs a new CodedError which
    36  // indicates that a there was an error deducting transaction fees from the
    37  // transaction Payer
    38  func NewTransactionFeeDeductionFailedError(
    39  	payer flow.Address,
    40  	txFees uint64,
    41  	err error,
    42  ) CodedError {
    43  	return WrapCodedError(
    44  		ErrCodeTransactionFeeDeductionFailedError,
    45  		err,
    46  		"failed to deduct %d transaction fees from %s",
    47  		txFees,
    48  		payer)
    49  }
    50  
    51  // IsTransactionFeeDeductionFailedError returns true if error has this code.
    52  func IsTransactionFeeDeductionFailedError(err error) bool {
    53  	return HasErrorCode(err, ErrCodeTransactionFeeDeductionFailedError)
    54  }
    55  
    56  // NewInsufficientPayerBalanceError constructs a new CodedError which
    57  // indicates that the payer has insufficient balance to attempt transaction execution.
    58  func NewInsufficientPayerBalanceError(
    59  	payer flow.Address,
    60  	requiredBalance cadence.UFix64,
    61  ) CodedError {
    62  	return NewCodedError(
    63  		ErrCodeInsufficientPayerBalance,
    64  		"payer %s has insufficient balance to attempt transaction execution (required balance: %s)",
    65  		payer,
    66  		requiredBalance,
    67  	)
    68  }
    69  
    70  // IsInsufficientPayerBalanceError returns true if error has this code.
    71  func IsInsufficientPayerBalanceError(err error) bool {
    72  	return HasErrorCode(err, ErrCodeInsufficientPayerBalance)
    73  }
    74  
    75  // indicates that a there was an error checking the payers balance.
    76  // This is an implementation error most likely between the smart contract and FVM interaction
    77  // and should not happen in regular execution.
    78  func NewPayerBalanceCheckFailure(
    79  	payer flow.Address,
    80  	err error,
    81  ) CodedError {
    82  	return WrapCodedError(
    83  		FailureCodePayerBalanceCheckFailure,
    84  		err,
    85  		"failed to check if the payer %s has sufficient balance",
    86  		payer)
    87  }
    88  
    89  // NewComputationLimitExceededError constructs a new CodedError which indicates
    90  // that computation has exceeded its limit.
    91  func NewComputationLimitExceededError(limit uint64) CodedError {
    92  	return NewCodedError(
    93  		ErrCodeComputationLimitExceededError,
    94  		"computation exceeds limit (%d)",
    95  		limit)
    96  }
    97  
    98  // IsComputationLimitExceededError returns true if error has this code.
    99  func IsComputationLimitExceededError(err error) bool {
   100  	return HasErrorCode(err, ErrCodeComputationLimitExceededError)
   101  }
   102  
   103  // NewMemoryLimitExceededError constructs a new CodedError which indicates
   104  // that execution has exceeded its memory limits.
   105  func NewMemoryLimitExceededError(limit uint64) CodedError {
   106  	return NewCodedError(
   107  		ErrCodeMemoryLimitExceededError,
   108  		"memory usage exceeds limit (%d)",
   109  		limit)
   110  }
   111  
   112  // IsMemoryLimitExceededError returns true if error has this code.
   113  func IsMemoryLimitExceededError(err error) bool {
   114  	return HasErrorCode(err, ErrCodeMemoryLimitExceededError)
   115  }
   116  
   117  // NewStorageCapacityExceededError constructs a new CodedError which indicates
   118  // that an account used more storage than it has storage capacity.
   119  func NewStorageCapacityExceededError(
   120  	address flow.Address,
   121  	storageUsed uint64,
   122  	storageCapacity uint64,
   123  ) CodedError {
   124  	return NewCodedError(
   125  		ErrCodeStorageCapacityExceeded,
   126  		"The account with address (%s) uses %d bytes of storage which is "+
   127  			"over its capacity (%d bytes). Capacity can be increased by "+
   128  			"adding FLOW tokens to the account.",
   129  		address,
   130  		storageUsed,
   131  		storageCapacity)
   132  }
   133  
   134  func IsStorageCapacityExceededError(err error) bool {
   135  	return HasErrorCode(err, ErrCodeStorageCapacityExceeded)
   136  }
   137  
   138  // NewEventLimitExceededError constructs a CodedError which indicates that the
   139  // transaction has produced events with size more than limit.
   140  func NewEventLimitExceededError(
   141  	totalByteSize uint64,
   142  	limit uint64) CodedError {
   143  	return NewCodedError(
   144  		ErrCodeEventLimitExceededError,
   145  		"total event byte size (%d) exceeds limit (%d)",
   146  		totalByteSize,
   147  		limit)
   148  }
   149  
   150  // NewStateKeySizeLimitError constructs a CodedError which indicates that the
   151  // provided key has exceeded the size limit allowed by the storage.
   152  func NewStateKeySizeLimitError(
   153  	owner string,
   154  	key string,
   155  	size uint64,
   156  	limit uint64,
   157  ) CodedError {
   158  	return NewCodedError(
   159  		ErrCodeStateKeySizeLimitError,
   160  		"key %s has size %d which is higher than storage key size limit %d.",
   161  		strings.Join([]string{owner, key}, "/"),
   162  		size,
   163  		limit)
   164  }
   165  
   166  // NewStateValueSizeLimitError constructs a CodedError which indicates that the
   167  // provided value has exceeded the size limit allowed by the storage.
   168  func NewStateValueSizeLimitError(
   169  	value flow.RegisterValue,
   170  	size uint64,
   171  	limit uint64,
   172  ) CodedError {
   173  	valueStr := ""
   174  	if len(value) > 23 {
   175  		valueStr = string(value[0:10]) + "..." + string(value[len(value)-10:])
   176  	} else {
   177  		valueStr = string(value)
   178  	}
   179  
   180  	return NewCodedError(
   181  		ErrCodeStateValueSizeLimitError,
   182  		"value %s has size %d which is higher than storage value size "+
   183  			"limit %d.",
   184  		valueStr,
   185  		size,
   186  		limit)
   187  }
   188  
   189  // NewLedgerInteractionLimitExceededError constructs a CodeError. It is
   190  // returned when a tx hits the maximum ledger interaction limit.
   191  func NewLedgerInteractionLimitExceededError(
   192  	used uint64,
   193  	limit uint64,
   194  ) CodedError {
   195  	return NewCodedError(
   196  		ErrCodeLedgerInteractionLimitExceededError,
   197  		"max interaction with storage has exceeded the limit "+
   198  			"(used: %d bytes, limit %d bytes)",
   199  		used,
   200  		limit)
   201  }
   202  
   203  func IsLedgerInteractionLimitExceededError(err error) bool {
   204  	return HasErrorCode(err, ErrCodeLedgerInteractionLimitExceededError)
   205  }
   206  
   207  // NewOperationNotSupportedError construct a new CodedError. It is generated
   208  // when an operation (e.g. getting block info) is not supported in the current
   209  // environment.
   210  func NewOperationNotSupportedError(operation string) CodedError {
   211  	return NewCodedError(
   212  		ErrCodeOperationNotSupportedError,
   213  		"operation (%s) is not supported in this environment",
   214  		operation)
   215  }
   216  
   217  func IsOperationNotSupportedError(err error) bool {
   218  	return HasErrorCode(err, ErrCodeOperationNotSupportedError)
   219  }
   220  
   221  // NewScriptExecutionCancelledError construct a new CodedError which indicates
   222  // that Cadence Script execution has been cancelled (e.g. request connection
   223  // has been droped)
   224  //
   225  // note: this error is used by scripts only and won't be emitted for
   226  // transactions since transaction execution has to be deterministic.
   227  func NewScriptExecutionCancelledError(err error) CodedError {
   228  	return WrapCodedError(
   229  		ErrCodeScriptExecutionCancelledError,
   230  		err,
   231  		"script execution is cancelled")
   232  }
   233  
   234  // NewScriptExecutionTimedOutError construct a new CodedError which indicates
   235  // that Cadence Script execution has been taking more time than what is allowed.
   236  //
   237  // note: this error is used by scripts only and won't be emitted for
   238  // transactions since transaction execution has to be deterministic.
   239  func NewScriptExecutionTimedOutError() CodedError {
   240  	return NewCodedError(
   241  		ErrCodeScriptExecutionTimedOutError,
   242  		"script execution is timed out and did not finish executing within "+
   243  			"the maximum execution time allowed")
   244  }
   245  
   246  // NewCouldNotGetExecutionParameterFromStateError constructs a new CodedError
   247  // which indicates that computation has exceeded its limit.
   248  func NewCouldNotGetExecutionParameterFromStateError(
   249  	address string,
   250  	path string,
   251  ) CodedError {
   252  	return NewCodedError(
   253  		ErrCodeCouldNotDecodeExecutionParameterFromState,
   254  		"could not get execution parameter from the state "+
   255  			"(address: %s path: %s)",
   256  		address,
   257  		path)
   258  }
   259  
   260  // NewInvalidFVMStateAccessError constructs a new CodedError which indicates
   261  // that the cadence program attempted to directly access fvm's internal state.
   262  func NewInvalidFVMStateAccessError(
   263  	address flow.Address,
   264  	path string,
   265  	opType string,
   266  ) CodedError {
   267  	return NewCodedError(
   268  		ErrCodeInvalidFVMStateAccessError,
   269  		"could not directly %s fvm internal state (address: %s: path: %s)",
   270  		opType,
   271  		address,
   272  		path)
   273  }