1use crate::action::GlobalContractIdentifier;
2use crate::hash::CryptoHash;
3use crate::serialize::dec_format;
4use crate::shard_layout::ShardLayoutError;
5use crate::sharding::ChunkHash;
6use crate::types::{AccountId, Balance, EpochId, Gas, Nonce};
7use borsh::{BorshDeserialize, BorshSerialize};
8use near_crypto::PublicKey;
9use near_primitives_core::types::ProtocolVersion;
10use near_schema_checker_lib::ProtocolSchema;
11use std::fmt::{Debug, Display};
12
13#[derive(
15 BorshSerialize,
16 BorshDeserialize,
17 Debug,
18 Clone,
19 PartialEq,
20 Eq,
21 serde::Deserialize,
22 serde::Serialize,
23 ProtocolSchema,
24)]
25pub enum TxExecutionError {
26 ActionError(ActionError),
28 InvalidTxError(InvalidTxError),
30}
31
32impl std::error::Error for TxExecutionError {}
33
34impl Display for TxExecutionError {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
36 match self {
37 TxExecutionError::ActionError(e) => write!(f, "{}", e),
38 TxExecutionError::InvalidTxError(e) => write!(f, "{}", e),
39 }
40 }
41}
42
43impl From<ActionError> for TxExecutionError {
44 fn from(error: ActionError) -> Self {
45 TxExecutionError::ActionError(error)
46 }
47}
48
49impl From<InvalidTxError> for TxExecutionError {
50 fn from(error: InvalidTxError) -> Self {
51 TxExecutionError::InvalidTxError(error)
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq)]
57pub enum RuntimeError {
58 UnexpectedIntegerOverflow(String),
60 InvalidTxError(InvalidTxError),
62 StorageError(StorageError),
65 BalanceMismatchError(Box<BalanceMismatchError>),
67 ReceiptValidationError(ReceiptValidationError),
69 ValidatorError(EpochError),
71}
72
73impl std::fmt::Display for RuntimeError {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
75 f.write_str(&format!("{:?}", self))
76 }
77}
78
79impl std::error::Error for RuntimeError {}
80
81#[derive(
83 Debug,
84 Clone,
85 PartialEq,
86 Eq,
87 serde::Deserialize,
88 serde::Serialize,
89 BorshSerialize,
90 BorshDeserialize,
91 ProtocolSchema,
92)]
93pub enum MissingTrieValueContext {
94 TrieIterator,
96 TriePrefetchingStorage,
98 TrieMemoryPartialStorage,
100 TrieStorage,
102}
103
104impl MissingTrieValueContext {
105 pub fn metrics_label(&self) -> &str {
106 match self {
107 Self::TrieIterator => "trie_iterator",
108 Self::TriePrefetchingStorage => "trie_prefetching_storage",
109 Self::TrieMemoryPartialStorage => "trie_memory_partial_storage",
110 Self::TrieStorage => "trie_storage",
111 }
112 }
113}
114
115#[derive(
118 Debug,
119 Clone,
120 PartialEq,
121 Eq,
122 serde::Deserialize,
123 serde::Serialize,
124 BorshSerialize,
125 BorshDeserialize,
126 ProtocolSchema,
127)]
128pub enum StorageError {
129 StorageInternalError,
131 MissingTrieValue(MissingTrieValueContext, CryptoHash),
133 UnexpectedTrieValue,
137 StorageInconsistentState(String),
143 FlatStorageBlockNotSupported(String),
147 MemTrieLoadingError(String),
149 FlatStorageReshardingAlreadyInProgress,
152}
153
154impl std::fmt::Display for StorageError {
155 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
156 f.write_str(&format!("{:?}", self))
157 }
158}
159
160impl std::error::Error for StorageError {}
161
162#[derive(
164 BorshSerialize,
165 BorshDeserialize,
166 Debug,
167 Clone,
168 PartialEq,
169 Eq,
170 serde::Deserialize,
171 serde::Serialize,
172 ProtocolSchema,
173)]
174pub enum InvalidTxError {
175 InvalidAccessKeyError(InvalidAccessKeyError),
177 InvalidSignerId {
179 signer_id: String,
180 },
181 SignerDoesNotExist {
183 signer_id: AccountId,
184 },
185 InvalidNonce {
187 tx_nonce: Nonce,
188 ak_nonce: Nonce,
189 },
190 NonceTooLarge {
192 tx_nonce: Nonce,
193 upper_bound: Nonce,
194 },
195 InvalidReceiverId {
197 receiver_id: String,
198 },
199 InvalidSignature,
201 NotEnoughBalance {
203 signer_id: AccountId,
204 #[serde(with = "dec_format")]
205 balance: Balance,
206 #[serde(with = "dec_format")]
207 cost: Balance,
208 },
209 LackBalanceForState {
211 signer_id: AccountId,
213 #[serde(with = "dec_format")]
215 amount: Balance,
216 },
217 CostOverflow,
219 InvalidChain,
221 Expired,
223 ActionsValidation(ActionsValidationError),
225 TransactionSizeExceeded {
227 size: u64,
228 limit: u64,
229 },
230 InvalidTransactionVersion,
232 StorageError(StorageError),
234 ShardCongested {
237 shard_id: u32,
239 congestion_level: ordered_float::NotNan<f64>,
241 },
242 ShardStuck {
245 shard_id: u32,
247 missed_chunks: u64,
249 },
250}
251
252impl From<StorageError> for InvalidTxError {
253 fn from(error: StorageError) -> Self {
254 InvalidTxError::StorageError(error)
255 }
256}
257
258impl std::error::Error for InvalidTxError {}
259
260#[derive(
261 BorshSerialize,
262 BorshDeserialize,
263 Debug,
264 Clone,
265 PartialEq,
266 Eq,
267 serde::Deserialize,
268 serde::Serialize,
269 ProtocolSchema,
270)]
271pub enum InvalidAccessKeyError {
272 AccessKeyNotFound { account_id: AccountId, public_key: Box<PublicKey> },
274 ReceiverMismatch { tx_receiver: AccountId, ak_receiver: String },
276 MethodNameMismatch { method_name: String },
278 RequiresFullAccess,
280 NotEnoughAllowance {
282 account_id: AccountId,
283 public_key: Box<PublicKey>,
284 #[serde(with = "dec_format")]
285 allowance: Balance,
286 #[serde(with = "dec_format")]
287 cost: Balance,
288 },
289 DepositWithFunctionCall,
291}
292
293#[derive(
295 BorshSerialize,
296 BorshDeserialize,
297 Debug,
298 Clone,
299 PartialEq,
300 Eq,
301 serde::Serialize,
302 serde::Deserialize,
303 ProtocolSchema,
304)]
305pub enum ActionsValidationError {
306 DeleteActionMustBeFinal,
308 TotalPrepaidGasExceeded { total_prepaid_gas: Gas, limit: Gas },
310 TotalNumberOfActionsExceeded { total_number_of_actions: u64, limit: u64 },
312 AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes: u64, limit: u64 },
314 AddKeyMethodNameLengthExceeded { length: u64, limit: u64 },
316 IntegerOverflow,
318 InvalidAccountId { account_id: String },
320 ContractSizeExceeded { size: u64, limit: u64 },
322 FunctionCallMethodNameLengthExceeded { length: u64, limit: u64 },
324 FunctionCallArgumentsLengthExceeded { length: u64, limit: u64 },
326 UnsuitableStakingKey { public_key: Box<PublicKey> },
328 FunctionCallZeroAttachedGas,
330 DelegateActionMustBeOnlyOne,
332 UnsupportedProtocolFeature { protocol_feature: String, version: ProtocolVersion },
339}
340
341#[derive(
343 BorshSerialize,
344 BorshDeserialize,
345 Debug,
346 Clone,
347 PartialEq,
348 Eq,
349 serde::Serialize,
350 serde::Deserialize,
351 ProtocolSchema,
352)]
353pub enum ReceiptValidationError {
354 InvalidPredecessorId { account_id: String },
356 InvalidReceiverId { account_id: String },
358 InvalidSignerId { account_id: String },
360 InvalidDataReceiverId { account_id: String },
362 ReturnedValueLengthExceeded { length: u64, limit: u64 },
364 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 },
366 ActionsValidation(ActionsValidationError),
368 ReceiptSizeExceeded { size: u64, limit: u64 },
370}
371
372impl Display for ReceiptValidationError {
373 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
374 match self {
375 ReceiptValidationError::InvalidPredecessorId { account_id } => {
376 write!(f, "The predecessor_id `{}` of a Receipt is not valid.", account_id)
377 }
378 ReceiptValidationError::InvalidReceiverId { account_id } => {
379 write!(f, "The receiver_id `{}` of a Receipt is not valid.", account_id)
380 }
381 ReceiptValidationError::InvalidSignerId { account_id } => {
382 write!(f, "The signer_id `{}` of an ActionReceipt is not valid.", account_id)
383 }
384 ReceiptValidationError::InvalidDataReceiverId { account_id } => write!(
385 f,
386 "The receiver_id `{}` of a DataReceiver within an ActionReceipt is not valid.",
387 account_id
388 ),
389 ReceiptValidationError::ReturnedValueLengthExceeded { length, limit } => write!(
390 f,
391 "The length of the returned data {} exceeded the limit {} in a DataReceipt",
392 length, limit
393 ),
394 ReceiptValidationError::NumberInputDataDependenciesExceeded {
395 number_of_input_data_dependencies,
396 limit,
397 } => write!(
398 f,
399 "The number of input data dependencies {} exceeded the limit {} in an ActionReceipt",
400 number_of_input_data_dependencies, limit
401 ),
402 ReceiptValidationError::ActionsValidation(e) => write!(f, "{}", e),
403 ReceiptValidationError::ReceiptSizeExceeded { size, limit } => {
404 write!(f, "The size of the receipt exceeded the limit: {} > {}", size, limit)
405 }
406 }
407 }
408}
409
410impl std::error::Error for ReceiptValidationError {}
411
412impl Display for ActionsValidationError {
413 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
414 match self {
415 ActionsValidationError::DeleteActionMustBeFinal => {
416 write!(f, "The delete action must be the last action in transaction")
417 }
418 ActionsValidationError::TotalPrepaidGasExceeded { total_prepaid_gas, limit } => {
419 write!(f, "The total prepaid gas {} exceeds the limit {}", total_prepaid_gas, limit)
420 }
421 ActionsValidationError::TotalNumberOfActionsExceeded {
422 total_number_of_actions,
423 limit,
424 } => {
425 write!(
426 f,
427 "The total number of actions {} exceeds the limit {}",
428 total_number_of_actions, limit
429 )
430 }
431 ActionsValidationError::AddKeyMethodNamesNumberOfBytesExceeded {
432 total_number_of_bytes,
433 limit,
434 } => write!(
435 f,
436 "The total number of bytes in allowed method names {} exceeds the maximum allowed number {} in a AddKey action",
437 total_number_of_bytes, limit
438 ),
439 ActionsValidationError::AddKeyMethodNameLengthExceeded { length, limit } => write!(
440 f,
441 "The length of some method name {} exceeds the maximum allowed length {} in a AddKey action",
442 length, limit
443 ),
444 ActionsValidationError::IntegerOverflow => {
445 write!(f, "Integer overflow during a compute",)
446 }
447 ActionsValidationError::InvalidAccountId { account_id } => {
448 write!(f, "Invalid account ID `{}`", account_id)
449 }
450 ActionsValidationError::ContractSizeExceeded { size, limit } => write!(
451 f,
452 "The length of the contract size {} exceeds the maximum allowed size {} in a DeployContract action",
453 size, limit
454 ),
455 ActionsValidationError::FunctionCallMethodNameLengthExceeded { length, limit } => {
456 write!(
457 f,
458 "The length of the method name {} exceeds the maximum allowed length {} in a FunctionCall action",
459 length, limit
460 )
461 }
462 ActionsValidationError::FunctionCallArgumentsLengthExceeded { length, limit } => {
463 write!(
464 f,
465 "The length of the arguments {} exceeds the maximum allowed length {} in a FunctionCall action",
466 length, limit
467 )
468 }
469 ActionsValidationError::UnsuitableStakingKey { public_key } => write!(
470 f,
471 "The staking key must be ristretto compatible ED25519 key. {} is provided instead.",
472 public_key,
473 ),
474 ActionsValidationError::FunctionCallZeroAttachedGas => write!(
475 f,
476 "The attached amount of gas in a FunctionCall action has to be a positive number",
477 ),
478 ActionsValidationError::DelegateActionMustBeOnlyOne => {
479 write!(f, "The actions can contain the ony one DelegateAction")
480 }
481 ActionsValidationError::UnsupportedProtocolFeature { protocol_feature, version } => {
482 write!(
483 f,
484 "Transaction requires protocol feature {} / version {} which is not supported by the current protocol version",
485 protocol_feature, version,
486 )
487 }
488 }
489 }
490}
491
492impl std::error::Error for ActionsValidationError {}
493
494#[derive(
496 BorshSerialize,
497 BorshDeserialize,
498 Debug,
499 Clone,
500 PartialEq,
501 Eq,
502 serde::Deserialize,
503 serde::Serialize,
504 ProtocolSchema,
505)]
506pub struct ActionError {
507 pub index: Option<u64>,
510 pub kind: ActionErrorKind,
512}
513
514impl std::error::Error for ActionError {}
515
516#[derive(
517 BorshSerialize,
518 BorshDeserialize,
519 Debug,
520 Clone,
521 PartialEq,
522 Eq,
523 serde::Deserialize,
524 serde::Serialize,
525 ProtocolSchema,
526)]
527pub enum ActionErrorKind {
528 AccountAlreadyExists {
530 account_id: AccountId,
531 },
532 AccountDoesNotExist {
534 account_id: AccountId,
535 },
536 CreateAccountOnlyByRegistrar {
538 account_id: AccountId,
539 registrar_account_id: AccountId,
540 predecessor_id: AccountId,
541 },
542
543 CreateAccountNotAllowed {
545 account_id: AccountId,
546 predecessor_id: AccountId,
547 },
548 ActorNoPermission {
551 account_id: AccountId,
552 actor_id: AccountId,
553 },
554 DeleteKeyDoesNotExist {
556 account_id: AccountId,
557 public_key: Box<PublicKey>,
558 },
559 AddKeyAlreadyExists {
561 account_id: AccountId,
562 public_key: Box<PublicKey>,
563 },
564 DeleteAccountStaking {
566 account_id: AccountId,
567 },
568 LackBalanceForState {
570 account_id: AccountId,
572 #[serde(with = "dec_format")]
574 amount: Balance,
575 },
576 TriesToUnstake {
578 account_id: AccountId,
579 },
580 TriesToStake {
582 account_id: AccountId,
583 #[serde(with = "dec_format")]
584 stake: Balance,
585 #[serde(with = "dec_format")]
586 locked: Balance,
587 #[serde(with = "dec_format")]
588 balance: Balance,
589 },
590 InsufficientStake {
591 account_id: AccountId,
592 #[serde(with = "dec_format")]
593 stake: Balance,
594 #[serde(with = "dec_format")]
595 minimum_stake: Balance,
596 },
597 FunctionCallError(FunctionCallError),
599 NewReceiptValidationError(ReceiptValidationError),
602 OnlyImplicitAccountCreationAllowed {
609 account_id: AccountId,
610 },
611 DeleteAccountWithLargeState {
613 account_id: AccountId,
614 },
615 DelegateActionInvalidSignature,
617 DelegateActionSenderDoesNotMatchTxReceiver {
619 sender_id: AccountId,
620 receiver_id: AccountId,
621 },
622 DelegateActionExpired,
624 DelegateActionAccessKeyError(InvalidAccessKeyError),
626 DelegateActionInvalidNonce {
628 delegate_nonce: Nonce,
629 ak_nonce: Nonce,
630 },
631 DelegateActionNonceTooLarge {
633 delegate_nonce: Nonce,
634 upper_bound: Nonce,
635 },
636 GlobalContractDoesNotExist {
637 identifier: GlobalContractIdentifier,
638 },
639}
640
641impl From<ActionErrorKind> for ActionError {
642 fn from(e: ActionErrorKind) -> ActionError {
643 ActionError { index: None, kind: e }
644 }
645}
646
647impl Display for InvalidTxError {
648 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
649 match self {
650 InvalidTxError::InvalidSignerId { signer_id } => {
651 write!(f, "Invalid signer account ID {:?} according to requirements", signer_id)
652 }
653 InvalidTxError::SignerDoesNotExist { signer_id } => {
654 write!(f, "Signer {:?} does not exist", signer_id)
655 }
656 InvalidTxError::InvalidAccessKeyError(access_key_error) => {
657 Display::fmt(&access_key_error, f)
658 }
659 InvalidTxError::InvalidNonce { tx_nonce, ak_nonce } => write!(
660 f,
661 "Transaction nonce {} must be larger than nonce of the used access key {}",
662 tx_nonce, ak_nonce
663 ),
664 InvalidTxError::InvalidReceiverId { receiver_id } => {
665 write!(f, "Invalid receiver account ID {:?} according to requirements", receiver_id)
666 }
667 InvalidTxError::InvalidSignature => {
668 write!(f, "Transaction is not signed with the given public key")
669 }
670 InvalidTxError::NotEnoughBalance { signer_id, balance, cost } => write!(
671 f,
672 "Sender {:?} does not have enough balance {} for operation costing {}",
673 signer_id, balance, cost
674 ),
675 InvalidTxError::LackBalanceForState { signer_id, amount } => {
676 write!(
677 f,
678 "Failed to execute, because the account {:?} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more",
679 signer_id, amount
680 )
681 }
682 InvalidTxError::CostOverflow => {
683 write!(f, "Transaction gas or balance cost is too high")
684 }
685 InvalidTxError::InvalidChain => {
686 write!(f, "Transaction parent block hash doesn't belong to the current chain")
687 }
688 InvalidTxError::Expired => {
689 write!(f, "Transaction has expired")
690 }
691 InvalidTxError::ActionsValidation(error) => {
692 write!(f, "Transaction actions validation error: {}", error)
693 }
694 InvalidTxError::NonceTooLarge { tx_nonce, upper_bound } => {
695 write!(
696 f,
697 "Transaction nonce {} must be smaller than the access key nonce upper bound {}",
698 tx_nonce, upper_bound
699 )
700 }
701 InvalidTxError::TransactionSizeExceeded { size, limit } => {
702 write!(f, "Size of serialized transaction {} exceeded the limit {}", size, limit)
703 }
704 InvalidTxError::InvalidTransactionVersion => {
705 write!(f, "Transaction version is invalid")
706 }
707 InvalidTxError::StorageError(error) => {
708 write!(f, "Storage error: {}", error)
709 }
710 InvalidTxError::ShardCongested { shard_id, congestion_level } => {
711 write!(
712 f,
713 "Shard {shard_id} is currently at congestion level {congestion_level:.3} and rejects new transactions."
714 )
715 }
716 InvalidTxError::ShardStuck { shard_id, missed_chunks } => {
717 write!(
718 f,
719 "Shard {shard_id} missed {missed_chunks} chunks and rejects new transactions."
720 )
721 }
722 }
723 }
724}
725
726impl From<InvalidAccessKeyError> for InvalidTxError {
727 fn from(error: InvalidAccessKeyError) -> Self {
728 InvalidTxError::InvalidAccessKeyError(error)
729 }
730}
731
732impl Display for InvalidAccessKeyError {
733 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
734 match self {
735 InvalidAccessKeyError::AccessKeyNotFound { account_id, public_key } => write!(
736 f,
737 "Signer {:?} doesn't have access key with the given public_key {}",
738 account_id, public_key
739 ),
740 InvalidAccessKeyError::ReceiverMismatch { tx_receiver, ak_receiver } => write!(
741 f,
742 "Transaction receiver_id {:?} doesn't match the access key receiver_id {:?}",
743 tx_receiver, ak_receiver
744 ),
745 InvalidAccessKeyError::MethodNameMismatch { method_name } => write!(
746 f,
747 "Transaction method name {:?} isn't allowed by the access key",
748 method_name
749 ),
750 InvalidAccessKeyError::RequiresFullAccess => {
751 write!(
752 f,
753 "Invalid access key type. Full-access keys are required for transactions that have multiple or non-function-call actions"
754 )
755 }
756 InvalidAccessKeyError::NotEnoughAllowance {
757 account_id,
758 public_key,
759 allowance,
760 cost,
761 } => write!(
762 f,
763 "Access Key {:?}:{} does not have enough balance {} for transaction costing {}",
764 account_id, public_key, allowance, cost
765 ),
766 InvalidAccessKeyError::DepositWithFunctionCall => {
767 write!(
768 f,
769 "Having a deposit with a function call action is not allowed with a function call access key."
770 )
771 }
772 }
773 }
774}
775
776impl std::error::Error for InvalidAccessKeyError {}
777
778#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, ProtocolSchema)]
780pub struct BalanceMismatchError {
781 #[serde(with = "dec_format")]
783 pub incoming_validator_rewards: Balance,
784 #[serde(with = "dec_format")]
785 pub initial_accounts_balance: Balance,
786 #[serde(with = "dec_format")]
787 pub incoming_receipts_balance: Balance,
788 #[serde(with = "dec_format")]
789 pub processed_delayed_receipts_balance: Balance,
790 #[serde(with = "dec_format")]
791 pub initial_postponed_receipts_balance: Balance,
792 #[serde(with = "dec_format")]
793 pub forwarded_buffered_receipts_balance: Balance,
794 #[serde(with = "dec_format")]
796 pub final_accounts_balance: Balance,
797 #[serde(with = "dec_format")]
798 pub outgoing_receipts_balance: Balance,
799 #[serde(with = "dec_format")]
800 pub new_delayed_receipts_balance: Balance,
801 #[serde(with = "dec_format")]
802 pub final_postponed_receipts_balance: Balance,
803 #[serde(with = "dec_format")]
804 pub tx_burnt_amount: Balance,
805 #[serde(with = "dec_format")]
806 pub slashed_burnt_amount: Balance,
807 #[serde(with = "dec_format")]
808 pub new_buffered_receipts_balance: Balance,
809 #[serde(with = "dec_format")]
810 pub other_burnt_amount: Balance,
811}
812
813impl Display for BalanceMismatchError {
814 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
815 let initial_balance = self
817 .incoming_validator_rewards
818 .saturating_add(self.initial_accounts_balance)
819 .saturating_add(self.incoming_receipts_balance)
820 .saturating_add(self.processed_delayed_receipts_balance)
821 .saturating_add(self.initial_postponed_receipts_balance)
822 .saturating_add(self.forwarded_buffered_receipts_balance);
823 let final_balance = self
824 .final_accounts_balance
825 .saturating_add(self.outgoing_receipts_balance)
826 .saturating_add(self.new_delayed_receipts_balance)
827 .saturating_add(self.final_postponed_receipts_balance)
828 .saturating_add(self.tx_burnt_amount)
829 .saturating_add(self.slashed_burnt_amount)
830 .saturating_add(self.other_burnt_amount)
831 .saturating_add(self.new_buffered_receipts_balance);
832
833 write!(
834 f,
835 "Balance Mismatch Error. The input balance {} doesn't match output balance {}\n\
836 Inputs:\n\
837 \tIncoming validator rewards sum: {}\n\
838 \tInitial accounts balance sum: {}\n\
839 \tIncoming receipts balance sum: {}\n\
840 \tProcessed delayed receipts balance sum: {}\n\
841 \tInitial postponed receipts balance sum: {}\n\
842 \tForwarded buffered receipts sum: {}\n\
843 Outputs:\n\
844 \tFinal accounts balance sum: {}\n\
845 \tOutgoing receipts balance sum: {}\n\
846 \tNew delayed receipts balance sum: {}\n\
847 \tFinal postponed receipts balance sum: {}\n\
848 \tTx fees burnt amount: {}\n\
849 \tSlashed amount: {}\n\
850 \tNew buffered receipts balance sum: {}\n\
851 \tOther burnt amount: {}",
852 initial_balance,
853 final_balance,
854 self.incoming_validator_rewards,
855 self.initial_accounts_balance,
856 self.incoming_receipts_balance,
857 self.processed_delayed_receipts_balance,
858 self.initial_postponed_receipts_balance,
859 self.forwarded_buffered_receipts_balance,
860 self.final_accounts_balance,
861 self.outgoing_receipts_balance,
862 self.new_delayed_receipts_balance,
863 self.final_postponed_receipts_balance,
864 self.tx_burnt_amount,
865 self.slashed_burnt_amount,
866 self.new_buffered_receipts_balance,
867 self.other_burnt_amount,
868 )
869 }
870}
871
872impl std::error::Error for BalanceMismatchError {}
873
874#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, ProtocolSchema)]
875pub struct IntegerOverflowError;
876
877impl std::fmt::Display for IntegerOverflowError {
878 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
879 f.write_str(&format!("{:?}", self))
880 }
881}
882
883impl std::error::Error for IntegerOverflowError {}
884
885impl From<IntegerOverflowError> for InvalidTxError {
886 fn from(_: IntegerOverflowError) -> Self {
887 InvalidTxError::CostOverflow
888 }
889}
890
891impl From<IntegerOverflowError> for RuntimeError {
892 fn from(err: IntegerOverflowError) -> Self {
893 RuntimeError::UnexpectedIntegerOverflow(err.to_string())
894 }
895}
896
897impl From<StorageError> for RuntimeError {
898 fn from(e: StorageError) -> Self {
899 RuntimeError::StorageError(e)
900 }
901}
902
903impl From<BalanceMismatchError> for RuntimeError {
904 fn from(e: BalanceMismatchError) -> Self {
905 RuntimeError::BalanceMismatchError(Box::new(e))
906 }
907}
908
909impl From<InvalidTxError> for RuntimeError {
910 fn from(e: InvalidTxError) -> Self {
911 RuntimeError::InvalidTxError(e)
912 }
913}
914
915impl From<EpochError> for RuntimeError {
916 fn from(e: EpochError) -> Self {
917 RuntimeError::ValidatorError(e)
918 }
919}
920
921impl Display for ActionError {
922 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
923 write!(f, "Action #{}: {}", self.index.unwrap_or_default(), self.kind)
924 }
925}
926
927impl Display for ActionErrorKind {
928 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
929 match self {
930 ActionErrorKind::AccountAlreadyExists { account_id } => {
931 write!(f, "Can't create a new account {:?}, because it already exists", account_id)
932 }
933 ActionErrorKind::AccountDoesNotExist { account_id } => write!(
934 f,
935 "Can't complete the action because account {:?} doesn't exist",
936 account_id
937 ),
938 ActionErrorKind::ActorNoPermission { actor_id, account_id } => write!(
939 f,
940 "Actor {:?} doesn't have permission to account {:?} to complete the action",
941 actor_id, account_id
942 ),
943 ActionErrorKind::LackBalanceForState { account_id, amount } => write!(
944 f,
945 "The account {} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more",
946 account_id, amount
947 ),
948 ActionErrorKind::TriesToUnstake { account_id } => {
949 write!(f, "Account {:?} is not yet staked, but tries to unstake", account_id)
950 }
951 ActionErrorKind::TriesToStake { account_id, stake, locked, balance } => write!(
952 f,
953 "Account {:?} tries to stake {}, but has staked {} and only has {}",
954 account_id, stake, locked, balance
955 ),
956 ActionErrorKind::CreateAccountOnlyByRegistrar {
957 account_id,
958 registrar_account_id,
959 predecessor_id,
960 } => write!(
961 f,
962 "A top-level account ID {:?} can't be created by {:?}, short top-level account IDs can only be created by {:?}",
963 account_id, predecessor_id, registrar_account_id,
964 ),
965 ActionErrorKind::CreateAccountNotAllowed { account_id, predecessor_id } => write!(
966 f,
967 "A sub-account ID {:?} can't be created by account {:?}",
968 account_id, predecessor_id,
969 ),
970 ActionErrorKind::DeleteKeyDoesNotExist { account_id, .. } => write!(
971 f,
972 "Account {:?} tries to remove an access key that doesn't exist",
973 account_id
974 ),
975 ActionErrorKind::AddKeyAlreadyExists { public_key, .. } => write!(
976 f,
977 "The public key {:?} is already used for an existing access key",
978 public_key
979 ),
980 ActionErrorKind::DeleteAccountStaking { account_id } => {
981 write!(f, "Account {:?} is staking and can not be deleted", account_id)
982 }
983 ActionErrorKind::FunctionCallError(s) => write!(f, "{:?}", s),
984 ActionErrorKind::NewReceiptValidationError(e) => {
985 write!(f, "An new action receipt created during a FunctionCall is not valid: {}", e)
986 }
987 ActionErrorKind::InsufficientStake { account_id, stake, minimum_stake } => write!(
988 f,
989 "Account {} tries to stake {} but minimum required stake is {}",
990 account_id, stake, minimum_stake
991 ),
992 ActionErrorKind::OnlyImplicitAccountCreationAllowed { account_id } => write!(
993 f,
994 "CreateAccount action is called on hex-characters account of length 64 {}",
995 account_id
996 ),
997 ActionErrorKind::DeleteAccountWithLargeState { account_id } => write!(
998 f,
999 "The state of account {} is too large and therefore cannot be deleted",
1000 account_id
1001 ),
1002 ActionErrorKind::DelegateActionInvalidSignature => {
1003 write!(f, "DelegateAction is not signed with the given public key")
1004 }
1005 ActionErrorKind::DelegateActionSenderDoesNotMatchTxReceiver {
1006 sender_id,
1007 receiver_id,
1008 } => write!(
1009 f,
1010 "Transaction receiver {} doesn't match DelegateAction sender {}",
1011 receiver_id, sender_id
1012 ),
1013 ActionErrorKind::DelegateActionExpired => write!(f, "DelegateAction has expired"),
1014 ActionErrorKind::DelegateActionAccessKeyError(access_key_error) => {
1015 Display::fmt(&access_key_error, f)
1016 }
1017 ActionErrorKind::DelegateActionInvalidNonce { delegate_nonce, ak_nonce } => write!(
1018 f,
1019 "DelegateAction nonce {} must be larger than nonce of the used access key {}",
1020 delegate_nonce, ak_nonce
1021 ),
1022 ActionErrorKind::DelegateActionNonceTooLarge { delegate_nonce, upper_bound } => write!(
1023 f,
1024 "DelegateAction nonce {} must be smaller than the access key nonce upper bound {}",
1025 delegate_nonce, upper_bound
1026 ),
1027 ActionErrorKind::GlobalContractDoesNotExist { identifier } => {
1028 write!(f, "Global contract identifier {:?} not found", identifier)
1029 }
1030 }
1031 }
1032}
1033
1034#[derive(Eq, PartialEq, Clone)]
1035pub enum EpochError {
1036 ThresholdError {
1039 stake_sum: Balance,
1040 num_seats: u64,
1041 },
1042 EpochOutOfBounds(EpochId),
1044 MissingBlock(CryptoHash),
1046 IOErr(String),
1048 NotAValidator(AccountId, EpochId),
1050 ShardingError(String),
1052 NotEnoughValidators {
1053 num_validators: u64,
1054 num_shards: u64,
1055 },
1056 ChunkValidatorSelectionError(String),
1058 ChunkProducerSelectionError(String),
1060}
1061
1062impl std::error::Error for EpochError {}
1063
1064impl Display for EpochError {
1065 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1066 match self {
1067 EpochError::ThresholdError { stake_sum, num_seats } => write!(
1068 f,
1069 "Total stake {} must be higher than the number of seats {}",
1070 stake_sum, num_seats
1071 ),
1072 EpochError::EpochOutOfBounds(epoch_id) => {
1073 write!(f, "Epoch {:?} is out of bounds", epoch_id)
1074 }
1075 EpochError::MissingBlock(hash) => write!(f, "Missing block {}", hash),
1076 EpochError::IOErr(err) => write!(f, "IO: {}", err),
1077 EpochError::NotAValidator(account_id, epoch_id) => {
1078 write!(f, "{} is not a validator in epoch {:?}", account_id, epoch_id)
1079 }
1080 EpochError::ShardingError(err) => write!(f, "Sharding Error: {}", err),
1081 EpochError::NotEnoughValidators { num_shards, num_validators } => {
1082 write!(
1083 f,
1084 "There were not enough validator proposals to fill all shards. num_proposals: {}, num_shards: {}",
1085 num_validators, num_shards
1086 )
1087 }
1088 EpochError::ChunkValidatorSelectionError(err) => {
1089 write!(f, "Error selecting validators for a chunk: {}", err)
1090 }
1091 EpochError::ChunkProducerSelectionError(err) => {
1092 write!(f, "Error selecting chunk producer: {}", err)
1093 }
1094 }
1095 }
1096}
1097
1098impl Debug for EpochError {
1099 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1100 match self {
1101 EpochError::ThresholdError { stake_sum, num_seats } => {
1102 write!(f, "ThresholdError({}, {})", stake_sum, num_seats)
1103 }
1104 EpochError::EpochOutOfBounds(epoch_id) => write!(f, "EpochOutOfBounds({:?})", epoch_id),
1105 EpochError::MissingBlock(hash) => write!(f, "MissingBlock({})", hash),
1106 EpochError::IOErr(err) => write!(f, "IOErr({})", err),
1107 EpochError::NotAValidator(account_id, epoch_id) => {
1108 write!(f, "NotAValidator({}, {:?})", account_id, epoch_id)
1109 }
1110 EpochError::ShardingError(err) => write!(f, "ShardingError({})", err),
1111 EpochError::NotEnoughValidators { num_shards, num_validators } => {
1112 write!(f, "NotEnoughValidators({}, {})", num_validators, num_shards)
1113 }
1114 EpochError::ChunkValidatorSelectionError(err) => {
1115 write!(f, "ChunkValidatorSelectionError({})", err)
1116 }
1117 EpochError::ChunkProducerSelectionError(err) => {
1118 write!(f, "ChunkProducerSelectionError({})", err)
1119 }
1120 }
1121 }
1122}
1123
1124impl From<std::io::Error> for EpochError {
1125 fn from(error: std::io::Error) -> Self {
1126 EpochError::IOErr(error.to_string())
1127 }
1128}
1129
1130impl From<ShardLayoutError> for EpochError {
1131 fn from(error: ShardLayoutError) -> Self {
1132 EpochError::ShardingError(error.to_string())
1133 }
1134}
1135
1136#[derive(
1137 Debug,
1138 Clone,
1139 PartialEq,
1140 Eq,
1141 BorshDeserialize,
1142 BorshSerialize,
1143 serde::Deserialize,
1144 serde::Serialize,
1145 ProtocolSchema,
1146)]
1147pub enum PrepareError {
1149 Serialization,
1151 Deserialization,
1153 InternalMemoryDeclared,
1155 GasInstrumentation,
1159 StackHeightInstrumentation,
1163 Instantiate,
1168 Memory,
1170 TooManyFunctions,
1172 TooManyLocals,
1174}
1175
1176#[derive(
1178 Debug,
1179 Clone,
1180 PartialEq,
1181 Eq,
1182 BorshDeserialize,
1183 BorshSerialize,
1184 serde::Deserialize,
1185 serde::Serialize,
1186 strum::IntoStaticStr,
1187 ProtocolSchema,
1188)]
1189pub enum WasmTrap {
1190 Unreachable,
1192 IncorrectCallIndirectSignature,
1194 MemoryOutOfBounds,
1196 CallIndirectOOB,
1198 IllegalArithmetic,
1200 MisalignedAtomicAccess,
1202 IndirectCallToNull,
1204 StackOverflow,
1206 GenericTrap,
1208}
1209
1210#[derive(
1211 Debug,
1212 Clone,
1213 PartialEq,
1214 Eq,
1215 BorshDeserialize,
1216 BorshSerialize,
1217 serde::Deserialize,
1218 serde::Serialize,
1219 strum::IntoStaticStr,
1220 ProtocolSchema,
1221)]
1222pub enum HostError {
1223 BadUTF16,
1225 BadUTF8,
1227 GasExceeded,
1229 GasLimitExceeded,
1231 BalanceExceeded,
1233 EmptyMethodName,
1235 GuestPanic { panic_msg: String },
1237 IntegerOverflow,
1239 InvalidPromiseIndex { promise_idx: u64 },
1241 CannotAppendActionToJointPromise,
1243 CannotReturnJointPromise,
1245 InvalidPromiseResultIndex { result_idx: u64 },
1247 InvalidRegisterId { register_id: u64 },
1249 IteratorWasInvalidated { iterator_index: u64 },
1251 MemoryAccessViolation,
1253 InvalidReceiptIndex { receipt_index: u64 },
1255 InvalidIteratorIndex { iterator_index: u64 },
1257 InvalidAccountId,
1259 InvalidMethodName,
1261 InvalidPublicKey,
1263 ProhibitedInView { method_name: String },
1265 NumberOfLogsExceeded { limit: u64 },
1267 KeyLengthExceeded { length: u64, limit: u64 },
1269 ValueLengthExceeded { length: u64, limit: u64 },
1271 TotalLogLengthExceeded { length: u64, limit: u64 },
1273 NumberPromisesExceeded { number_of_promises: u64, limit: u64 },
1275 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 },
1277 ReturnedValueLengthExceeded { length: u64, limit: u64 },
1279 ContractSizeExceeded { size: u64, limit: u64 },
1281 Deprecated { method_name: String },
1283 ECRecoverError { msg: String },
1285 AltBn128InvalidInput { msg: String },
1288 Ed25519VerifyInvalidInput { msg: String },
1291}
1292
1293#[derive(
1294 Debug,
1295 Clone,
1296 PartialEq,
1297 Eq,
1298 BorshDeserialize,
1299 BorshSerialize,
1300 serde::Deserialize,
1301 serde::Serialize,
1302 strum::IntoStaticStr,
1303 ProtocolSchema,
1304)]
1305pub enum MethodResolveError {
1306 MethodEmptyName,
1307 MethodNotFound,
1308 MethodInvalidSignature,
1309}
1310
1311#[derive(
1312 Debug,
1313 Clone,
1314 PartialEq,
1315 Eq,
1316 BorshDeserialize,
1317 BorshSerialize,
1318 serde::Deserialize,
1319 serde::Serialize,
1320 strum::IntoStaticStr,
1321 ProtocolSchema,
1322)]
1323pub enum CompilationError {
1324 CodeDoesNotExist {
1325 account_id: AccountId,
1326 },
1327 PrepareError(PrepareError),
1328 WasmerCompileError {
1332 msg: String,
1333 },
1334}
1335
1336#[derive(
1341 Debug,
1342 Clone,
1343 PartialEq,
1344 Eq,
1345 BorshDeserialize,
1346 BorshSerialize,
1347 serde::Serialize,
1348 serde::Deserialize,
1349 ProtocolSchema,
1350)]
1351pub enum FunctionCallError {
1352 CompilationError(CompilationError),
1354 LinkError {
1358 msg: String,
1359 },
1360 MethodResolveError(MethodResolveError),
1362 WasmTrap(WasmTrap),
1366 WasmUnknownError,
1367 HostError(HostError),
1369 _EVMError,
1372 ExecutionError(String),
1373}
1374
1375#[derive(Debug)]
1376pub enum ChunkAccessError {
1377 ChunkMissing(ChunkHash),
1378}
1379
1380impl std::fmt::Display for ChunkAccessError {
1381 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1382 f.write_str(&format!("{:?}", self))
1383 }
1384}
1385
1386impl std::error::Error for ChunkAccessError {}