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