1use serde::Deserialize;
7
8use super::rpc::GlobalContractIdentifierView;
9use super::{AccountId, CryptoHash, Gas, NearToken, PublicKey};
10
11#[derive(Debug, Clone, Deserialize)]
17pub enum TxExecutionError {
18 ActionError(ActionError),
20 InvalidTxError(InvalidTxError),
22}
23
24impl std::fmt::Display for TxExecutionError {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 match self {
27 Self::ActionError(e) => write!(f, "ActionError: {e}"),
28 Self::InvalidTxError(e) => write!(f, "InvalidTxError: {e}"),
29 }
30 }
31}
32
33impl std::error::Error for TxExecutionError {}
34
35#[derive(Debug, Clone, Deserialize)]
41pub struct ActionError {
42 #[serde(default)]
45 pub index: Option<u64>,
46 pub kind: ActionErrorKind,
48}
49
50impl std::fmt::Display for ActionError {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 match self.index {
53 Some(i) => write!(f, "action #{i}: {}", self.kind),
54 None => write!(f, "{}", self.kind),
55 }
56 }
57}
58
59#[derive(Debug, Clone, Deserialize)]
61pub enum ActionErrorKind {
62 AccountAlreadyExists {
63 account_id: AccountId,
64 },
65 AccountDoesNotExist {
66 account_id: AccountId,
67 },
68 CreateAccountOnlyByRegistrar {
69 account_id: AccountId,
70 predecessor_id: AccountId,
71 registrar_account_id: AccountId,
72 },
73 CreateAccountNotAllowed {
74 account_id: AccountId,
75 predecessor_id: AccountId,
76 },
77 ActorNoPermission {
78 account_id: AccountId,
79 actor_id: AccountId,
80 },
81 DeleteKeyDoesNotExist {
82 account_id: AccountId,
83 public_key: PublicKey,
84 },
85 AddKeyAlreadyExists {
86 account_id: AccountId,
87 public_key: PublicKey,
88 },
89 DeleteAccountStaking {
90 account_id: AccountId,
91 },
92 LackBalanceForState {
93 account_id: AccountId,
94 amount: NearToken,
95 },
96 TriesToUnstake {
97 account_id: AccountId,
98 },
99 TriesToStake {
100 account_id: AccountId,
101 balance: NearToken,
102 locked: NearToken,
103 stake: NearToken,
104 },
105 InsufficientStake {
106 account_id: AccountId,
107 minimum_stake: NearToken,
108 stake: NearToken,
109 },
110 FunctionCallError(FunctionCallError),
111 NewReceiptValidationError(ReceiptValidationError),
112 OnlyImplicitAccountCreationAllowed {
113 account_id: AccountId,
114 },
115 DeleteAccountWithLargeState {
116 account_id: AccountId,
117 },
118 DelegateActionInvalidSignature,
119 DelegateActionSenderDoesNotMatchTxReceiver {
120 receiver_id: AccountId,
121 sender_id: AccountId,
122 },
123 DelegateActionExpired,
124 DelegateActionAccessKeyError(InvalidAccessKeyError),
125 DelegateActionInvalidNonce {
126 ak_nonce: u64,
127 delegate_nonce: u64,
128 },
129 DelegateActionNonceTooLarge {
130 delegate_nonce: u64,
131 upper_bound: u64,
132 },
133 GlobalContractDoesNotExist {
134 identifier: GlobalContractIdentifierView,
135 },
136 GasKeyDoesNotExist {
137 account_id: AccountId,
138 public_key: PublicKey,
139 },
140 InsufficientGasKeyBalance {
141 account_id: AccountId,
142 balance: NearToken,
143 public_key: PublicKey,
144 required: NearToken,
145 },
146 GasKeyBalanceTooHigh {
147 account_id: AccountId,
148 balance: NearToken,
149 #[serde(default)]
150 public_key: Option<PublicKey>,
151 },
152}
153
154impl std::fmt::Display for ActionErrorKind {
155 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156 match self {
157 Self::AccountAlreadyExists { account_id } => {
158 write!(f, "account {account_id} already exists")
159 }
160 Self::AccountDoesNotExist { account_id } => {
161 write!(f, "account {account_id} does not exist")
162 }
163 Self::LackBalanceForState { account_id, amount } => {
164 write!(f, "account {account_id} lacks {amount} for state")
165 }
166 Self::FunctionCallError(e) => write!(f, "{e}"),
167 _ => write!(f, "{self:?}"),
168 }
169 }
170}
171
172#[derive(Debug, Clone, Deserialize)]
178pub enum InvalidTxError {
179 InvalidAccessKeyError(InvalidAccessKeyError),
180 InvalidSignerId {
181 signer_id: String,
182 },
183 SignerDoesNotExist {
184 signer_id: AccountId,
185 },
186 InvalidNonce {
187 ak_nonce: u64,
188 tx_nonce: u64,
189 },
190 NonceTooLarge {
191 tx_nonce: u64,
192 upper_bound: u64,
193 },
194 InvalidReceiverId {
195 receiver_id: String,
196 },
197 InvalidSignature,
198 NotEnoughBalance {
199 balance: NearToken,
200 cost: NearToken,
201 signer_id: AccountId,
202 },
203 LackBalanceForState {
204 amount: NearToken,
205 signer_id: AccountId,
206 },
207 CostOverflow,
208 InvalidChain,
209 Expired,
210 ActionsValidation(ActionsValidationError),
211 TransactionSizeExceeded {
212 limit: u64,
213 size: u64,
214 },
215 InvalidTransactionVersion,
216 StorageError(StorageError),
217 ShardCongested {
218 congestion_level: f64,
219 shard_id: u64,
220 },
221 ShardStuck {
222 missed_chunks: u64,
223 shard_id: u64,
224 },
225 InvalidNonceIndex {
226 num_nonces: u16,
227 #[serde(default)]
228 tx_nonce_index: Option<u16>,
229 },
230 NotEnoughGasKeyBalance {
231 balance: NearToken,
232 cost: NearToken,
233 signer_id: AccountId,
234 },
235 NotEnoughBalanceForDeposit {
236 balance: NearToken,
237 cost: NearToken,
238 reason: DepositCostFailureReason,
239 signer_id: AccountId,
240 },
241}
242
243impl std::fmt::Display for InvalidTxError {
244 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
245 match self {
246 Self::InvalidSignature => write!(f, "invalid signature"),
247 Self::NotEnoughBalance {
248 signer_id, cost, ..
249 } => write!(
250 f,
251 "{signer_id} does not have enough balance to cover {cost}"
252 ),
253 Self::InvalidNonce {
254 ak_nonce, tx_nonce, ..
255 } => write!(
256 f,
257 "invalid nonce: tx nonce {tx_nonce}, access key nonce {ak_nonce}"
258 ),
259 Self::Expired => write!(f, "transaction has expired"),
260 Self::ShardCongested { shard_id, .. } => write!(f, "shard {shard_id} is congested"),
261 _ => write!(f, "{self:?}"),
262 }
263 }
264}
265
266#[derive(Debug, Clone, Deserialize)]
272pub enum InvalidAccessKeyError {
273 AccessKeyNotFound {
274 account_id: AccountId,
275 public_key: PublicKey,
276 },
277 ReceiverMismatch {
278 ak_receiver: String,
279 tx_receiver: AccountId,
280 },
281 MethodNameMismatch {
282 method_name: String,
283 },
284 RequiresFullAccess,
285 NotEnoughAllowance {
286 account_id: AccountId,
287 allowance: NearToken,
288 cost: NearToken,
289 public_key: PublicKey,
290 },
291 DepositWithFunctionCall,
292}
293
294#[derive(Debug, Clone, Deserialize)]
300pub enum FunctionCallError {
301 WasmUnknownError,
302 #[serde(rename = "_EVMError")]
303 EvmError,
304 CompilationError(CompilationError),
305 LinkError {
306 msg: String,
307 },
308 MethodResolveError(MethodResolveError),
309 WasmTrap(WasmTrap),
310 HostError(HostError),
311 ExecutionError(String),
312}
313
314impl std::fmt::Display for FunctionCallError {
315 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
316 match self {
317 Self::ExecutionError(msg) => write!(f, "execution error: {msg}"),
318 Self::HostError(e) => write!(f, "host error: {e:?}"),
319 Self::WasmTrap(e) => write!(f, "wasm trap: {e:?}"),
320 Self::CompilationError(e) => write!(f, "compilation error: {e:?}"),
321 Self::MethodResolveError(e) => write!(f, "method resolve error: {e:?}"),
322 Self::LinkError { msg } => write!(f, "link error: {msg}"),
323 _ => write!(f, "{self:?}"),
324 }
325 }
326}
327
328#[derive(Debug, Clone, Deserialize)]
330pub enum CompilationError {
331 CodeDoesNotExist { account_id: AccountId },
332 PrepareError(PrepareError),
333 WasmerCompileError { msg: String },
334}
335
336#[derive(Debug, Clone, Deserialize)]
338pub enum PrepareError {
339 Serialization,
340 Deserialization,
341 InternalMemoryDeclared,
342 GasInstrumentation,
343 StackHeightInstrumentation,
344 Instantiate,
345 Memory,
346 TooManyFunctions,
347 TooManyLocals,
348 TooManyTables,
349 TooManyTableElements,
350}
351
352#[derive(Debug, Clone, Deserialize)]
354pub enum MethodResolveError {
355 MethodEmptyName,
356 MethodNotFound,
357 MethodInvalidSignature,
358}
359
360#[derive(Debug, Clone, Deserialize)]
362pub enum WasmTrap {
363 Unreachable,
364 IncorrectCallIndirectSignature,
365 MemoryOutOfBounds,
366 #[serde(rename = "CallIndirectOOB")]
367 CallIndirectOob,
368 IllegalArithmetic,
369 MisalignedAtomicAccess,
370 IndirectCallToNull,
371 StackOverflow,
372 GenericTrap,
373}
374
375#[derive(Debug, Clone, Deserialize)]
377pub enum HostError {
378 #[serde(rename = "BadUTF16")]
379 BadUtf16,
380 #[serde(rename = "BadUTF8")]
381 BadUtf8,
382 GasExceeded,
383 GasLimitExceeded,
384 BalanceExceeded,
385 EmptyMethodName,
386 GuestPanic {
387 panic_msg: String,
388 },
389 IntegerOverflow,
390 InvalidPromiseIndex {
391 promise_idx: u64,
392 },
393 CannotAppendActionToJointPromise,
394 CannotReturnJointPromise,
395 InvalidPromiseResultIndex {
396 result_idx: u64,
397 },
398 InvalidRegisterId {
399 register_id: u64,
400 },
401 IteratorWasInvalidated {
402 iterator_index: u64,
403 },
404 MemoryAccessViolation,
405 InvalidReceiptIndex {
406 receipt_index: u64,
407 },
408 InvalidIteratorIndex {
409 iterator_index: u64,
410 },
411 InvalidAccountId,
412 InvalidMethodName,
413 InvalidPublicKey,
414 ProhibitedInView {
415 method_name: String,
416 },
417 NumberOfLogsExceeded {
418 limit: u64,
419 },
420 KeyLengthExceeded {
421 length: u64,
422 limit: u64,
423 },
424 ValueLengthExceeded {
425 length: u64,
426 limit: u64,
427 },
428 TotalLogLengthExceeded {
429 length: u64,
430 limit: u64,
431 },
432 NumberPromisesExceeded {
433 limit: u64,
434 number_of_promises: u64,
435 },
436 NumberInputDataDependenciesExceeded {
437 limit: u64,
438 number_of_input_data_dependencies: u64,
439 },
440 ReturnedValueLengthExceeded {
441 length: u64,
442 limit: u64,
443 },
444 ContractSizeExceeded {
445 limit: u64,
446 size: u64,
447 },
448 Deprecated {
449 method_name: String,
450 },
451 #[serde(rename = "ECRecoverError")]
452 EcRecoverError {
453 msg: String,
454 },
455 AltBn128InvalidInput {
456 msg: String,
457 },
458 Ed25519VerifyInvalidInput {
459 msg: String,
460 },
461}
462
463#[derive(Debug, Clone, Deserialize)]
469pub enum ActionsValidationError {
470 DeleteActionMustBeFinal,
471 TotalPrepaidGasExceeded {
472 limit: Gas,
473 total_prepaid_gas: Gas,
474 },
475 TotalNumberOfActionsExceeded {
476 limit: u64,
477 total_number_of_actions: u64,
478 },
479 AddKeyMethodNamesNumberOfBytesExceeded {
480 limit: u64,
481 total_number_of_bytes: u64,
482 },
483 AddKeyMethodNameLengthExceeded {
484 length: u64,
485 limit: u64,
486 },
487 IntegerOverflow,
488 InvalidAccountId {
489 account_id: String,
490 },
491 ContractSizeExceeded {
492 limit: u64,
493 size: u64,
494 },
495 FunctionCallMethodNameLengthExceeded {
496 length: u64,
497 limit: u64,
498 },
499 FunctionCallArgumentsLengthExceeded {
500 length: u64,
501 limit: u64,
502 },
503 UnsuitableStakingKey {
504 public_key: PublicKey,
505 },
506 FunctionCallZeroAttachedGas,
507 DelegateActionMustBeOnlyOne,
508 UnsupportedProtocolFeature {
509 protocol_feature: String,
510 version: u32,
511 },
512 InvalidDeterministicStateInitReceiver {
513 derived_id: AccountId,
514 receiver_id: AccountId,
515 },
516 DeterministicStateInitKeyLengthExceeded {
517 length: u64,
518 limit: u64,
519 },
520 DeterministicStateInitValueLengthExceeded {
521 length: u64,
522 limit: u64,
523 },
524 GasKeyInvalidNumNonces {
525 limit: u16,
526 requested_nonces: u16,
527 },
528 AddGasKeyWithNonZeroBalance {
529 balance: NearToken,
530 },
531 GasKeyFunctionCallAllowanceNotAllowed,
532}
533
534#[derive(Debug, Clone, Deserialize)]
540pub enum ReceiptValidationError {
541 InvalidPredecessorId {
542 account_id: String,
543 },
544 InvalidReceiverId {
545 account_id: String,
546 },
547 InvalidSignerId {
548 account_id: String,
549 },
550 InvalidDataReceiverId {
551 account_id: String,
552 },
553 ReturnedValueLengthExceeded {
554 length: u64,
555 limit: u64,
556 },
557 NumberInputDataDependenciesExceeded {
558 limit: u64,
559 number_of_input_data_dependencies: u64,
560 },
561 ActionsValidation(ActionsValidationError),
562 ReceiptSizeExceeded {
563 limit: u64,
564 size: u64,
565 },
566 InvalidRefundTo {
567 account_id: String,
568 },
569}
570
571#[derive(Debug, Clone, Deserialize)]
577pub enum StorageError {
578 StorageInternalError,
579 MissingTrieValue(MissingTrieValue),
580 UnexpectedTrieValue,
581 StorageInconsistentState(String),
582 FlatStorageBlockNotSupported(String),
583 MemTrieLoadingError(String),
584}
585
586#[derive(Debug, Clone, Deserialize)]
588pub struct MissingTrieValue {
589 pub context: MissingTrieValueContext,
590 pub hash: CryptoHash,
591}
592
593#[derive(Debug, Clone, Deserialize)]
595#[allow(clippy::enum_variant_names)] pub enum MissingTrieValueContext {
597 TrieIterator,
598 TriePrefetchingStorage,
599 TrieMemoryPartialStorage,
600 TrieStorage,
601}
602
603#[derive(Debug, Clone, Deserialize)]
609pub enum DepositCostFailureReason {
610 NotEnoughBalance,
611 LackBalanceForState,
612}