near_primitives/
errors.rs

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