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