near_primitives/
errors.rs

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