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