Skip to main content

near_primitives/
errors.rs

1use crate::action::GlobalContractIdentifier;
2use crate::hash::CryptoHash;
3use crate::shard_layout::ShardLayoutError;
4use crate::sharding::ChunkHash;
5use crate::types::{AccountId, Balance, EpochId, Nonce, SpiceChunkId};
6use borsh::{BorshDeserialize, BorshSerialize};
7use near_crypto::PublicKey;
8pub use near_primitives_core::errors::IntegerOverflowError;
9use near_primitives_core::types::Gas;
10use near_primitives_core::types::{BlockHeight, NonceIndex, ProtocolVersion, ShardId};
11use near_schema_checker_lib::ProtocolSchema;
12use std::fmt::{Debug, Display};
13use std::io;
14
15/// Error returned in the ExecutionOutcome in case of failure
16#[derive(
17    BorshSerialize,
18    BorshDeserialize,
19    Debug,
20    Clone,
21    PartialEq,
22    Eq,
23    serde::Deserialize,
24    serde::Serialize,
25    ProtocolSchema,
26)]
27#[borsh(use_discriminant = true)]
28#[repr(u8)]
29#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
30pub enum TxExecutionError {
31    /// An error happened during Action execution
32    ActionError(ActionError) = 0,
33    /// An error happened during Transaction execution
34    InvalidTxError(InvalidTxError) = 1,
35}
36
37impl std::error::Error for TxExecutionError {}
38
39impl Display for TxExecutionError {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
41        match self {
42            TxExecutionError::ActionError(e) => write!(f, "{}", e),
43            TxExecutionError::InvalidTxError(e) => write!(f, "{}", e),
44        }
45    }
46}
47
48impl From<ActionError> for TxExecutionError {
49    fn from(error: ActionError) -> Self {
50        TxExecutionError::ActionError(error)
51    }
52}
53
54impl From<InvalidTxError> for TxExecutionError {
55    fn from(error: InvalidTxError) -> Self {
56        TxExecutionError::InvalidTxError(error)
57    }
58}
59
60/// Error returned from `Runtime::apply`
61#[derive(Debug, Clone, PartialEq, Eq)]
62pub enum RuntimeError {
63    /// An unexpected integer overflow occurred. The likely issue is an invalid state or the transition.
64    UnexpectedIntegerOverflow(String),
65    /// An error happened during TX verification and account charging.
66    InvalidTxError(InvalidTxError),
67    /// Unexpected error which is typically related to the node storage corruption.
68    /// It's possible the input state is invalid or malicious.
69    StorageError(StorageError),
70    /// The incoming receipt didn't pass the validation, it's likely a malicious behavior.
71    ReceiptValidationError(ReceiptValidationError),
72    /// Error when accessing validator information. Happens inside epoch manager.
73    ValidatorError(EpochError),
74}
75
76impl std::fmt::Display for RuntimeError {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
78        f.write_str(&format!("{:?}", self))
79    }
80}
81
82impl std::error::Error for RuntimeError {}
83
84/// Contexts in which `StorageError::MissingTrieValue` error might occur.
85#[derive(
86    Debug,
87    Clone,
88    PartialEq,
89    Eq,
90    serde::Deserialize,
91    serde::Serialize,
92    BorshSerialize,
93    BorshDeserialize,
94    ProtocolSchema,
95)]
96#[borsh(use_discriminant = true)]
97#[repr(u8)]
98#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
99pub enum MissingTrieValueContext {
100    /// Missing trie value when reading from TrieIterator.
101    TrieIterator = 0,
102    /// Missing trie value when reading from TriePrefetchingStorage.
103    TriePrefetchingStorage = 1,
104    /// Missing trie value when reading from TrieMemoryPartialStorage.
105    TrieMemoryPartialStorage = 2,
106    /// Missing trie value when reading from TrieStorage.
107    TrieStorage = 3,
108}
109
110impl MissingTrieValueContext {
111    pub fn metrics_label(&self) -> &str {
112        match self {
113            Self::TrieIterator => "trie_iterator",
114            Self::TriePrefetchingStorage => "trie_prefetching_storage",
115            Self::TrieMemoryPartialStorage => "trie_memory_partial_storage",
116            Self::TrieStorage => "trie_storage",
117        }
118    }
119}
120
121#[derive(
122    Debug,
123    Clone,
124    PartialEq,
125    Eq,
126    serde::Deserialize,
127    serde::Serialize,
128    BorshSerialize,
129    BorshDeserialize,
130    ProtocolSchema,
131)]
132#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
133pub struct MissingTrieValue {
134    pub context: MissingTrieValueContext,
135    pub hash: CryptoHash,
136}
137
138/// Errors which may occur during working with trie storages, storing
139/// trie values (trie nodes and state values) by their hashes.
140#[derive(
141    Debug,
142    Clone,
143    PartialEq,
144    Eq,
145    serde::Deserialize,
146    serde::Serialize,
147    BorshSerialize,
148    BorshDeserialize,
149    ProtocolSchema,
150)]
151#[borsh(use_discriminant = true)]
152#[repr(u8)]
153#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
154pub enum StorageError {
155    /// Key-value db internal failure
156    StorageInternalError = 0,
157    /// Requested trie value by its hash which is missing in storage.
158    MissingTrieValue(MissingTrieValue) = 1,
159    /// Found trie node which shouldn't be part of state. Raised during
160    /// validation of state sync parts where incorrect node was passed.
161    /// TODO (#8997): consider including hash of trie node.
162    UnexpectedTrieValue = 2,
163    /// Either invalid state or key-value db is corrupted.
164    /// For PartialStorage it cannot be corrupted.
165    /// Error message is unreliable and for debugging purposes only. It's also probably ok to
166    /// panic in every place that produces this error.
167    /// We can check if db is corrupted by verifying everything in the state trie.
168    StorageInconsistentState(String) = 3,
169    /// Flat storage error, meaning that it doesn't support some block anymore.
170    /// We guarantee that such block cannot become final, thus block processing
171    /// must resume normally.
172    FlatStorageBlockNotSupported(String) = 4,
173    /// In-memory trie could not be loaded for some reason.
174    MemTrieLoadingError(String) = 5,
175}
176
177impl std::fmt::Display for StorageError {
178    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
179        f.write_str(&format!("{:?}", self))
180    }
181}
182
183impl std::error::Error for StorageError {}
184
185/// Reason why a gas key transaction failed at the deposit/account level.
186/// In these cases, gas is still charged from the gas key.
187#[derive(
188    BorshSerialize,
189    BorshDeserialize,
190    Debug,
191    Clone,
192    PartialEq,
193    Eq,
194    serde::Deserialize,
195    serde::Serialize,
196    ProtocolSchema,
197)]
198#[borsh(use_discriminant = true)]
199#[repr(u8)]
200#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
201pub enum DepositCostFailureReason {
202    NotEnoughBalance = 0,
203    LackBalanceForState = 1,
204}
205
206/// An error happened during TX execution
207#[derive(
208    BorshSerialize,
209    BorshDeserialize,
210    Debug,
211    Clone,
212    PartialEq,
213    Eq,
214    serde::Deserialize,
215    serde::Serialize,
216    ProtocolSchema,
217)]
218#[borsh(use_discriminant = true)]
219#[repr(u8)]
220#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
221pub enum InvalidTxError {
222    /// Happens if a wrong AccessKey used or AccessKey has not enough permissions
223    InvalidAccessKeyError(InvalidAccessKeyError) = 0,
224    /// TX signer_id is not a valid [`AccountId`]
225    InvalidSignerId {
226        signer_id: String,
227    } = 1,
228    /// TX signer_id is not found in a storage
229    SignerDoesNotExist {
230        signer_id: AccountId,
231    } = 2,
232    /// Transaction nonce must be strictly greater than `account[access_key].nonce`.
233    InvalidNonce {
234        tx_nonce: Nonce,
235        ak_nonce: Nonce,
236    } = 3,
237    /// Transaction nonce is larger than the upper bound given by the block height
238    NonceTooLarge {
239        tx_nonce: Nonce,
240        upper_bound: Nonce,
241    } = 4,
242    /// TX receiver_id is not a valid AccountId
243    InvalidReceiverId {
244        receiver_id: String,
245    } = 5,
246    /// TX signature is not valid
247    InvalidSignature = 6,
248    /// Account does not have enough balance to cover TX cost
249    NotEnoughBalance {
250        signer_id: AccountId,
251        balance: Balance,
252        cost: Balance,
253    } = 7,
254    /// Signer account doesn't have enough balance after transaction.
255    LackBalanceForState {
256        /// An account which doesn't have enough balance to cover storage.
257        signer_id: AccountId,
258        /// Required balance to cover the state.
259        amount: Balance,
260    } = 8,
261    /// An integer overflow occurred during transaction cost estimation.
262    CostOverflow = 9,
263    /// Transaction parent block hash doesn't belong to the current chain
264    InvalidChain = 10,
265    /// Transaction has expired
266    Expired = 11,
267    /// An error occurred while validating actions of a Transaction.
268    ActionsValidation(ActionsValidationError) = 12,
269    /// The size of serialized transaction exceeded the limit.
270    TransactionSizeExceeded {
271        size: u64,
272        limit: u64,
273    } = 13,
274    /// Transaction version is invalid.
275    InvalidTransactionVersion = 14,
276    // Error occurred during storage access
277    StorageError(StorageError) = 15,
278    /// The receiver shard of the transaction is too congested to accept new
279    /// transactions at the moment.
280    ShardCongested {
281        /// The congested shard.
282        shard_id: u32,
283        /// A value between 0 (no congestion) and 1 (max congestion).
284        #[cfg_attr(feature = "schemars", schemars(with = "f64"))]
285        congestion_level: ordered_float::NotNan<f64>,
286    } = 16,
287    /// The receiver shard of the transaction missed several chunks and rejects
288    /// new transaction until it can make progress again.
289    ShardStuck {
290        /// The shard that fails making progress.
291        shard_id: u32,
292        /// The number of blocks since the last included chunk of the shard.
293        missed_chunks: u64,
294    } = 17,
295    /// Transaction is specifying an invalid nonce index. Gas key transactions
296    /// must have a nonce_index in valid range, regular transactions must not.
297    InvalidNonceIndex {
298        /// The nonce_index from the transaction (None if missing).
299        tx_nonce_index: Option<NonceIndex>,
300        /// Number of nonces supported by the key. 0 means no nonce_index allowed (regular key).
301        num_nonces: NonceIndex,
302    } = 18,
303    /// Gas key does not have enough balance to cover gas costs.
304    NotEnoughGasKeyBalance {
305        signer_id: AccountId,
306        balance: Balance,
307        cost: Balance,
308    } = 19,
309    /// Gas key transaction failed because the account could not cover the deposit cost.
310    /// Gas is still charged from the gas key in this case.
311    NotEnoughBalanceForDeposit {
312        signer_id: AccountId,
313        balance: Balance,
314        cost: Balance,
315        reason: DepositCostFailureReason,
316    } = 20,
317}
318
319impl From<StorageError> for InvalidTxError {
320    fn from(error: StorageError) -> Self {
321        InvalidTxError::StorageError(error)
322    }
323}
324
325impl std::error::Error for InvalidTxError {}
326
327#[derive(
328    BorshSerialize,
329    BorshDeserialize,
330    Debug,
331    Clone,
332    PartialEq,
333    Eq,
334    serde::Deserialize,
335    serde::Serialize,
336    ProtocolSchema,
337)]
338#[borsh(use_discriminant = true)]
339#[repr(u8)]
340#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
341pub enum InvalidAccessKeyError {
342    /// The access key identified by the `public_key` doesn't exist for the account
343    AccessKeyNotFound { account_id: AccountId, public_key: Box<PublicKey> } = 0,
344    /// Transaction `receiver_id` doesn't match the access key receiver_id
345    ReceiverMismatch { tx_receiver: AccountId, ak_receiver: String } = 1,
346    /// Transaction method name isn't allowed by the access key
347    MethodNameMismatch { method_name: String } = 2,
348    /// Transaction requires a full permission access key.
349    RequiresFullAccess = 3,
350    /// Access Key does not have enough allowance to cover transaction cost
351    NotEnoughAllowance {
352        account_id: AccountId,
353        public_key: Box<PublicKey>,
354        allowance: Balance,
355        cost: Balance,
356    } = 4,
357    /// Having a deposit with a function call action is not allowed with a function call access key.
358    DepositWithFunctionCall = 5,
359    /// Gas keys track nonces per index in dedicated storage, which a plain
360    /// access key nonce does not select, so a gas key must sign a `DelegateV2`
361    /// with a gas key nonce instead.
362    DelegateActionRequiresNonGasKey = 6,
363    /// A delegate action with a gas key nonce must be signed by a gas key.
364    DelegateActionRequiresGasKey = 7,
365}
366
367/// Describes the error for validating a list of actions.
368#[derive(
369    BorshSerialize,
370    BorshDeserialize,
371    Debug,
372    Clone,
373    PartialEq,
374    Eq,
375    serde::Serialize,
376    serde::Deserialize,
377    ProtocolSchema,
378)]
379#[borsh(use_discriminant = true)]
380#[repr(u8)]
381#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
382pub enum ActionsValidationError {
383    /// The delete action must be a final action in transaction
384    DeleteActionMustBeFinal = 0,
385    /// The total prepaid gas (for all given actions) exceeded the limit.
386    TotalPrepaidGasExceeded {
387        total_prepaid_gas: Gas,
388        limit: Gas,
389    } = 1,
390    /// The number of actions exceeded the given limit.
391    TotalNumberOfActionsExceeded {
392        total_number_of_actions: u64,
393        limit: u64,
394    } = 2,
395    /// The total number of bytes of the method names exceeded the limit in a Add Key action.
396    AddKeyMethodNamesNumberOfBytesExceeded {
397        total_number_of_bytes: u64,
398        limit: u64,
399    } = 3,
400    /// The length of some method name exceeded the limit in a Add Key action.
401    AddKeyMethodNameLengthExceeded {
402        length: u64,
403        limit: u64,
404    } = 4,
405    /// Integer overflow during a compute.
406    IntegerOverflow = 5,
407    /// Invalid account ID.
408    InvalidAccountId {
409        account_id: String,
410    } = 6,
411    /// The size of the contract code exceeded the limit in a DeployContract action.
412    ContractSizeExceeded {
413        size: u64,
414        limit: u64,
415    } = 7,
416    /// The length of the method name exceeded the limit in a Function Call action.
417    FunctionCallMethodNameLengthExceeded {
418        length: u64,
419        limit: u64,
420    } = 8,
421    /// The length of the arguments exceeded the limit in a Function Call action.
422    FunctionCallArgumentsLengthExceeded {
423        length: u64,
424        limit: u64,
425    } = 9,
426    /// An attempt to stake with a public key that is not convertible to ristretto.
427    UnsuitableStakingKey {
428        public_key: Box<PublicKey>,
429    } = 10,
430    /// The attached amount of gas in a FunctionCall action has to be a positive number.
431    FunctionCallZeroAttachedGas = 11,
432    /// There should be the only one DelegateAction
433    DelegateActionMustBeOnlyOne = 12,
434    /// The transaction includes a feature that the current protocol version
435    /// does not support.
436    ///
437    /// Note: we stringify the protocol feature name instead of using
438    /// `ProtocolFeature` here because we don't want to leak the internals of
439    /// that type into observable borsh serialization.
440    UnsupportedProtocolFeature {
441        protocol_feature: String,
442        version: ProtocolVersion,
443    } = 13,
444    InvalidDeterministicStateInitReceiver {
445        receiver_id: AccountId,
446        derived_id: AccountId,
447    } = 14,
448    DeterministicStateInitKeyLengthExceeded {
449        length: u64,
450        limit: u64,
451    } = 15,
452    DeterministicStateInitValueLengthExceeded {
453        length: u64,
454        limit: u64,
455    } = 16,
456    GasKeyInvalidNumNonces {
457        requested_nonces: NonceIndex,
458        limit: NonceIndex,
459    } = 17,
460    AddGasKeyWithNonZeroBalance {
461        balance: Balance,
462    } = 18,
463    /// Gas keys with FunctionCall permission cannot have an allowance set.
464    GasKeyFunctionCallAllowanceNotAllowed = 19,
465    /// The combined number of `DeployContract` and `DeployGlobalContract`
466    /// actions in one receipt exceeded the limit.
467    TotalNumberOfDeployActionsExceeded {
468        number_of_deploy_actions: u64,
469        limit: u64,
470    } = 20,
471}
472
473/// Describes the error for validating a receipt.
474#[derive(
475    BorshSerialize,
476    BorshDeserialize,
477    Debug,
478    Clone,
479    PartialEq,
480    Eq,
481    serde::Serialize,
482    serde::Deserialize,
483    ProtocolSchema,
484)]
485#[borsh(use_discriminant = true)]
486#[repr(u8)]
487#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
488pub enum ReceiptValidationError {
489    /// The `predecessor_id` of a Receipt is not valid.
490    InvalidPredecessorId { account_id: String } = 0,
491    /// The `receiver_id` of a Receipt is not valid.
492    InvalidReceiverId { account_id: String } = 1,
493    /// The `signer_id` of an ActionReceipt is not valid.
494    InvalidSignerId { account_id: String } = 2,
495    /// The `receiver_id` of a DataReceiver within an ActionReceipt is not valid.
496    InvalidDataReceiverId { account_id: String } = 3,
497    /// The length of the returned data exceeded the limit in a DataReceipt.
498    ReturnedValueLengthExceeded { length: u64, limit: u64 } = 4,
499    /// The number of input data dependencies exceeds the limit in an ActionReceipt.
500    NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 } = 5,
501    /// An error occurred while validating actions of an ActionReceipt.
502    ActionsValidation(ActionsValidationError) = 6,
503    /// Receipt is bigger than the limit.
504    ReceiptSizeExceeded { size: u64, limit: u64 } = 7,
505    /// The `refund_to` of an ActionReceipt is not valid.
506    InvalidRefundTo { account_id: String } = 8,
507}
508
509impl Display for ReceiptValidationError {
510    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
511        match self {
512            ReceiptValidationError::InvalidPredecessorId { account_id } => {
513                write!(f, "The predecessor_id `{}` of a Receipt is not valid.", account_id)
514            }
515            ReceiptValidationError::InvalidReceiverId { account_id } => {
516                write!(f, "The receiver_id `{}` of a Receipt is not valid.", account_id)
517            }
518            ReceiptValidationError::InvalidSignerId { account_id } => {
519                write!(f, "The signer_id `{}` of an ActionReceipt is not valid.", account_id)
520            }
521            ReceiptValidationError::InvalidDataReceiverId { account_id } => write!(
522                f,
523                "The receiver_id `{}` of a DataReceiver within an ActionReceipt is not valid.",
524                account_id
525            ),
526            ReceiptValidationError::ReturnedValueLengthExceeded { length, limit } => write!(
527                f,
528                "The length of the returned data {} exceeded the limit {} in a DataReceipt",
529                length, limit
530            ),
531            ReceiptValidationError::NumberInputDataDependenciesExceeded {
532                number_of_input_data_dependencies,
533                limit,
534            } => write!(
535                f,
536                "The number of input data dependencies {} exceeded the limit {} in an ActionReceipt",
537                number_of_input_data_dependencies, limit
538            ),
539            ReceiptValidationError::ActionsValidation(e) => write!(f, "{}", e),
540            ReceiptValidationError::ReceiptSizeExceeded { size, limit } => {
541                write!(f, "The size of the receipt exceeded the limit: {} > {}", size, limit)
542            }
543            ReceiptValidationError::InvalidRefundTo { account_id } => {
544                write!(f, "The refund_to `{}` of an ActionReceipt is not valid.", account_id)
545            }
546        }
547    }
548}
549
550impl std::error::Error for ReceiptValidationError {}
551
552impl Display for ActionsValidationError {
553    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
554        match self {
555            ActionsValidationError::DeleteActionMustBeFinal => {
556                write!(f, "The delete action must be the last action in transaction")
557            }
558            ActionsValidationError::TotalPrepaidGasExceeded { total_prepaid_gas, limit } => {
559                write!(f, "The total prepaid gas {} exceeds the limit {}", total_prepaid_gas, limit)
560            }
561            ActionsValidationError::TotalNumberOfActionsExceeded {
562                total_number_of_actions,
563                limit,
564            } => {
565                write!(
566                    f,
567                    "The total number of actions {} exceeds the limit {}",
568                    total_number_of_actions, limit
569                )
570            }
571            ActionsValidationError::AddKeyMethodNamesNumberOfBytesExceeded {
572                total_number_of_bytes,
573                limit,
574            } => write!(
575                f,
576                "The total number of bytes in allowed method names {} exceeds the maximum allowed number {} in a AddKey action",
577                total_number_of_bytes, limit
578            ),
579            ActionsValidationError::AddKeyMethodNameLengthExceeded { length, limit } => write!(
580                f,
581                "The length of some method name {} exceeds the maximum allowed length {} in a AddKey action",
582                length, limit
583            ),
584            ActionsValidationError::IntegerOverflow => {
585                write!(f, "Integer overflow during a compute",)
586            }
587            ActionsValidationError::InvalidAccountId { account_id } => {
588                write!(f, "Invalid account ID `{}`", account_id)
589            }
590            ActionsValidationError::ContractSizeExceeded { size, limit } => write!(
591                f,
592                "The length of the contract size {} exceeds the maximum allowed size {} in a DeployContract action",
593                size, limit
594            ),
595            ActionsValidationError::FunctionCallMethodNameLengthExceeded { length, limit } => {
596                write!(
597                    f,
598                    "The length of the method name {} exceeds the maximum allowed length {} in a FunctionCall action",
599                    length, limit
600                )
601            }
602            ActionsValidationError::FunctionCallArgumentsLengthExceeded { length, limit } => {
603                write!(
604                    f,
605                    "The length of the arguments {} exceeds the maximum allowed length {} in a FunctionCall action",
606                    length, limit
607                )
608            }
609            ActionsValidationError::UnsuitableStakingKey { public_key } => write!(
610                f,
611                "The staking key must be ristretto compatible ED25519 key. {} is provided instead.",
612                public_key,
613            ),
614            ActionsValidationError::FunctionCallZeroAttachedGas => write!(
615                f,
616                "The attached amount of gas in a FunctionCall action has to be a positive number",
617            ),
618            ActionsValidationError::DelegateActionMustBeOnlyOne => {
619                write!(f, "The actions can contain the ony one DelegateAction")
620            }
621            ActionsValidationError::UnsupportedProtocolFeature { protocol_feature, version } => {
622                write!(
623                    f,
624                    "Transaction requires protocol feature {} / version {} which is not supported by the current protocol version",
625                    protocol_feature, version,
626                )
627            }
628            ActionsValidationError::InvalidDeterministicStateInitReceiver {
629                receiver_id,
630                derived_id,
631            } => {
632                write!(
633                    f,
634                    "DeterministicStateInit action payload is invalid for account {receiver_id}, derived id is {derived_id}",
635                )
636            }
637            ActionsValidationError::DeterministicStateInitKeyLengthExceeded { length, limit } => {
638                write!(
639                    f,
640                    "DeterministicStateInit contains key of length {length} but at most {limit} is allowed",
641                )
642            }
643            ActionsValidationError::DeterministicStateInitValueLengthExceeded { length, limit } => {
644                write!(
645                    f,
646                    "DeterministicStateInit contains value of length {length} but at most {limit} is allowed",
647                )
648            }
649            ActionsValidationError::GasKeyInvalidNumNonces { requested_nonces, limit } => {
650                write!(
651                    f,
652                    "gas key requested invalid number of nonces: {} (must be between 1 and {})",
653                    requested_nonces, limit
654                )
655            }
656            ActionsValidationError::AddGasKeyWithNonZeroBalance { balance } => {
657                write!(
658                    f,
659                    "Adding a gas key with non-zero balance is not allowed: balance = {}",
660                    balance
661                )
662            }
663            ActionsValidationError::GasKeyFunctionCallAllowanceNotAllowed => {
664                write!(f, "Gas keys with FunctionCall permission cannot have an allowance set")
665            }
666            ActionsValidationError::TotalNumberOfDeployActionsExceeded {
667                number_of_deploy_actions,
668                limit,
669            } => write!(
670                f,
671                "The total number of deploy actions {} exceeds the per-receipt limit {}",
672                number_of_deploy_actions, limit
673            ),
674        }
675    }
676}
677
678impl std::error::Error for ActionsValidationError {}
679
680/// An error happened during Action execution
681#[derive(
682    BorshSerialize,
683    BorshDeserialize,
684    Debug,
685    Clone,
686    PartialEq,
687    Eq,
688    serde::Deserialize,
689    serde::Serialize,
690    ProtocolSchema,
691)]
692#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
693pub struct ActionError {
694    /// Index of the failed action in the transaction.
695    /// Action index is not defined if ActionError.kind is `ActionErrorKind::LackBalanceForState`
696    pub index: Option<u64>,
697    /// The kind of ActionError happened
698    pub kind: ActionErrorKind,
699}
700
701impl std::error::Error for ActionError {}
702
703#[derive(
704    BorshSerialize,
705    BorshDeserialize,
706    Debug,
707    Clone,
708    PartialEq,
709    Eq,
710    serde::Deserialize,
711    serde::Serialize,
712    ProtocolSchema,
713)]
714#[borsh(use_discriminant = true)]
715#[repr(u8)]
716#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
717pub enum ActionErrorKind {
718    /// Happens when CreateAccount action tries to create an account with account_id which is already exists in the storage
719    AccountAlreadyExists {
720        account_id: AccountId,
721    } = 0,
722    /// Happens when TX receiver_id doesn't exist (but action is not Action::CreateAccount)
723    AccountDoesNotExist {
724        account_id: AccountId,
725    } = 1,
726    /// A top-level account ID can only be created by registrar.
727    CreateAccountOnlyByRegistrar {
728        account_id: AccountId,
729        registrar_account_id: AccountId,
730        predecessor_id: AccountId,
731    } = 2,
732
733    /// A newly created account must be under a namespace of the creator account
734    CreateAccountNotAllowed {
735        account_id: AccountId,
736        predecessor_id: AccountId,
737    } = 3,
738    /// Administrative actions like `DeployContract`, `Stake`, `AddKey`, `DeleteKey`. can be proceed only if sender=receiver
739    /// or the first TX action is a `CreateAccount` action
740    ActorNoPermission {
741        account_id: AccountId,
742        actor_id: AccountId,
743    } = 4,
744    /// Account tries to remove an access key that doesn't exist
745    DeleteKeyDoesNotExist {
746        account_id: AccountId,
747        public_key: Box<PublicKey>,
748    } = 5,
749    /// The public key is already used for an existing access key
750    AddKeyAlreadyExists {
751        account_id: AccountId,
752        public_key: Box<PublicKey>,
753    } = 6,
754    /// Account is staking and can not be deleted
755    DeleteAccountStaking {
756        account_id: AccountId,
757    } = 7,
758    /// ActionReceipt can't be completed, because the remaining balance will not be enough to cover storage.
759    LackBalanceForState {
760        /// An account which needs balance
761        account_id: AccountId,
762        /// Balance required to complete an action.
763        amount: Balance,
764    } = 8,
765    /// Account is not yet staked, but tries to unstake
766    TriesToUnstake {
767        account_id: AccountId,
768    } = 9,
769    /// The account doesn't have enough balance to increase the stake.
770    TriesToStake {
771        account_id: AccountId,
772        stake: Balance,
773        locked: Balance,
774        balance: Balance,
775    } = 10,
776    InsufficientStake {
777        account_id: AccountId,
778        stake: Balance,
779        minimum_stake: Balance,
780    } = 11,
781    /// An error occurred during a `FunctionCall` Action, parameter is debug message.
782    FunctionCallError(FunctionCallError) = 12,
783    /// Error occurs when a new `ActionReceipt` created by the `FunctionCall` action fails
784    /// receipt validation.
785    NewReceiptValidationError(ReceiptValidationError) = 13,
786    /// Error occurs when a `CreateAccount` action is called on a NEAR-implicit or ETH-implicit account.
787    /// See NEAR-implicit account creation NEP: <https://github.com/nearprotocol/NEPs/pull/71>.
788    /// Also, see ETH-implicit account creation NEP: <https://github.com/near/NEPs/issues/518>.
789    ///
790    /// TODO(#8598): This error is named very poorly. A better name would be
791    /// `OnlyNamedAccountCreationAllowed`.
792    OnlyImplicitAccountCreationAllowed {
793        account_id: AccountId,
794    } = 14,
795    /// Delete account whose state is large is temporarily banned.
796    DeleteAccountWithLargeState {
797        account_id: AccountId,
798    } = 15,
799    /// Signature does not match the provided actions and given signer public key.
800    DelegateActionInvalidSignature = 16,
801    /// Receiver of the transaction doesn't match Sender of the delegate action
802    DelegateActionSenderDoesNotMatchTxReceiver {
803        sender_id: AccountId,
804        receiver_id: AccountId,
805    } = 17,
806    /// Delegate action has expired. `max_block_height` is less than actual block height.
807    DelegateActionExpired = 18,
808    /// The given public key doesn't exist for Sender account
809    DelegateActionAccessKeyError(InvalidAccessKeyError) = 19,
810    /// DelegateAction nonce must be greater sender[public_key].nonce
811    DelegateActionInvalidNonce {
812        delegate_nonce: Nonce,
813        ak_nonce: Nonce,
814    } = 20,
815    /// DelegateAction nonce is larger than the upper bound given by the block height
816    DelegateActionNonceTooLarge {
817        delegate_nonce: Nonce,
818        upper_bound: Nonce,
819    } = 21,
820    GlobalContractDoesNotExist {
821        identifier: GlobalContractIdentifier,
822    } = 22,
823    /// Gas key does not exist for the specified public key
824    GasKeyDoesNotExist {
825        account_id: AccountId,
826        public_key: Box<PublicKey>,
827    } = 23,
828    /// Gas key does not have sufficient balance for the requested withdrawal
829    InsufficientGasKeyBalance {
830        account_id: AccountId,
831        public_key: Box<PublicKey>,
832        balance: Balance,
833        required: Balance,
834    } = 24,
835    /// Gas key balance is too high to burn during deletion
836    GasKeyBalanceTooHigh {
837        account_id: AccountId,
838        /// Set for DeleteKey (specific key), None for DeleteAccount (aggregate)
839        public_key: Option<Box<PublicKey>>,
840        balance: Balance,
841    } = 25,
842    /// DelegateAction nonce index is outside the gas key's nonce range
843    DelegateActionInvalidNonceIndex {
844        nonce_index: NonceIndex,
845        num_nonces: NonceIndex,
846    } = 26,
847}
848
849impl From<ActionErrorKind> for ActionError {
850    fn from(e: ActionErrorKind) -> ActionError {
851        ActionError { index: None, kind: e }
852    }
853}
854
855impl Display for InvalidTxError {
856    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
857        match self {
858            InvalidTxError::InvalidSignerId { signer_id } => {
859                write!(f, "Invalid signer account ID {:?} according to requirements", signer_id)
860            }
861            InvalidTxError::SignerDoesNotExist { signer_id } => {
862                write!(f, "Signer {:?} does not exist", signer_id)
863            }
864            InvalidTxError::InvalidAccessKeyError(access_key_error) => {
865                Display::fmt(&access_key_error, f)
866            }
867            InvalidTxError::InvalidNonce { tx_nonce, ak_nonce } => write!(
868                f,
869                "Transaction nonce {} must be larger than nonce of the used access key {}",
870                tx_nonce, ak_nonce
871            ),
872            InvalidTxError::InvalidReceiverId { receiver_id } => {
873                write!(f, "Invalid receiver account ID {:?} according to requirements", receiver_id)
874            }
875            InvalidTxError::InvalidSignature => {
876                write!(f, "Transaction is not signed with the given public key")
877            }
878            InvalidTxError::NotEnoughBalance { signer_id, balance, cost } => write!(
879                f,
880                "Sender {:?} does not have enough balance {} for operation costing {}",
881                signer_id, balance, cost
882            ),
883            InvalidTxError::LackBalanceForState { signer_id, amount } => {
884                write!(
885                    f,
886                    "Failed to execute, because the account {:?} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more",
887                    signer_id, amount
888                )
889            }
890            InvalidTxError::CostOverflow => {
891                write!(f, "Transaction gas or balance cost is too high")
892            }
893            InvalidTxError::InvalidChain => {
894                write!(f, "Transaction parent block hash doesn't belong to the current chain")
895            }
896            InvalidTxError::Expired => {
897                write!(f, "Transaction has expired")
898            }
899            InvalidTxError::ActionsValidation(error) => {
900                write!(f, "Transaction actions validation error: {}", error)
901            }
902            InvalidTxError::NonceTooLarge { tx_nonce, upper_bound } => {
903                write!(
904                    f,
905                    "Transaction nonce {} must be smaller than the access key nonce upper bound {}",
906                    tx_nonce, upper_bound
907                )
908            }
909            InvalidTxError::TransactionSizeExceeded { size, limit } => {
910                write!(f, "Size of serialized transaction {} exceeded the limit {}", size, limit)
911            }
912            InvalidTxError::InvalidTransactionVersion => {
913                write!(f, "Transaction version is invalid")
914            }
915            InvalidTxError::StorageError(error) => {
916                write!(f, "Storage error: {}", error)
917            }
918            InvalidTxError::ShardCongested { shard_id, congestion_level } => {
919                write!(
920                    f,
921                    "Shard {shard_id} is currently at congestion level {congestion_level:.3} and rejects new transactions."
922                )
923            }
924            InvalidTxError::ShardStuck { shard_id, missed_chunks } => {
925                write!(
926                    f,
927                    "Shard {shard_id} missed {missed_chunks} chunks and rejects new transactions."
928                )
929            }
930            InvalidTxError::InvalidNonceIndex { tx_nonce_index, num_nonces } => {
931                write!(f, "Invalid nonce_index {tx_nonce_index:?} for key with {num_nonces} nonces")
932            }
933            InvalidTxError::NotEnoughGasKeyBalance { signer_id, balance, cost } => write!(
934                f,
935                "Gas key for {:?} does not have enough balance {} for gas cost {}",
936                signer_id, balance, cost
937            ),
938            InvalidTxError::NotEnoughBalanceForDeposit { signer_id, balance, cost, reason } => {
939                match reason {
940                    DepositCostFailureReason::NotEnoughBalance => write!(
941                        f,
942                        "Sender {:?} does not have enough balance {} to cover deposit cost {}",
943                        signer_id, balance, cost
944                    ),
945                    DepositCostFailureReason::LackBalanceForState => write!(
946                        f,
947                        "Sender {:?} would not have enough balance for storage after covering deposit (required {} more)",
948                        signer_id, cost
949                    ),
950                }
951            }
952        }
953    }
954}
955
956impl From<InvalidAccessKeyError> for InvalidTxError {
957    fn from(error: InvalidAccessKeyError) -> Self {
958        InvalidTxError::InvalidAccessKeyError(error)
959    }
960}
961
962impl Display for InvalidAccessKeyError {
963    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
964        match self {
965            InvalidAccessKeyError::AccessKeyNotFound { account_id, public_key } => write!(
966                f,
967                "Signer {:?} doesn't have access key with the given public_key {}",
968                account_id, public_key
969            ),
970            InvalidAccessKeyError::ReceiverMismatch { tx_receiver, ak_receiver } => write!(
971                f,
972                "Transaction receiver_id {:?} doesn't match the access key receiver_id {:?}",
973                tx_receiver, ak_receiver
974            ),
975            InvalidAccessKeyError::MethodNameMismatch { method_name } => write!(
976                f,
977                "Transaction method name {:?} isn't allowed by the access key",
978                method_name
979            ),
980            InvalidAccessKeyError::RequiresFullAccess => {
981                write!(
982                    f,
983                    "Invalid access key type. Full-access keys are required for transactions that have multiple or non-function-call actions"
984                )
985            }
986            InvalidAccessKeyError::NotEnoughAllowance {
987                account_id,
988                public_key,
989                allowance,
990                cost,
991            } => write!(
992                f,
993                "Access Key {:?}:{} does not have enough balance {} for transaction costing {}",
994                account_id, public_key, allowance, cost
995            ),
996            InvalidAccessKeyError::DepositWithFunctionCall => {
997                write!(
998                    f,
999                    "Having a deposit with a function call action is not allowed with a function call access key."
1000                )
1001            }
1002            InvalidAccessKeyError::DelegateActionRequiresGasKey => {
1003                write!(f, "Gas key delegate action requires a gas key")
1004            }
1005            InvalidAccessKeyError::DelegateActionRequiresNonGasKey => {
1006                write!(
1007                    f,
1008                    "Gas keys can't sign a delegate action with a plain nonce; use a DelegateV2 with a gas key nonce"
1009                )
1010            }
1011        }
1012    }
1013}
1014
1015impl std::error::Error for InvalidAccessKeyError {}
1016
1017impl From<IntegerOverflowError> for InvalidTxError {
1018    fn from(_: IntegerOverflowError) -> Self {
1019        InvalidTxError::CostOverflow
1020    }
1021}
1022
1023impl From<IntegerOverflowError> for RuntimeError {
1024    fn from(err: IntegerOverflowError) -> Self {
1025        RuntimeError::UnexpectedIntegerOverflow(err.to_string())
1026    }
1027}
1028
1029impl From<StorageError> for RuntimeError {
1030    fn from(e: StorageError) -> Self {
1031        RuntimeError::StorageError(e)
1032    }
1033}
1034
1035impl From<InvalidTxError> for RuntimeError {
1036    fn from(e: InvalidTxError) -> Self {
1037        RuntimeError::InvalidTxError(e)
1038    }
1039}
1040
1041impl From<EpochError> for RuntimeError {
1042    fn from(e: EpochError) -> Self {
1043        RuntimeError::ValidatorError(e)
1044    }
1045}
1046
1047impl Display for ActionError {
1048    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1049        write!(f, "Action #{}: {}", self.index.unwrap_or_default(), self.kind)
1050    }
1051}
1052
1053impl Display for ActionErrorKind {
1054    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1055        match self {
1056            ActionErrorKind::AccountAlreadyExists { account_id } => {
1057                write!(f, "Can't create a new account {:?}, because it already exists", account_id)
1058            }
1059            ActionErrorKind::AccountDoesNotExist { account_id } => write!(
1060                f,
1061                "Can't complete the action because account {:?} doesn't exist",
1062                account_id
1063            ),
1064            ActionErrorKind::ActorNoPermission { actor_id, account_id } => write!(
1065                f,
1066                "Actor {:?} doesn't have permission to account {:?} to complete the action",
1067                actor_id, account_id
1068            ),
1069            ActionErrorKind::LackBalanceForState { account_id, amount } => write!(
1070                f,
1071                "The account {} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more",
1072                account_id, amount
1073            ),
1074            ActionErrorKind::TriesToUnstake { account_id } => {
1075                write!(f, "Account {:?} is not yet staked, but tries to unstake", account_id)
1076            }
1077            ActionErrorKind::TriesToStake { account_id, stake, locked, balance } => write!(
1078                f,
1079                "Account {:?} tries to stake {}, but has staked {} and only has {}",
1080                account_id, stake, locked, balance
1081            ),
1082            ActionErrorKind::CreateAccountOnlyByRegistrar {
1083                account_id,
1084                registrar_account_id,
1085                predecessor_id,
1086            } => write!(
1087                f,
1088                "A top-level account ID {:?} can't be created by {:?}, short top-level account IDs can only be created by {:?}",
1089                account_id, predecessor_id, registrar_account_id,
1090            ),
1091            ActionErrorKind::CreateAccountNotAllowed { account_id, predecessor_id } => write!(
1092                f,
1093                "A sub-account ID {:?} can't be created by account {:?}",
1094                account_id, predecessor_id,
1095            ),
1096            ActionErrorKind::DeleteKeyDoesNotExist { account_id, .. } => write!(
1097                f,
1098                "Account {:?} tries to remove an access key that doesn't exist",
1099                account_id
1100            ),
1101            ActionErrorKind::AddKeyAlreadyExists { public_key, .. } => write!(
1102                f,
1103                "The public key {:?} is already used for an existing access key",
1104                public_key
1105            ),
1106            ActionErrorKind::DeleteAccountStaking { account_id } => {
1107                write!(f, "Account {:?} is staking and can not be deleted", account_id)
1108            }
1109            ActionErrorKind::FunctionCallError(s) => write!(f, "{:?}", s),
1110            ActionErrorKind::NewReceiptValidationError(e) => {
1111                write!(f, "An new action receipt created during a FunctionCall is not valid: {}", e)
1112            }
1113            ActionErrorKind::InsufficientStake { account_id, stake, minimum_stake } => write!(
1114                f,
1115                "Account {} tries to stake {} but minimum required stake is {}",
1116                account_id, stake, minimum_stake
1117            ),
1118            ActionErrorKind::OnlyImplicitAccountCreationAllowed { account_id } => write!(
1119                f,
1120                "CreateAccount action is called on hex-characters account of length 64 {}",
1121                account_id
1122            ),
1123            ActionErrorKind::DeleteAccountWithLargeState { account_id } => write!(
1124                f,
1125                "The state of account {} is too large and therefore cannot be deleted",
1126                account_id
1127            ),
1128            ActionErrorKind::DelegateActionInvalidSignature => {
1129                write!(f, "DelegateAction is not signed with the given public key")
1130            }
1131            ActionErrorKind::DelegateActionSenderDoesNotMatchTxReceiver {
1132                sender_id,
1133                receiver_id,
1134            } => write!(
1135                f,
1136                "Transaction receiver {} doesn't match DelegateAction sender {}",
1137                receiver_id, sender_id
1138            ),
1139            ActionErrorKind::DelegateActionExpired => write!(f, "DelegateAction has expired"),
1140            ActionErrorKind::DelegateActionAccessKeyError(access_key_error) => {
1141                Display::fmt(&access_key_error, f)
1142            }
1143            ActionErrorKind::DelegateActionInvalidNonce { delegate_nonce, ak_nonce } => write!(
1144                f,
1145                "DelegateAction nonce {} must be larger than nonce of the used access key {}",
1146                delegate_nonce, ak_nonce
1147            ),
1148            ActionErrorKind::DelegateActionNonceTooLarge { delegate_nonce, upper_bound } => write!(
1149                f,
1150                "DelegateAction nonce {} must be smaller than the access key nonce upper bound {}",
1151                delegate_nonce, upper_bound
1152            ),
1153            ActionErrorKind::DelegateActionInvalidNonceIndex { nonce_index, num_nonces } => write!(
1154                f,
1155                "DelegateAction nonce index {} must be smaller than the gas key nonce count {}",
1156                nonce_index, num_nonces
1157            ),
1158            ActionErrorKind::GlobalContractDoesNotExist { identifier } => {
1159                write!(f, "Global contract identifier {:?} not found", identifier)
1160            }
1161            ActionErrorKind::GasKeyDoesNotExist { account_id, public_key } => {
1162                write!(f, "Gas key {} does not exist for account {}", public_key, account_id)
1163            }
1164            ActionErrorKind::InsufficientGasKeyBalance {
1165                account_id,
1166                public_key,
1167                balance,
1168                required,
1169            } => {
1170                write!(
1171                    f,
1172                    "Gas key {} for account {} has insufficient balance: {} available, {} required",
1173                    public_key, account_id, balance, required
1174                )
1175            }
1176            ActionErrorKind::GasKeyBalanceTooHigh { account_id, public_key, balance } => {
1177                if let Some(pk) = public_key {
1178                    write!(
1179                        f,
1180                        "Gas key {} for account {} has balance {} which is too high to burn on deletion",
1181                        pk, account_id, balance
1182                    )
1183                } else {
1184                    write!(
1185                        f,
1186                        "Account {} has total gas key balance {} which is too high to burn on deletion",
1187                        account_id, balance
1188                    )
1189                }
1190            }
1191        }
1192    }
1193}
1194
1195#[derive(Eq, PartialEq, Clone)]
1196pub enum EpochError {
1197    /// Error calculating threshold from given stakes for given number of seats.
1198    /// Only should happened if calling code doesn't check for integer value of stake > number of seats.
1199    ThresholdError {
1200        stake_sum: Balance,
1201        num_seats: u64,
1202    },
1203    /// Requesting validators for an epoch that wasn't computed yet.
1204    EpochOutOfBounds(EpochId),
1205    /// Missing block hash in the storage (means there is some structural issue).
1206    MissingBlock(CryptoHash),
1207    /// Error due to IO (DB read/write, serialization, etc.).
1208    IOErr(String),
1209    /// Given account ID is not a validator in the given epoch ID.
1210    NotAValidator(AccountId, EpochId),
1211    /// Error getting information for a shard
1212    ShardingError(String),
1213    NotEnoughValidators {
1214        num_validators: u64,
1215        num_shards: u64,
1216    },
1217    /// Error selecting validators for a chunk.
1218    ChunkValidatorSelectionError(String),
1219    /// Error selecting chunk producer for a shard.
1220    ChunkProducerSelectionError(String),
1221    /// Chunk producer entry not found in the ChunkProducers DB column.
1222    /// This is transient during initial sync — the entry is populated when
1223    /// the parent block is processed.
1224    ChunkProducerNotInDB(CryptoHash, ShardId),
1225}
1226
1227impl std::error::Error for EpochError {}
1228
1229impl Display for EpochError {
1230    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1231        match self {
1232            EpochError::ThresholdError { stake_sum, num_seats } => write!(
1233                f,
1234                "Total stake {} must be higher than the number of seats {}",
1235                stake_sum, num_seats
1236            ),
1237            EpochError::EpochOutOfBounds(epoch_id) => {
1238                write!(f, "Epoch {:?} is out of bounds", epoch_id)
1239            }
1240            EpochError::MissingBlock(hash) => write!(f, "Missing block {}", hash),
1241            EpochError::IOErr(err) => write!(f, "IO: {}", err),
1242            EpochError::NotAValidator(account_id, epoch_id) => {
1243                write!(f, "{} is not a validator in epoch {:?}", account_id, epoch_id)
1244            }
1245            EpochError::ShardingError(err) => write!(f, "Sharding Error: {}", err),
1246            EpochError::NotEnoughValidators { num_shards, num_validators } => {
1247                write!(
1248                    f,
1249                    "There were not enough validator proposals to fill all shards. num_proposals: {}, num_shards: {}",
1250                    num_validators, num_shards
1251                )
1252            }
1253            EpochError::ChunkValidatorSelectionError(err) => {
1254                write!(f, "Error selecting validators for a chunk: {}", err)
1255            }
1256            EpochError::ChunkProducerSelectionError(err) => {
1257                write!(f, "Error selecting chunk producer: {}", err)
1258            }
1259            EpochError::ChunkProducerNotInDB(hash, shard_id) => {
1260                write!(f, "chunk producer not in DB for block {} shard {}", hash, shard_id)
1261            }
1262        }
1263    }
1264}
1265
1266impl Debug for EpochError {
1267    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1268        match self {
1269            EpochError::ThresholdError { stake_sum, num_seats } => {
1270                write!(f, "ThresholdError({}, {})", stake_sum, num_seats)
1271            }
1272            EpochError::EpochOutOfBounds(epoch_id) => write!(f, "EpochOutOfBounds({:?})", epoch_id),
1273            EpochError::MissingBlock(hash) => write!(f, "MissingBlock({})", hash),
1274            EpochError::IOErr(err) => write!(f, "IOErr({})", err),
1275            EpochError::NotAValidator(account_id, epoch_id) => {
1276                write!(f, "NotAValidator({}, {:?})", account_id, epoch_id)
1277            }
1278            EpochError::ShardingError(err) => write!(f, "ShardingError({})", err),
1279            EpochError::NotEnoughValidators { num_shards, num_validators } => {
1280                write!(f, "NotEnoughValidators({}, {})", num_validators, num_shards)
1281            }
1282            EpochError::ChunkValidatorSelectionError(err) => {
1283                write!(f, "ChunkValidatorSelectionError({})", err)
1284            }
1285            EpochError::ChunkProducerSelectionError(err) => {
1286                write!(f, "ChunkProducerSelectionError({})", err)
1287            }
1288            EpochError::ChunkProducerNotInDB(hash, shard_id) => {
1289                write!(f, "ChunkProducerNotInDB({}, {})", hash, shard_id)
1290            }
1291        }
1292    }
1293}
1294
1295impl From<std::io::Error> for EpochError {
1296    fn from(error: std::io::Error) -> Self {
1297        EpochError::IOErr(error.to_string())
1298    }
1299}
1300
1301impl From<ShardLayoutError> for EpochError {
1302    fn from(error: ShardLayoutError) -> Self {
1303        EpochError::ShardingError(error.to_string())
1304    }
1305}
1306
1307#[derive(
1308    Debug,
1309    Clone,
1310    PartialEq,
1311    Eq,
1312    BorshDeserialize,
1313    BorshSerialize,
1314    serde::Deserialize,
1315    serde::Serialize,
1316    ProtocolSchema,
1317)]
1318#[borsh(use_discriminant = true)]
1319#[repr(u8)]
1320#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1321/// Error that can occur while preparing or executing Wasm smart-contract.
1322pub enum PrepareError {
1323    /// Error happened while serializing the module.
1324    Serialization = 0,
1325    /// Error happened while deserializing the module.
1326    Deserialization = 1,
1327    /// Internal memory declaration has been found in the module.
1328    InternalMemoryDeclared = 2,
1329    /// Gas instrumentation failed.
1330    ///
1331    /// This most likely indicates the module isn't valid.
1332    GasInstrumentation = 3,
1333    /// Stack instrumentation failed.
1334    ///
1335    /// This  most likely indicates the module isn't valid.
1336    StackHeightInstrumentation = 4,
1337    /// Error happened during instantiation.
1338    ///
1339    /// This might indicate that `start` function trapped, or module isn't
1340    /// instantiable and/or un-linkable.
1341    Instantiate = 5,
1342    /// Error creating memory.
1343    Memory = 6,
1344    /// Contract contains too many functions.
1345    TooManyFunctions = 7,
1346    /// Contract contains too many locals.
1347    TooManyLocals = 8,
1348    /// Contract contains too many tables.
1349    TooManyTables = 9,
1350    /// Contract contains too many table elements.
1351    TooManyTableElements = 10,
1352    /// A function body in the contract exceeds the size limit.
1353    FunctionBodyTooLarge = 11,
1354    /// The instrumented code exceeds the size limit.
1355    InstrumentedCodeTooLarge = 12,
1356    /// A function contains too many basic blocks.
1357    TooManyBlocksPerFunction = 13,
1358    /// A contract contains too many basic blocks.
1359    TooManyBlocksPerContract = 14,
1360    /// Contract declares too many entries in the wasm type section.
1361    TooManyTypes = 15,
1362    /// All contract functions combined have more than `max_params_per_contract` parameters.
1363    TooManyParamsPerFunction = 16,
1364    /// A function has more than `max_params_per_function` parameters.
1365    TooManyParamsPerContract = 17,
1366    /// A function's max operand-stack size (in bytes) exceeds
1367    /// `max_operand_stack_bytes_per_function`.
1368    OperandStackTooLarge = 18,
1369}
1370
1371/// A kind of a trap happened during execution of a binary
1372#[derive(
1373    Debug,
1374    Clone,
1375    PartialEq,
1376    Eq,
1377    BorshDeserialize,
1378    BorshSerialize,
1379    serde::Deserialize,
1380    serde::Serialize,
1381    strum::IntoStaticStr,
1382    ProtocolSchema,
1383)]
1384#[borsh(use_discriminant = true)]
1385#[repr(u8)]
1386#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1387pub enum WasmTrap {
1388    /// An `unreachable` opcode was executed.
1389    Unreachable = 0,
1390    /// Call indirect incorrect signature trap.
1391    IncorrectCallIndirectSignature = 1,
1392    /// Memory out of bounds trap.
1393    MemoryOutOfBounds = 2,
1394    /// Call indirect out of bounds trap.
1395    CallIndirectOOB = 3,
1396    /// An arithmetic exception, e.g. divided by zero.
1397    IllegalArithmetic = 4,
1398    /// Misaligned atomic access trap.
1399    MisalignedAtomicAccess = 5,
1400    /// Indirect call to null.
1401    IndirectCallToNull = 6,
1402    /// Stack overflow.
1403    StackOverflow = 7,
1404    /// Generic trap.
1405    GenericTrap = 8,
1406}
1407
1408#[derive(
1409    Debug,
1410    Clone,
1411    PartialEq,
1412    Eq,
1413    BorshDeserialize,
1414    BorshSerialize,
1415    serde::Deserialize,
1416    serde::Serialize,
1417    strum::IntoStaticStr,
1418    ProtocolSchema,
1419)]
1420#[borsh(use_discriminant = true)]
1421#[repr(u8)]
1422#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1423pub enum HostError {
1424    /// String encoding is bad UTF-16 sequence
1425    BadUTF16 = 0,
1426    /// String encoding is bad UTF-8 sequence
1427    BadUTF8 = 1,
1428    /// Exceeded the prepaid gas
1429    GasExceeded = 2,
1430    /// Exceeded the maximum amount of gas allowed to burn per contract
1431    GasLimitExceeded = 3,
1432    /// Exceeded the account balance
1433    BalanceExceeded = 4,
1434    /// Tried to call an empty method name
1435    EmptyMethodName = 5,
1436    /// Smart contract panicked
1437    GuestPanic { panic_msg: String } = 6,
1438    /// IntegerOverflow happened during a contract execution
1439    IntegerOverflow = 7,
1440    /// `promise_idx` does not correspond to existing promises
1441    InvalidPromiseIndex { promise_idx: u64 } = 8,
1442    /// Actions can only be appended to non-joint promise.
1443    CannotAppendActionToJointPromise = 9,
1444    /// Returning joint promise is currently prohibited
1445    CannotReturnJointPromise = 10,
1446    /// Accessed invalid promise result index
1447    InvalidPromiseResultIndex { result_idx: u64 } = 11,
1448    /// Accessed invalid register id
1449    InvalidRegisterId { register_id: u64 } = 12,
1450    /// Iterator `iterator_index` was invalidated after its creation by performing a mutable operation on trie
1451    IteratorWasInvalidated { iterator_index: u64 } = 13,
1452    /// Accessed memory outside the bounds
1453    MemoryAccessViolation = 14,
1454    /// VM Logic returned an invalid receipt index
1455    InvalidReceiptIndex { receipt_index: u64 } = 15,
1456    /// Iterator index `iterator_index` does not exist
1457    InvalidIteratorIndex { iterator_index: u64 } = 16,
1458    /// VM Logic returned an invalid account id
1459    InvalidAccountId = 17,
1460    /// VM Logic returned an invalid method name
1461    InvalidMethodName = 18,
1462    /// VM Logic provided an invalid public key
1463    InvalidPublicKey = 19,
1464    /// `method_name` is not allowed in view calls
1465    ProhibitedInView { method_name: String } = 20,
1466    /// The total number of logs will exceed the limit.
1467    NumberOfLogsExceeded { limit: u64 } = 21,
1468    /// The storage key length exceeded the limit.
1469    KeyLengthExceeded { length: u64, limit: u64 } = 22,
1470    /// The storage value length exceeded the limit.
1471    ValueLengthExceeded { length: u64, limit: u64 } = 23,
1472    /// The total log length exceeded the limit.
1473    TotalLogLengthExceeded { length: u64, limit: u64 } = 24,
1474    /// The maximum number of promises within a FunctionCall exceeded the limit.
1475    NumberPromisesExceeded { number_of_promises: u64, limit: u64 } = 25,
1476    /// The maximum number of input data dependencies exceeded the limit.
1477    NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 } = 26,
1478    /// The returned value length exceeded the limit.
1479    ReturnedValueLengthExceeded { length: u64, limit: u64 } = 27,
1480    /// The contract size for DeployContract action exceeded the limit.
1481    ContractSizeExceeded { size: u64, limit: u64 } = 28,
1482    /// The host function was deprecated.
1483    Deprecated { method_name: String } = 29,
1484    /// General errors for ECDSA recover.
1485    ECRecoverError { msg: String } = 30,
1486    /// Invalid input to alt_bn128 family of functions (e.g., point which isn't
1487    /// on the curve).
1488    AltBn128InvalidInput { msg: String } = 31,
1489    /// Invalid input to ed25519 signature verification function (e.g. signature cannot be
1490    /// derived from bytes).
1491    Ed25519VerifyInvalidInput { msg: String } = 32,
1492    /// Input length mismatch for p256 signature verification (signature is not 64
1493    /// bytes or public key is not 33 bytes). Parse failures of otherwise
1494    /// well-sized inputs return 0 from the host function instead of aborting.
1495    P256VerifyInvalidInput { msg: String } = 33,
1496}
1497
1498#[derive(
1499    Debug,
1500    Clone,
1501    PartialEq,
1502    Eq,
1503    BorshDeserialize,
1504    BorshSerialize,
1505    serde::Deserialize,
1506    serde::Serialize,
1507    strum::IntoStaticStr,
1508    ProtocolSchema,
1509)]
1510#[borsh(use_discriminant = true)]
1511#[repr(u8)]
1512#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1513pub enum MethodResolveError {
1514    MethodEmptyName = 0,
1515    MethodNotFound = 1,
1516    MethodInvalidSignature = 2,
1517}
1518
1519#[derive(
1520    Debug,
1521    Clone,
1522    PartialEq,
1523    Eq,
1524    BorshDeserialize,
1525    BorshSerialize,
1526    serde::Deserialize,
1527    serde::Serialize,
1528    strum::IntoStaticStr,
1529    ProtocolSchema,
1530)]
1531#[borsh(use_discriminant = true)]
1532#[repr(u8)]
1533#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1534pub enum CompilationError {
1535    CodeDoesNotExist {
1536        account_id: AccountId,
1537    } = 0,
1538    PrepareError(PrepareError) = 1,
1539    /// This is for defense in depth.
1540    /// We expect our runtime-independent preparation code to fully catch all invalid wasms,
1541    /// but, if it ever misses something we’ll emit this error
1542    WasmerCompileError {
1543        msg: String,
1544    } = 2,
1545}
1546
1547/// Serializable version of `near-vm-runner::FunctionCallError`.
1548///
1549/// Must never reorder/remove elements, can only add new variants at the end (but do that very
1550/// carefully). It describes stable serialization format, and only used by serialization logic.
1551#[derive(
1552    Debug,
1553    Clone,
1554    PartialEq,
1555    Eq,
1556    BorshDeserialize,
1557    BorshSerialize,
1558    serde::Serialize,
1559    serde::Deserialize,
1560    ProtocolSchema,
1561)]
1562#[borsh(use_discriminant = true)]
1563#[repr(u8)]
1564#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1565pub enum FunctionCallError {
1566    /// Wasm compilation error
1567    CompilationError(CompilationError) = 0,
1568    /// Wasm binary env link error
1569    ///
1570    /// Note: this is only to deserialize old data, use execution error for new data
1571    LinkError {
1572        msg: String,
1573    } = 1,
1574    /// Import/export resolve error
1575    MethodResolveError(MethodResolveError) = 2,
1576    /// A trap happened during execution of a binary
1577    ///
1578    /// Note: this is only to deserialize old data, use execution error for new data
1579    WasmTrap(WasmTrap) = 3,
1580    WasmUnknownError = 4,
1581    /// Note: this is only to deserialize old data, use execution error for new data
1582    HostError(HostError) = 5,
1583    // Unused, can be reused by a future error but must be exactly one error to keep ExecutionError
1584    // error borsh serialized at correct index
1585    _EVMError = 6,
1586    ExecutionError(String) = 7,
1587}
1588
1589#[derive(Debug)]
1590pub enum ChunkAccessError {
1591    ChunkMissing(ChunkHash),
1592}
1593
1594impl std::fmt::Display for ChunkAccessError {
1595    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1596        f.write_str(&format!("{:?}", self))
1597    }
1598}
1599
1600impl std::error::Error for ChunkAccessError {}
1601
1602#[derive(Debug)]
1603pub enum InvalidSpiceCoreStatementsError {
1604    /// Information about uncertified chunks for previous block is missing.
1605    NoPrevUncertifiedChunks,
1606    /// Could not find shard_ids for endorsement epoch.
1607    NoShardIdsForEpochId { index: usize, error: EpochError },
1608    /// Spice core statement is invalid.
1609    InvalidCoreStatement { index: usize, reason: &'static str },
1610    /// Spice core statements skipped over execution result for chunk.
1611    SkippedExecutionResult { chunk_id: SpiceChunkId },
1612    /// Could not find validator assignment for chunk.
1613    NoValidatorAssignments {
1614        shard_id: ShardId,
1615        epoch_id: EpochId,
1616        height_created: BlockHeight,
1617        error: EpochError,
1618    },
1619    /// Execution results for endorsed chunk are missing from block.
1620    NoExecutionResultForEndorsedChunk { chunk_id: SpiceChunkId },
1621    /// Could not find block corresponding to endorsement.
1622    UnknownBlock { block_hash: CryptoHash },
1623    /// Encountered io error
1624    IoError { error: io::Error },
1625}
1626
1627impl std::fmt::Display for InvalidSpiceCoreStatementsError {
1628    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1629        f.write_str(&format!(" {:?}", self))
1630    }
1631}
1632
1633impl std::error::Error for InvalidSpiceCoreStatementsError {}