1use crate::hash::CryptoHash;
2use crate::serialize::dec_format;
3use crate::shard_layout::ShardLayoutError;
4use crate::sharding::ChunkHash;
5use crate::types::{AccountId, Balance, EpochId, Gas, Nonce};
6use borsh::{BorshDeserialize, BorshSerialize};
7use near_crypto::PublicKey;
8use near_primitives_core::types::ProtocolVersion;
9use near_schema_checker_lib::ProtocolSchema;
10use std::fmt::{Debug, Display};
11
12#[derive(
14 BorshSerialize,
15 BorshDeserialize,
16 Debug,
17 Clone,
18 PartialEq,
19 Eq,
20 serde::Deserialize,
21 serde::Serialize,
22 ProtocolSchema,
23)]
24pub enum TxExecutionError {
25 ActionError(ActionError),
27 InvalidTxError(InvalidTxError),
29}
30
31impl std::error::Error for TxExecutionError {}
32
33impl Display for TxExecutionError {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
35 match self {
36 TxExecutionError::ActionError(e) => write!(f, "{}", e),
37 TxExecutionError::InvalidTxError(e) => write!(f, "{}", e),
38 }
39 }
40}
41
42impl From<ActionError> for TxExecutionError {
43 fn from(error: ActionError) -> Self {
44 TxExecutionError::ActionError(error)
45 }
46}
47
48impl From<InvalidTxError> for TxExecutionError {
49 fn from(error: InvalidTxError) -> Self {
50 TxExecutionError::InvalidTxError(error)
51 }
52}
53
54#[derive(Debug, Clone, PartialEq, Eq)]
56pub enum RuntimeError {
57 UnexpectedIntegerOverflow(String),
59 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 { number_of_input_data_dependencies, limit } => write!(
395 f,
396 "The number of input data dependencies {} exceeded the limit {} in an ActionReceipt",
397 number_of_input_data_dependencies, limit
398 ),
399 ReceiptValidationError::ActionsValidation(e) => write!(f, "{}", e),
400 ReceiptValidationError::ReceiptSizeExceeded { size, limit } => write!(
401 f,
402 "The size of the receipt exceeded the limit: {} > {}",
403 size, limit
404 ),
405 }
406 }
407}
408
409impl std::error::Error for ReceiptValidationError {}
410
411impl Display for ActionsValidationError {
412 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
413 match self {
414 ActionsValidationError::DeleteActionMustBeFinal => {
415 write!(f, "The delete action must be the last action in transaction")
416 }
417 ActionsValidationError::TotalPrepaidGasExceeded { total_prepaid_gas, limit } => {
418 write!(f, "The total prepaid gas {} exceeds the limit {}", total_prepaid_gas, limit)
419 }
420 ActionsValidationError::TotalNumberOfActionsExceeded {total_number_of_actions, limit } => {
421 write!(
422 f,
423 "The total number of actions {} exceeds the limit {}",
424 total_number_of_actions, limit
425 )
426 }
427 ActionsValidationError::AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes, limit } => write!(
428 f,
429 "The total number of bytes in allowed method names {} exceeds the maximum allowed number {} in a AddKey action",
430 total_number_of_bytes, limit
431 ),
432 ActionsValidationError::AddKeyMethodNameLengthExceeded { length, limit } => write!(
433 f,
434 "The length of some method name {} exceeds the maximum allowed length {} in a AddKey action",
435 length, limit
436 ),
437 ActionsValidationError::IntegerOverflow => write!(
438 f,
439 "Integer overflow during a compute",
440 ),
441 ActionsValidationError::InvalidAccountId { account_id } => write!(
442 f,
443 "Invalid account ID `{}`",
444 account_id
445 ),
446 ActionsValidationError::ContractSizeExceeded { size, limit } => write!(
447 f,
448 "The length of the contract size {} exceeds the maximum allowed size {} in a DeployContract action",
449 size, limit
450 ),
451 ActionsValidationError::FunctionCallMethodNameLengthExceeded { length, limit } => write!(
452 f,
453 "The length of the method name {} exceeds the maximum allowed length {} in a FunctionCall action",
454 length, limit
455 ),
456 ActionsValidationError::FunctionCallArgumentsLengthExceeded { length, limit } => write!(
457 f,
458 "The length of the arguments {} exceeds the maximum allowed length {} in a FunctionCall action",
459 length, limit
460 ),
461 ActionsValidationError::UnsuitableStakingKey { public_key } => write!(
462 f,
463 "The staking key must be ristretto compatible ED25519 key. {} is provided instead.",
464 public_key,
465 ),
466 ActionsValidationError::FunctionCallZeroAttachedGas => write!(
467 f,
468 "The attached amount of gas in a FunctionCall action has to be a positive number",
469 ),
470 ActionsValidationError::DelegateActionMustBeOnlyOne => write!(
471 f,
472 "The actions can contain the ony one DelegateAction"
473 ),
474 ActionsValidationError::UnsupportedProtocolFeature { protocol_feature, version } => write!(
475 f,
476 "Transaction requires protocol feature {} / version {} which is not supported by the current protocol version",
477 protocol_feature,
478 version,
479 ),
480 }
481 }
482}
483
484impl std::error::Error for ActionsValidationError {}
485
486#[derive(
488 BorshSerialize,
489 BorshDeserialize,
490 Debug,
491 Clone,
492 PartialEq,
493 Eq,
494 serde::Deserialize,
495 serde::Serialize,
496 ProtocolSchema,
497)]
498pub struct ActionError {
499 pub index: Option<u64>,
502 pub kind: ActionErrorKind,
504}
505
506impl std::error::Error for ActionError {}
507
508#[derive(
509 BorshSerialize,
510 BorshDeserialize,
511 Debug,
512 Clone,
513 PartialEq,
514 Eq,
515 serde::Deserialize,
516 serde::Serialize,
517 ProtocolSchema,
518)]
519pub enum ActionErrorKind {
520 AccountAlreadyExists { account_id: AccountId },
522 AccountDoesNotExist { account_id: AccountId },
524 CreateAccountOnlyByRegistrar {
526 account_id: AccountId,
527 registrar_account_id: AccountId,
528 predecessor_id: AccountId,
529 },
530
531 CreateAccountNotAllowed { account_id: AccountId, predecessor_id: AccountId },
533 ActorNoPermission { account_id: AccountId, actor_id: AccountId },
536 DeleteKeyDoesNotExist { account_id: AccountId, public_key: Box<PublicKey> },
538 AddKeyAlreadyExists { account_id: AccountId, public_key: Box<PublicKey> },
540 DeleteAccountStaking { account_id: AccountId },
542 LackBalanceForState {
544 account_id: AccountId,
546 #[serde(with = "dec_format")]
548 amount: Balance,
549 },
550 TriesToUnstake { account_id: AccountId },
552 TriesToStake {
554 account_id: AccountId,
555 #[serde(with = "dec_format")]
556 stake: Balance,
557 #[serde(with = "dec_format")]
558 locked: Balance,
559 #[serde(with = "dec_format")]
560 balance: Balance,
561 },
562 InsufficientStake {
563 account_id: AccountId,
564 #[serde(with = "dec_format")]
565 stake: Balance,
566 #[serde(with = "dec_format")]
567 minimum_stake: Balance,
568 },
569 FunctionCallError(FunctionCallError),
571 NewReceiptValidationError(ReceiptValidationError),
574 OnlyImplicitAccountCreationAllowed { account_id: AccountId },
581 DeleteAccountWithLargeState { account_id: AccountId },
583 DelegateActionInvalidSignature,
585 DelegateActionSenderDoesNotMatchTxReceiver { sender_id: AccountId, receiver_id: AccountId },
587 DelegateActionExpired,
589 DelegateActionAccessKeyError(InvalidAccessKeyError),
591 DelegateActionInvalidNonce { delegate_nonce: Nonce, ak_nonce: Nonce },
593 DelegateActionNonceTooLarge { delegate_nonce: Nonce, upper_bound: Nonce },
595 NonRefundableTransferToExistingAccount { account_id: AccountId },
597}
598
599impl From<ActionErrorKind> for ActionError {
600 fn from(e: ActionErrorKind) -> ActionError {
601 ActionError { index: None, kind: e }
602 }
603}
604
605impl Display for InvalidTxError {
606 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
607 match self {
608 InvalidTxError::InvalidSignerId { signer_id } => {
609 write!(f, "Invalid signer account ID {:?} according to requirements", signer_id)
610 }
611 InvalidTxError::SignerDoesNotExist { signer_id } => {
612 write!(f, "Signer {:?} does not exist", signer_id)
613 }
614 InvalidTxError::InvalidAccessKeyError(access_key_error) => {
615 Display::fmt(&access_key_error, f)
616 }
617 InvalidTxError::InvalidNonce { tx_nonce, ak_nonce } => write!(
618 f,
619 "Transaction nonce {} must be larger than nonce of the used access key {}",
620 tx_nonce, ak_nonce
621 ),
622 InvalidTxError::InvalidReceiverId { receiver_id } => {
623 write!(f, "Invalid receiver account ID {:?} according to requirements", receiver_id)
624 }
625 InvalidTxError::InvalidSignature => {
626 write!(f, "Transaction is not signed with the given public key")
627 }
628 InvalidTxError::NotEnoughBalance { signer_id, balance, cost } => write!(
629 f,
630 "Sender {:?} does not have enough balance {} for operation costing {}",
631 signer_id, balance, cost
632 ),
633 InvalidTxError::LackBalanceForState { signer_id, amount } => {
634 write!(f, "Failed to execute, because the account {:?} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more", signer_id, amount)
635 }
636 InvalidTxError::CostOverflow => {
637 write!(f, "Transaction gas or balance cost is too high")
638 }
639 InvalidTxError::InvalidChain => {
640 write!(f, "Transaction parent block hash doesn't belong to the current chain")
641 }
642 InvalidTxError::Expired => {
643 write!(f, "Transaction has expired")
644 }
645 InvalidTxError::ActionsValidation(error) => {
646 write!(f, "Transaction actions validation error: {}", error)
647 }
648 InvalidTxError::NonceTooLarge { tx_nonce, upper_bound } => {
649 write!(
650 f,
651 "Transaction nonce {} must be smaller than the access key nonce upper bound {}",
652 tx_nonce, upper_bound
653 )
654 }
655 InvalidTxError::TransactionSizeExceeded { size, limit } => {
656 write!(f, "Size of serialized transaction {} exceeded the limit {}", size, limit)
657 }
658 InvalidTxError::InvalidTransactionVersion => {
659 write!(f, "Transaction version is invalid")
660 }
661 InvalidTxError::StorageError(error) => {
662 write!(f, "Storage error: {}", error)
663 }
664 InvalidTxError::ShardCongested { shard_id, congestion_level } => {
665 write!(f, "Shard {shard_id} is currently at congestion level {congestion_level:.3} and rejects new transactions.")
666 }
667 InvalidTxError::ShardStuck { shard_id, missed_chunks } => {
668 write!(
669 f,
670 "Shard {shard_id} missed {missed_chunks} chunks and rejects new transactions."
671 )
672 }
673 }
674 }
675}
676
677impl From<InvalidAccessKeyError> for InvalidTxError {
678 fn from(error: InvalidAccessKeyError) -> Self {
679 InvalidTxError::InvalidAccessKeyError(error)
680 }
681}
682
683impl Display for InvalidAccessKeyError {
684 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
685 match self {
686 InvalidAccessKeyError::AccessKeyNotFound { account_id, public_key } => write!(
687 f,
688 "Signer {:?} doesn't have access key with the given public_key {}",
689 account_id, public_key
690 ),
691 InvalidAccessKeyError::ReceiverMismatch { tx_receiver, ak_receiver } => write!(
692 f,
693 "Transaction receiver_id {:?} doesn't match the access key receiver_id {:?}",
694 tx_receiver, ak_receiver
695 ),
696 InvalidAccessKeyError::MethodNameMismatch { method_name } => write!(
697 f,
698 "Transaction method name {:?} isn't allowed by the access key",
699 method_name
700 ),
701 InvalidAccessKeyError::RequiresFullAccess => {
702 write!(f, "Invalid access key type. Full-access keys are required for transactions that have multiple or non-function-call actions")
703 }
704 InvalidAccessKeyError::NotEnoughAllowance {
705 account_id,
706 public_key,
707 allowance,
708 cost,
709 } => write!(
710 f,
711 "Access Key {:?}:{} does not have enough balance {} for transaction costing {}",
712 account_id, public_key, allowance, cost
713 ),
714 InvalidAccessKeyError::DepositWithFunctionCall => {
715 write!(f, "Having a deposit with a function call action is not allowed with a function call access key.")
716 }
717 }
718 }
719}
720
721impl std::error::Error for InvalidAccessKeyError {}
722
723#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, ProtocolSchema)]
725pub struct BalanceMismatchError {
726 #[serde(with = "dec_format")]
728 pub incoming_validator_rewards: Balance,
729 #[serde(with = "dec_format")]
730 pub initial_accounts_balance: Balance,
731 #[serde(with = "dec_format")]
732 pub incoming_receipts_balance: Balance,
733 #[serde(with = "dec_format")]
734 pub processed_delayed_receipts_balance: Balance,
735 #[serde(with = "dec_format")]
736 pub initial_postponed_receipts_balance: Balance,
737 #[serde(with = "dec_format")]
738 pub forwarded_buffered_receipts_balance: Balance,
739 #[serde(with = "dec_format")]
741 pub final_accounts_balance: Balance,
742 #[serde(with = "dec_format")]
743 pub outgoing_receipts_balance: Balance,
744 #[serde(with = "dec_format")]
745 pub new_delayed_receipts_balance: Balance,
746 #[serde(with = "dec_format")]
747 pub final_postponed_receipts_balance: Balance,
748 #[serde(with = "dec_format")]
749 pub tx_burnt_amount: Balance,
750 #[serde(with = "dec_format")]
751 pub slashed_burnt_amount: Balance,
752 #[serde(with = "dec_format")]
753 pub new_buffered_receipts_balance: Balance,
754 #[serde(with = "dec_format")]
755 pub other_burnt_amount: Balance,
756}
757
758impl Display for BalanceMismatchError {
759 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
760 let initial_balance = self
762 .incoming_validator_rewards
763 .saturating_add(self.initial_accounts_balance)
764 .saturating_add(self.incoming_receipts_balance)
765 .saturating_add(self.processed_delayed_receipts_balance)
766 .saturating_add(self.initial_postponed_receipts_balance)
767 .saturating_add(self.forwarded_buffered_receipts_balance);
768 let final_balance = self
769 .final_accounts_balance
770 .saturating_add(self.outgoing_receipts_balance)
771 .saturating_add(self.new_delayed_receipts_balance)
772 .saturating_add(self.final_postponed_receipts_balance)
773 .saturating_add(self.tx_burnt_amount)
774 .saturating_add(self.slashed_burnt_amount)
775 .saturating_add(self.other_burnt_amount)
776 .saturating_add(self.new_buffered_receipts_balance);
777
778 write!(
779 f,
780 "Balance Mismatch Error. The input balance {} doesn't match output balance {}\n\
781 Inputs:\n\
782 \tIncoming validator rewards sum: {}\n\
783 \tInitial accounts balance sum: {}\n\
784 \tIncoming receipts balance sum: {}\n\
785 \tProcessed delayed receipts balance sum: {}\n\
786 \tInitial postponed receipts balance sum: {}\n\
787 \tForwarded buffered receipts sum: {}\n\
788 Outputs:\n\
789 \tFinal accounts balance sum: {}\n\
790 \tOutgoing receipts balance sum: {}\n\
791 \tNew delayed receipts balance sum: {}\n\
792 \tFinal postponed receipts balance sum: {}\n\
793 \tTx fees burnt amount: {}\n\
794 \tSlashed amount: {}\n\
795 \tNew buffered receipts balance sum: {}\n\
796 \tOther burnt amount: {}",
797 initial_balance,
798 final_balance,
799 self.incoming_validator_rewards,
800 self.initial_accounts_balance,
801 self.incoming_receipts_balance,
802 self.processed_delayed_receipts_balance,
803 self.initial_postponed_receipts_balance,
804 self.forwarded_buffered_receipts_balance,
805 self.final_accounts_balance,
806 self.outgoing_receipts_balance,
807 self.new_delayed_receipts_balance,
808 self.final_postponed_receipts_balance,
809 self.tx_burnt_amount,
810 self.slashed_burnt_amount,
811 self.new_buffered_receipts_balance,
812 self.other_burnt_amount,
813 )
814 }
815}
816
817impl std::error::Error for BalanceMismatchError {}
818
819#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, ProtocolSchema)]
820pub struct IntegerOverflowError;
821
822impl std::fmt::Display for IntegerOverflowError {
823 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
824 f.write_str(&format!("{:?}", self))
825 }
826}
827
828impl std::error::Error for IntegerOverflowError {}
829
830impl From<IntegerOverflowError> for InvalidTxError {
831 fn from(_: IntegerOverflowError) -> Self {
832 InvalidTxError::CostOverflow
833 }
834}
835
836impl From<IntegerOverflowError> for RuntimeError {
837 fn from(err: IntegerOverflowError) -> Self {
838 RuntimeError::UnexpectedIntegerOverflow(err.to_string())
839 }
840}
841
842impl From<StorageError> for RuntimeError {
843 fn from(e: StorageError) -> Self {
844 RuntimeError::StorageError(e)
845 }
846}
847
848impl From<BalanceMismatchError> for RuntimeError {
849 fn from(e: BalanceMismatchError) -> Self {
850 RuntimeError::BalanceMismatchError(Box::new(e))
851 }
852}
853
854impl From<InvalidTxError> for RuntimeError {
855 fn from(e: InvalidTxError) -> Self {
856 RuntimeError::InvalidTxError(e)
857 }
858}
859
860impl From<EpochError> for RuntimeError {
861 fn from(e: EpochError) -> Self {
862 RuntimeError::ValidatorError(e)
863 }
864}
865
866impl Display for ActionError {
867 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
868 write!(f, "Action #{}: {}", self.index.unwrap_or_default(), self.kind)
869 }
870}
871
872impl Display for ActionErrorKind {
873 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
874 match self {
875 ActionErrorKind::AccountAlreadyExists { account_id } => {
876 write!(f, "Can't create a new account {:?}, because it already exists", account_id)
877 }
878 ActionErrorKind::AccountDoesNotExist { account_id } => write!(
879 f,
880 "Can't complete the action because account {:?} doesn't exist",
881 account_id
882 ),
883 ActionErrorKind::ActorNoPermission { actor_id, account_id } => write!(
884 f,
885 "Actor {:?} doesn't have permission to account {:?} to complete the action",
886 actor_id, account_id
887 ),
888 ActionErrorKind::LackBalanceForState { account_id, amount } => write!(
889 f,
890 "The account {} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more",
891 account_id, amount
892 ),
893 ActionErrorKind::TriesToUnstake { account_id } => {
894 write!(f, "Account {:?} is not yet staked, but tries to unstake", account_id)
895 }
896 ActionErrorKind::TriesToStake { account_id, stake, locked, balance } => write!(
897 f,
898 "Account {:?} tries to stake {}, but has staked {} and only has {}",
899 account_id, stake, locked, balance
900 ),
901 ActionErrorKind::CreateAccountOnlyByRegistrar { account_id, registrar_account_id, predecessor_id } => write!(
902 f,
903 "A top-level account ID {:?} can't be created by {:?}, short top-level account IDs can only be created by {:?}",
904 account_id, predecessor_id, registrar_account_id,
905 ),
906 ActionErrorKind::CreateAccountNotAllowed { account_id, predecessor_id } => write!(
907 f,
908 "A sub-account ID {:?} can't be created by account {:?}",
909 account_id, predecessor_id,
910 ),
911 ActionErrorKind::DeleteKeyDoesNotExist { account_id, .. } => write!(
912 f,
913 "Account {:?} tries to remove an access key that doesn't exist",
914 account_id
915 ),
916 ActionErrorKind::AddKeyAlreadyExists { public_key, .. } => write!(
917 f,
918 "The public key {:?} is already used for an existing access key",
919 public_key
920 ),
921 ActionErrorKind::DeleteAccountStaking { account_id } => {
922 write!(f, "Account {:?} is staking and can not be deleted", account_id)
923 }
924 ActionErrorKind::FunctionCallError(s) => write!(f, "{:?}", s),
925 ActionErrorKind::NewReceiptValidationError(e) => {
926 write!(f, "An new action receipt created during a FunctionCall is not valid: {}", e)
927 }
928 ActionErrorKind::InsufficientStake { account_id, stake, minimum_stake } => write!(f, "Account {} tries to stake {} but minimum required stake is {}", account_id, stake, minimum_stake),
929 ActionErrorKind::OnlyImplicitAccountCreationAllowed { account_id } => write!(f, "CreateAccount action is called on hex-characters account of length 64 {}", account_id),
930 ActionErrorKind::DeleteAccountWithLargeState { account_id } => write!(f, "The state of account {} is too large and therefore cannot be deleted", account_id),
931 ActionErrorKind::DelegateActionInvalidSignature => write!(f, "DelegateAction is not signed with the given public key"),
932 ActionErrorKind::DelegateActionSenderDoesNotMatchTxReceiver { sender_id, receiver_id } => write!(f, "Transaction receiver {} doesn't match DelegateAction sender {}", receiver_id, sender_id),
933 ActionErrorKind::DelegateActionExpired => write!(f, "DelegateAction has expired"),
934 ActionErrorKind::DelegateActionAccessKeyError(access_key_error) => Display::fmt(&access_key_error, f),
935 ActionErrorKind::DelegateActionInvalidNonce { delegate_nonce, ak_nonce } => write!(f, "DelegateAction nonce {} must be larger than nonce of the used access key {}", delegate_nonce, ak_nonce),
936 ActionErrorKind::DelegateActionNonceTooLarge { delegate_nonce, upper_bound } => write!(f, "DelegateAction nonce {} must be smaller than the access key nonce upper bound {}", delegate_nonce, upper_bound),
937 ActionErrorKind::NonRefundableTransferToExistingAccount { account_id} => {
938 write!(f, "Can't make non-refundable storage transfer to {} because it already exists", account_id)
939 }
940 }
941 }
942}
943
944#[derive(Eq, PartialEq, Clone)]
945pub enum EpochError {
946 ThresholdError {
949 stake_sum: Balance,
950 num_seats: u64,
951 },
952 EpochOutOfBounds(EpochId),
954 MissingBlock(CryptoHash),
956 IOErr(String),
958 NotAValidator(AccountId, EpochId),
960 ShardingError(String),
962 NotEnoughValidators {
963 num_validators: u64,
964 num_shards: u64,
965 },
966 ChunkValidatorSelectionError(String),
968 ChunkProducerSelectionError(String),
970}
971
972impl std::error::Error for EpochError {}
973
974impl Display for EpochError {
975 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
976 match self {
977 EpochError::ThresholdError { stake_sum, num_seats } => write!(
978 f,
979 "Total stake {} must be higher than the number of seats {}",
980 stake_sum, num_seats
981 ),
982 EpochError::EpochOutOfBounds(epoch_id) => {
983 write!(f, "Epoch {:?} is out of bounds", epoch_id)
984 }
985 EpochError::MissingBlock(hash) => write!(f, "Missing block {}", hash),
986 EpochError::IOErr(err) => write!(f, "IO: {}", err),
987 EpochError::NotAValidator(account_id, epoch_id) => {
988 write!(f, "{} is not a validator in epoch {:?}", account_id, epoch_id)
989 }
990 EpochError::ShardingError(err) => write!(f, "Sharding Error: {}", err),
991 EpochError::NotEnoughValidators { num_shards, num_validators } => {
992 write!(f, "There were not enough validator proposals to fill all shards. num_proposals: {}, num_shards: {}", num_validators, num_shards)
993 }
994 EpochError::ChunkValidatorSelectionError(err) => {
995 write!(f, "Error selecting validators for a chunk: {}", err)
996 }
997 EpochError::ChunkProducerSelectionError(err) => {
998 write!(f, "Error selecting chunk producer: {}", err)
999 }
1000 }
1001 }
1002}
1003
1004impl Debug for EpochError {
1005 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1006 match self {
1007 EpochError::ThresholdError { stake_sum, num_seats } => {
1008 write!(f, "ThresholdError({}, {})", stake_sum, num_seats)
1009 }
1010 EpochError::EpochOutOfBounds(epoch_id) => write!(f, "EpochOutOfBounds({:?})", epoch_id),
1011 EpochError::MissingBlock(hash) => write!(f, "MissingBlock({})", hash),
1012 EpochError::IOErr(err) => write!(f, "IOErr({})", err),
1013 EpochError::NotAValidator(account_id, epoch_id) => {
1014 write!(f, "NotAValidator({}, {:?})", account_id, epoch_id)
1015 }
1016 EpochError::ShardingError(err) => write!(f, "ShardingError({})", err),
1017 EpochError::NotEnoughValidators { num_shards, num_validators } => {
1018 write!(f, "NotEnoughValidators({}, {})", num_validators, num_shards)
1019 }
1020 EpochError::ChunkValidatorSelectionError(err) => {
1021 write!(f, "ChunkValidatorSelectionError({})", err)
1022 }
1023 EpochError::ChunkProducerSelectionError(err) => {
1024 write!(f, "ChunkProducerSelectionError({})", err)
1025 }
1026 }
1027 }
1028}
1029
1030impl From<std::io::Error> for EpochError {
1031 fn from(error: std::io::Error) -> Self {
1032 EpochError::IOErr(error.to_string())
1033 }
1034}
1035
1036impl From<ShardLayoutError> for EpochError {
1037 fn from(error: ShardLayoutError) -> Self {
1038 EpochError::ShardingError(error.to_string())
1039 }
1040}
1041
1042#[derive(
1043 Debug,
1044 Clone,
1045 PartialEq,
1046 Eq,
1047 BorshDeserialize,
1048 BorshSerialize,
1049 serde::Deserialize,
1050 serde::Serialize,
1051 ProtocolSchema,
1052)]
1053pub enum PrepareError {
1055 Serialization,
1057 Deserialization,
1059 InternalMemoryDeclared,
1061 GasInstrumentation,
1065 StackHeightInstrumentation,
1069 Instantiate,
1074 Memory,
1076 TooManyFunctions,
1078 TooManyLocals,
1080}
1081
1082#[derive(
1084 Debug,
1085 Clone,
1086 PartialEq,
1087 Eq,
1088 BorshDeserialize,
1089 BorshSerialize,
1090 serde::Deserialize,
1091 serde::Serialize,
1092 strum::IntoStaticStr,
1093 ProtocolSchema,
1094)]
1095pub enum WasmTrap {
1096 Unreachable,
1098 IncorrectCallIndirectSignature,
1100 MemoryOutOfBounds,
1102 CallIndirectOOB,
1104 IllegalArithmetic,
1106 MisalignedAtomicAccess,
1108 IndirectCallToNull,
1110 StackOverflow,
1112 GenericTrap,
1114}
1115
1116#[derive(
1117 Debug,
1118 Clone,
1119 PartialEq,
1120 Eq,
1121 BorshDeserialize,
1122 BorshSerialize,
1123 serde::Deserialize,
1124 serde::Serialize,
1125 strum::IntoStaticStr,
1126 ProtocolSchema,
1127)]
1128pub enum HostError {
1129 BadUTF16,
1131 BadUTF8,
1133 GasExceeded,
1135 GasLimitExceeded,
1137 BalanceExceeded,
1139 EmptyMethodName,
1141 GuestPanic { panic_msg: String },
1143 IntegerOverflow,
1145 InvalidPromiseIndex { promise_idx: u64 },
1147 CannotAppendActionToJointPromise,
1149 CannotReturnJointPromise,
1151 InvalidPromiseResultIndex { result_idx: u64 },
1153 InvalidRegisterId { register_id: u64 },
1155 IteratorWasInvalidated { iterator_index: u64 },
1157 MemoryAccessViolation,
1159 InvalidReceiptIndex { receipt_index: u64 },
1161 InvalidIteratorIndex { iterator_index: u64 },
1163 InvalidAccountId,
1165 InvalidMethodName,
1167 InvalidPublicKey,
1169 ProhibitedInView { method_name: String },
1171 NumberOfLogsExceeded { limit: u64 },
1173 KeyLengthExceeded { length: u64, limit: u64 },
1175 ValueLengthExceeded { length: u64, limit: u64 },
1177 TotalLogLengthExceeded { length: u64, limit: u64 },
1179 NumberPromisesExceeded { number_of_promises: u64, limit: u64 },
1181 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 },
1183 ReturnedValueLengthExceeded { length: u64, limit: u64 },
1185 ContractSizeExceeded { size: u64, limit: u64 },
1187 Deprecated { method_name: String },
1189 ECRecoverError { msg: String },
1191 AltBn128InvalidInput { msg: String },
1194 Ed25519VerifyInvalidInput { msg: String },
1197}
1198
1199#[derive(
1200 Debug,
1201 Clone,
1202 PartialEq,
1203 Eq,
1204 BorshDeserialize,
1205 BorshSerialize,
1206 serde::Deserialize,
1207 serde::Serialize,
1208 strum::IntoStaticStr,
1209 ProtocolSchema,
1210)]
1211pub enum MethodResolveError {
1212 MethodEmptyName,
1213 MethodNotFound,
1214 MethodInvalidSignature,
1215}
1216
1217#[derive(
1218 Debug,
1219 Clone,
1220 PartialEq,
1221 Eq,
1222 BorshDeserialize,
1223 BorshSerialize,
1224 serde::Deserialize,
1225 serde::Serialize,
1226 strum::IntoStaticStr,
1227 ProtocolSchema,
1228)]
1229pub enum CompilationError {
1230 CodeDoesNotExist {
1231 account_id: AccountId,
1232 },
1233 PrepareError(PrepareError),
1234 WasmerCompileError {
1238 msg: String,
1239 },
1240}
1241
1242#[derive(
1247 Debug,
1248 Clone,
1249 PartialEq,
1250 Eq,
1251 BorshDeserialize,
1252 BorshSerialize,
1253 serde::Serialize,
1254 serde::Deserialize,
1255 ProtocolSchema,
1256)]
1257pub enum FunctionCallError {
1258 CompilationError(CompilationError),
1260 LinkError {
1264 msg: String,
1265 },
1266 MethodResolveError(MethodResolveError),
1268 WasmTrap(WasmTrap),
1272 WasmUnknownError,
1273 HostError(HostError),
1275 _EVMError,
1278 ExecutionError(String),
1279}
1280
1281#[derive(Debug)]
1282pub enum ChunkAccessError {
1283 ChunkMissing(ChunkHash),
1284}
1285
1286impl std::fmt::Display for ChunkAccessError {
1287 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1288 f.write_str(&format!("{:?}", self))
1289 }
1290}
1291
1292impl std::error::Error for ChunkAccessError {}