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#[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 ActionError(ActionError) = 0,
33 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#[derive(Debug, Clone, PartialEq, Eq)]
62pub enum RuntimeError {
63 UnexpectedIntegerOverflow(String),
65 InvalidTxError(InvalidTxError),
67 StorageError(StorageError),
70 ReceiptValidationError(ReceiptValidationError),
72 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#[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 TrieIterator = 0,
102 TriePrefetchingStorage = 1,
104 TrieMemoryPartialStorage = 2,
106 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#[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 StorageInternalError = 0,
157 MissingTrieValue(MissingTrieValue) = 1,
159 UnexpectedTrieValue = 2,
163 StorageInconsistentState(String) = 3,
169 FlatStorageBlockNotSupported(String) = 4,
173 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#[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 InvalidAccessKeyError(InvalidAccessKeyError) = 0,
203 InvalidSignerId {
205 signer_id: String,
206 } = 1,
207 SignerDoesNotExist {
209 signer_id: AccountId,
210 } = 2,
211 InvalidNonce {
213 tx_nonce: Nonce,
214 ak_nonce: Nonce,
215 } = 3,
216 NonceTooLarge {
218 tx_nonce: Nonce,
219 upper_bound: Nonce,
220 } = 4,
221 InvalidReceiverId {
223 receiver_id: String,
224 } = 5,
225 InvalidSignature = 6,
227 NotEnoughBalance {
229 signer_id: AccountId,
230 balance: Balance,
231 cost: Balance,
232 } = 7,
233 LackBalanceForState {
235 signer_id: AccountId,
237 amount: Balance,
239 } = 8,
240 CostOverflow = 9,
242 InvalidChain = 10,
244 Expired = 11,
246 ActionsValidation(ActionsValidationError) = 12,
248 TransactionSizeExceeded {
250 size: u64,
251 limit: u64,
252 } = 13,
253 InvalidTransactionVersion = 14,
255 StorageError(StorageError) = 15,
257 ShardCongested {
260 shard_id: u32,
262 #[cfg_attr(feature = "schemars", schemars(with = "f64"))]
264 congestion_level: ordered_float::NotNan<f64>,
265 } = 16,
266 ShardStuck {
269 shard_id: u32,
271 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 AccessKeyNotFound { account_id: AccountId, public_key: Box<PublicKey> } = 0,
301 ReceiverMismatch { tx_receiver: AccountId, ak_receiver: String } = 1,
303 MethodNameMismatch { method_name: String } = 2,
305 RequiresFullAccess = 3,
307 NotEnoughAllowance {
309 account_id: AccountId,
310 public_key: Box<PublicKey>,
311 allowance: Balance,
312 cost: Balance,
313 } = 4,
314 DepositWithFunctionCall = 5,
316}
317
318#[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 DeleteActionMustBeFinal = 0,
336 TotalPrepaidGasExceeded {
338 total_prepaid_gas: Gas,
339 limit: Gas,
340 } = 1,
341 TotalNumberOfActionsExceeded {
343 total_number_of_actions: u64,
344 limit: u64,
345 } = 2,
346 AddKeyMethodNamesNumberOfBytesExceeded {
348 total_number_of_bytes: u64,
349 limit: u64,
350 } = 3,
351 AddKeyMethodNameLengthExceeded {
353 length: u64,
354 limit: u64,
355 } = 4,
356 IntegerOverflow = 5,
358 InvalidAccountId {
360 account_id: String,
361 } = 6,
362 ContractSizeExceeded {
364 size: u64,
365 limit: u64,
366 } = 7,
367 FunctionCallMethodNameLengthExceeded {
369 length: u64,
370 limit: u64,
371 } = 8,
372 FunctionCallArgumentsLengthExceeded {
374 length: u64,
375 limit: u64,
376 } = 9,
377 UnsuitableStakingKey {
379 public_key: Box<PublicKey>,
380 } = 10,
381 FunctionCallZeroAttachedGas = 11,
383 DelegateActionMustBeOnlyOne = 12,
385 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#[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 InvalidPredecessorId { account_id: String } = 0,
427 InvalidReceiverId { account_id: String } = 1,
429 InvalidSignerId { account_id: String } = 2,
431 InvalidDataReceiverId { account_id: String } = 3,
433 ReturnedValueLengthExceeded { length: u64, limit: u64 } = 4,
435 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 } = 5,
437 ActionsValidation(ActionsValidationError) = 6,
439 ReceiptSizeExceeded { size: u64, limit: u64 } = 7,
441 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#[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 pub index: Option<u64>,
608 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 AccountAlreadyExists {
631 account_id: AccountId,
632 } = 0,
633 AccountDoesNotExist {
635 account_id: AccountId,
636 } = 1,
637 CreateAccountOnlyByRegistrar {
639 account_id: AccountId,
640 registrar_account_id: AccountId,
641 predecessor_id: AccountId,
642 } = 2,
643
644 CreateAccountNotAllowed {
646 account_id: AccountId,
647 predecessor_id: AccountId,
648 } = 3,
649 ActorNoPermission {
652 account_id: AccountId,
653 actor_id: AccountId,
654 } = 4,
655 DeleteKeyDoesNotExist {
657 account_id: AccountId,
658 public_key: Box<PublicKey>,
659 } = 5,
660 AddKeyAlreadyExists {
662 account_id: AccountId,
663 public_key: Box<PublicKey>,
664 } = 6,
665 DeleteAccountStaking {
667 account_id: AccountId,
668 } = 7,
669 LackBalanceForState {
671 account_id: AccountId,
673 amount: Balance,
675 } = 8,
676 TriesToUnstake {
678 account_id: AccountId,
679 } = 9,
680 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 FunctionCallError(FunctionCallError) = 12,
694 NewReceiptValidationError(ReceiptValidationError) = 13,
697 OnlyImplicitAccountCreationAllowed {
704 account_id: AccountId,
705 } = 14,
706 DeleteAccountWithLargeState {
708 account_id: AccountId,
709 } = 15,
710 DelegateActionInvalidSignature = 16,
712 DelegateActionSenderDoesNotMatchTxReceiver {
714 sender_id: AccountId,
715 receiver_id: AccountId,
716 } = 17,
717 DelegateActionExpired = 18,
719 DelegateActionAccessKeyError(InvalidAccessKeyError) = 19,
721 DelegateActionInvalidNonce {
723 delegate_nonce: Nonce,
724 ak_nonce: Nonce,
725 } = 20,
726 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 ThresholdError {
1021 stake_sum: Balance,
1022 num_seats: u64,
1023 },
1024 EpochOutOfBounds(EpochId),
1026 MissingBlock(CryptoHash),
1028 IOErr(String),
1030 NotAValidator(AccountId, EpochId),
1032 ShardingError(String),
1034 NotEnoughValidators {
1035 num_validators: u64,
1036 num_shards: u64,
1037 },
1038 ChunkValidatorSelectionError(String),
1040 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))]
1132pub enum PrepareError {
1134 Serialization = 0,
1136 Deserialization = 1,
1138 InternalMemoryDeclared = 2,
1140 GasInstrumentation = 3,
1144 StackHeightInstrumentation = 4,
1148 Instantiate = 5,
1153 Memory = 6,
1155 TooManyFunctions = 7,
1157 TooManyLocals = 8,
1159 TooManyTables = 9,
1161 TooManyTableElements = 10,
1163}
1164
1165#[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 Unreachable = 0,
1184 IncorrectCallIndirectSignature = 1,
1186 MemoryOutOfBounds = 2,
1188 CallIndirectOOB = 3,
1190 IllegalArithmetic = 4,
1192 MisalignedAtomicAccess = 5,
1194 IndirectCallToNull = 6,
1196 StackOverflow = 7,
1198 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 BadUTF16 = 0,
1220 BadUTF8 = 1,
1222 GasExceeded = 2,
1224 GasLimitExceeded = 3,
1226 BalanceExceeded = 4,
1228 EmptyMethodName = 5,
1230 GuestPanic { panic_msg: String } = 6,
1232 IntegerOverflow = 7,
1234 InvalidPromiseIndex { promise_idx: u64 } = 8,
1236 CannotAppendActionToJointPromise = 9,
1238 CannotReturnJointPromise = 10,
1240 InvalidPromiseResultIndex { result_idx: u64 } = 11,
1242 InvalidRegisterId { register_id: u64 } = 12,
1244 IteratorWasInvalidated { iterator_index: u64 } = 13,
1246 MemoryAccessViolation = 14,
1248 InvalidReceiptIndex { receipt_index: u64 } = 15,
1250 InvalidIteratorIndex { iterator_index: u64 } = 16,
1252 InvalidAccountId = 17,
1254 InvalidMethodName = 18,
1256 InvalidPublicKey = 19,
1258 ProhibitedInView { method_name: String } = 20,
1260 NumberOfLogsExceeded { limit: u64 } = 21,
1262 KeyLengthExceeded { length: u64, limit: u64 } = 22,
1264 ValueLengthExceeded { length: u64, limit: u64 } = 23,
1266 TotalLogLengthExceeded { length: u64, limit: u64 } = 24,
1268 NumberPromisesExceeded { number_of_promises: u64, limit: u64 } = 25,
1270 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 } = 26,
1272 ReturnedValueLengthExceeded { length: u64, limit: u64 } = 27,
1274 ContractSizeExceeded { size: u64, limit: u64 } = 28,
1276 Deprecated { method_name: String } = 29,
1278 ECRecoverError { msg: String } = 30,
1280 AltBn128InvalidInput { msg: String } = 31,
1283 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 WasmerCompileError {
1333 msg: String,
1334 } = 2,
1335}
1336
1337#[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 CompilationError(CompilationError) = 0,
1358 LinkError {
1362 msg: String,
1363 } = 1,
1364 MethodResolveError(MethodResolveError) = 2,
1366 WasmTrap(WasmTrap) = 3,
1370 WasmUnknownError = 4,
1371 HostError(HostError) = 5,
1373 _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 NoPrevUncertifiedChunks,
1396 NoShardIdsForEpochId { index: usize, error: EpochError },
1398 InvalidCoreStatement { index: usize, reason: &'static str },
1400 SkippedExecutionResult { chunk_id: SpiceChunkId },
1402 NoValidatorAssignments {
1404 shard_id: ShardId,
1405 epoch_id: EpochId,
1406 height_created: BlockHeight,
1407 error: EpochError,
1408 },
1409 NoExecutionResultForEndorsedChunk { chunk_id: SpiceChunkId },
1411 UnknownBlock { block_hash: CryptoHash },
1413 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 {}