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),
61 StorageError(StorageError),
64 BalanceMismatchError(Box<BalanceMismatchError>),
66 ReceiptValidationError(ReceiptValidationError),
68 ValidatorError(EpochError),
70}
71
72impl std::fmt::Display for RuntimeError {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
74 f.write_str(&format!("{:?}", self))
75 }
76}
77
78impl std::error::Error for RuntimeError {}
79
80#[derive(
82 Debug,
83 Clone,
84 PartialEq,
85 Eq,
86 serde::Deserialize,
87 serde::Serialize,
88 BorshSerialize,
89 BorshDeserialize,
90 ProtocolSchema,
91)]
92pub enum MissingTrieValueContext {
93 TrieIterator,
95 TriePrefetchingStorage,
97 TrieMemoryPartialStorage,
99 TrieStorage,
101}
102
103impl MissingTrieValueContext {
104 pub fn metrics_label(&self) -> &str {
105 match self {
106 Self::TrieIterator => "trie_iterator",
107 Self::TriePrefetchingStorage => "trie_prefetching_storage",
108 Self::TrieMemoryPartialStorage => "trie_memory_partial_storage",
109 Self::TrieStorage => "trie_storage",
110 }
111 }
112}
113
114#[derive(
117 Debug,
118 Clone,
119 PartialEq,
120 Eq,
121 serde::Deserialize,
122 serde::Serialize,
123 BorshSerialize,
124 BorshDeserialize,
125 ProtocolSchema,
126)]
127pub enum StorageError {
128 StorageInternalError,
130 MissingTrieValue(MissingTrieValueContext, CryptoHash),
132 UnexpectedTrieValue,
136 StorageInconsistentState(String),
142 FlatStorageBlockNotSupported(String),
146 MemTrieLoadingError(String),
148 FlatStorageReshardingAlreadyInProgress,
151}
152
153impl std::fmt::Display for StorageError {
154 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
155 f.write_str(&format!("{:?}", self))
156 }
157}
158
159impl std::error::Error for StorageError {}
160
161#[derive(
163 BorshSerialize,
164 BorshDeserialize,
165 Debug,
166 Clone,
167 PartialEq,
168 Eq,
169 serde::Deserialize,
170 serde::Serialize,
171 ProtocolSchema,
172)]
173pub enum InvalidTxError {
174 InvalidAccessKeyError(InvalidAccessKeyError),
176 InvalidSignerId {
178 signer_id: String,
179 },
180 SignerDoesNotExist {
182 signer_id: AccountId,
183 },
184 InvalidNonce {
186 tx_nonce: Nonce,
187 ak_nonce: Nonce,
188 },
189 NonceTooLarge {
191 tx_nonce: Nonce,
192 upper_bound: Nonce,
193 },
194 InvalidReceiverId {
196 receiver_id: String,
197 },
198 InvalidSignature,
200 NotEnoughBalance {
202 signer_id: AccountId,
203 #[serde(with = "dec_format")]
204 balance: Balance,
205 #[serde(with = "dec_format")]
206 cost: Balance,
207 },
208 LackBalanceForState {
210 signer_id: AccountId,
212 #[serde(with = "dec_format")]
214 amount: Balance,
215 },
216 CostOverflow,
218 InvalidChain,
220 Expired,
222 ActionsValidation(ActionsValidationError),
224 TransactionSizeExceeded {
226 size: u64,
227 limit: u64,
228 },
229 InvalidTransactionVersion,
231 StorageError(StorageError),
233 ShardCongested {
236 shard_id: u32,
238 congestion_level: ordered_float::NotNan<f64>,
240 },
241 ShardStuck {
244 shard_id: u32,
246 missed_chunks: u64,
248 },
249}
250
251impl From<StorageError> for InvalidTxError {
252 fn from(error: StorageError) -> Self {
253 InvalidTxError::StorageError(error)
254 }
255}
256
257impl std::error::Error for InvalidTxError {}
258
259#[derive(
260 BorshSerialize,
261 BorshDeserialize,
262 Debug,
263 Clone,
264 PartialEq,
265 Eq,
266 serde::Deserialize,
267 serde::Serialize,
268 ProtocolSchema,
269)]
270pub enum InvalidAccessKeyError {
271 AccessKeyNotFound { account_id: AccountId, public_key: Box<PublicKey> },
273 ReceiverMismatch { tx_receiver: AccountId, ak_receiver: String },
275 MethodNameMismatch { method_name: String },
277 RequiresFullAccess,
279 NotEnoughAllowance {
281 account_id: AccountId,
282 public_key: Box<PublicKey>,
283 #[serde(with = "dec_format")]
284 allowance: Balance,
285 #[serde(with = "dec_format")]
286 cost: Balance,
287 },
288 DepositWithFunctionCall,
290}
291
292#[derive(
294 BorshSerialize,
295 BorshDeserialize,
296 Debug,
297 Clone,
298 PartialEq,
299 Eq,
300 serde::Serialize,
301 serde::Deserialize,
302 ProtocolSchema,
303)]
304pub enum ActionsValidationError {
305 DeleteActionMustBeFinal,
307 TotalPrepaidGasExceeded { total_prepaid_gas: Gas, limit: Gas },
309 TotalNumberOfActionsExceeded { total_number_of_actions: u64, limit: u64 },
311 AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes: u64, limit: u64 },
313 AddKeyMethodNameLengthExceeded { length: u64, limit: u64 },
315 IntegerOverflow,
317 InvalidAccountId { account_id: String },
319 ContractSizeExceeded { size: u64, limit: u64 },
321 FunctionCallMethodNameLengthExceeded { length: u64, limit: u64 },
323 FunctionCallArgumentsLengthExceeded { length: u64, limit: u64 },
325 UnsuitableStakingKey { public_key: Box<PublicKey> },
327 FunctionCallZeroAttachedGas,
329 DelegateActionMustBeOnlyOne,
331 UnsupportedProtocolFeature { protocol_feature: String, version: ProtocolVersion },
338}
339
340#[derive(
342 BorshSerialize,
343 BorshDeserialize,
344 Debug,
345 Clone,
346 PartialEq,
347 Eq,
348 serde::Serialize,
349 serde::Deserialize,
350 ProtocolSchema,
351)]
352pub enum ReceiptValidationError {
353 InvalidPredecessorId { account_id: String },
355 InvalidReceiverId { account_id: String },
357 InvalidSignerId { account_id: String },
359 InvalidDataReceiverId { account_id: String },
361 ReturnedValueLengthExceeded { length: u64, limit: u64 },
363 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 },
365 ActionsValidation(ActionsValidationError),
367 ReceiptSizeExceeded { size: u64, limit: u64 },
369}
370
371impl Display for ReceiptValidationError {
372 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
373 match self {
374 ReceiptValidationError::InvalidPredecessorId { account_id } => {
375 write!(f, "The predecessor_id `{}` of a Receipt is not valid.", account_id)
376 }
377 ReceiptValidationError::InvalidReceiverId { account_id } => {
378 write!(f, "The receiver_id `{}` of a Receipt is not valid.", account_id)
379 }
380 ReceiptValidationError::InvalidSignerId { account_id } => {
381 write!(f, "The signer_id `{}` of an ActionReceipt is not valid.", account_id)
382 }
383 ReceiptValidationError::InvalidDataReceiverId { account_id } => write!(
384 f,
385 "The receiver_id `{}` of a DataReceiver within an ActionReceipt is not valid.",
386 account_id
387 ),
388 ReceiptValidationError::ReturnedValueLengthExceeded { length, limit } => write!(
389 f,
390 "The length of the returned data {} exceeded the limit {} in a DataReceipt",
391 length, limit
392 ),
393 ReceiptValidationError::NumberInputDataDependenciesExceeded { number_of_input_data_dependencies, limit } => write!(
394 f,
395 "The number of input data dependencies {} exceeded the limit {} in an ActionReceipt",
396 number_of_input_data_dependencies, limit
397 ),
398 ReceiptValidationError::ActionsValidation(e) => write!(f, "{}", e),
399 ReceiptValidationError::ReceiptSizeExceeded { size, limit } => write!(
400 f,
401 "The size of the receipt exceeded the limit: {} > {}",
402 size, limit
403 ),
404 }
405 }
406}
407
408impl std::error::Error for ReceiptValidationError {}
409
410impl Display for ActionsValidationError {
411 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
412 match self {
413 ActionsValidationError::DeleteActionMustBeFinal => {
414 write!(f, "The delete action must be the last action in transaction")
415 }
416 ActionsValidationError::TotalPrepaidGasExceeded { total_prepaid_gas, limit } => {
417 write!(f, "The total prepaid gas {} exceeds the limit {}", total_prepaid_gas, limit)
418 }
419 ActionsValidationError::TotalNumberOfActionsExceeded {total_number_of_actions, limit } => {
420 write!(
421 f,
422 "The total number of actions {} exceeds the limit {}",
423 total_number_of_actions, limit
424 )
425 }
426 ActionsValidationError::AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes, limit } => write!(
427 f,
428 "The total number of bytes in allowed method names {} exceeds the maximum allowed number {} in a AddKey action",
429 total_number_of_bytes, limit
430 ),
431 ActionsValidationError::AddKeyMethodNameLengthExceeded { length, limit } => write!(
432 f,
433 "The length of some method name {} exceeds the maximum allowed length {} in a AddKey action",
434 length, limit
435 ),
436 ActionsValidationError::IntegerOverflow => write!(
437 f,
438 "Integer overflow during a compute",
439 ),
440 ActionsValidationError::InvalidAccountId { account_id } => write!(
441 f,
442 "Invalid account ID `{}`",
443 account_id
444 ),
445 ActionsValidationError::ContractSizeExceeded { size, limit } => write!(
446 f,
447 "The length of the contract size {} exceeds the maximum allowed size {} in a DeployContract action",
448 size, limit
449 ),
450 ActionsValidationError::FunctionCallMethodNameLengthExceeded { length, limit } => write!(
451 f,
452 "The length of the method name {} exceeds the maximum allowed length {} in a FunctionCall action",
453 length, limit
454 ),
455 ActionsValidationError::FunctionCallArgumentsLengthExceeded { length, limit } => write!(
456 f,
457 "The length of the arguments {} exceeds the maximum allowed length {} in a FunctionCall action",
458 length, limit
459 ),
460 ActionsValidationError::UnsuitableStakingKey { public_key } => write!(
461 f,
462 "The staking key must be ristretto compatible ED25519 key. {} is provided instead.",
463 public_key,
464 ),
465 ActionsValidationError::FunctionCallZeroAttachedGas => write!(
466 f,
467 "The attached amount of gas in a FunctionCall action has to be a positive number",
468 ),
469 ActionsValidationError::DelegateActionMustBeOnlyOne => write!(
470 f,
471 "The actions can contain the ony one DelegateAction"
472 ),
473 ActionsValidationError::UnsupportedProtocolFeature { protocol_feature, version } => write!(
474 f,
475 "Transaction requires protocol feature {} / version {} which is not supported by the current protocol version",
476 protocol_feature,
477 version,
478 ),
479 }
480 }
481}
482
483impl std::error::Error for ActionsValidationError {}
484
485#[derive(
487 BorshSerialize,
488 BorshDeserialize,
489 Debug,
490 Clone,
491 PartialEq,
492 Eq,
493 serde::Deserialize,
494 serde::Serialize,
495 ProtocolSchema,
496)]
497pub struct ActionError {
498 pub index: Option<u64>,
501 pub kind: ActionErrorKind,
503}
504
505impl std::error::Error for ActionError {}
506
507#[derive(
508 BorshSerialize,
509 BorshDeserialize,
510 Debug,
511 Clone,
512 PartialEq,
513 Eq,
514 serde::Deserialize,
515 serde::Serialize,
516 ProtocolSchema,
517)]
518pub enum ActionErrorKind {
519 AccountAlreadyExists { account_id: AccountId },
521 AccountDoesNotExist { account_id: AccountId },
523 CreateAccountOnlyByRegistrar {
525 account_id: AccountId,
526 registrar_account_id: AccountId,
527 predecessor_id: AccountId,
528 },
529
530 CreateAccountNotAllowed { account_id: AccountId, predecessor_id: AccountId },
532 ActorNoPermission { account_id: AccountId, actor_id: AccountId },
535 DeleteKeyDoesNotExist { account_id: AccountId, public_key: Box<PublicKey> },
537 AddKeyAlreadyExists { account_id: AccountId, public_key: Box<PublicKey> },
539 DeleteAccountStaking { account_id: AccountId },
541 LackBalanceForState {
543 account_id: AccountId,
545 #[serde(with = "dec_format")]
547 amount: Balance,
548 },
549 TriesToUnstake { account_id: AccountId },
551 TriesToStake {
553 account_id: AccountId,
554 #[serde(with = "dec_format")]
555 stake: Balance,
556 #[serde(with = "dec_format")]
557 locked: Balance,
558 #[serde(with = "dec_format")]
559 balance: Balance,
560 },
561 InsufficientStake {
562 account_id: AccountId,
563 #[serde(with = "dec_format")]
564 stake: Balance,
565 #[serde(with = "dec_format")]
566 minimum_stake: Balance,
567 },
568 FunctionCallError(FunctionCallError),
570 NewReceiptValidationError(ReceiptValidationError),
573 OnlyImplicitAccountCreationAllowed { account_id: AccountId },
580 DeleteAccountWithLargeState { account_id: AccountId },
582 DelegateActionInvalidSignature,
584 DelegateActionSenderDoesNotMatchTxReceiver { sender_id: AccountId, receiver_id: AccountId },
586 DelegateActionExpired,
588 DelegateActionAccessKeyError(InvalidAccessKeyError),
590 DelegateActionInvalidNonce { delegate_nonce: Nonce, ak_nonce: Nonce },
592 DelegateActionNonceTooLarge { delegate_nonce: Nonce, upper_bound: Nonce },
594 NonRefundableTransferToExistingAccount { account_id: AccountId },
596}
597
598impl From<ActionErrorKind> for ActionError {
599 fn from(e: ActionErrorKind) -> ActionError {
600 ActionError { index: None, kind: e }
601 }
602}
603
604impl Display for InvalidTxError {
605 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
606 match self {
607 InvalidTxError::InvalidSignerId { signer_id } => {
608 write!(f, "Invalid signer account ID {:?} according to requirements", signer_id)
609 }
610 InvalidTxError::SignerDoesNotExist { signer_id } => {
611 write!(f, "Signer {:?} does not exist", signer_id)
612 }
613 InvalidTxError::InvalidAccessKeyError(access_key_error) => {
614 Display::fmt(&access_key_error, f)
615 }
616 InvalidTxError::InvalidNonce { tx_nonce, ak_nonce } => write!(
617 f,
618 "Transaction nonce {} must be larger than nonce of the used access key {}",
619 tx_nonce, ak_nonce
620 ),
621 InvalidTxError::InvalidReceiverId { receiver_id } => {
622 write!(f, "Invalid receiver account ID {:?} according to requirements", receiver_id)
623 }
624 InvalidTxError::InvalidSignature => {
625 write!(f, "Transaction is not signed with the given public key")
626 }
627 InvalidTxError::NotEnoughBalance { signer_id, balance, cost } => write!(
628 f,
629 "Sender {:?} does not have enough balance {} for operation costing {}",
630 signer_id, balance, cost
631 ),
632 InvalidTxError::LackBalanceForState { signer_id, amount } => {
633 write!(f, "Failed to execute, because the account {:?} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more", signer_id, amount)
634 }
635 InvalidTxError::CostOverflow => {
636 write!(f, "Transaction gas or balance cost is too high")
637 }
638 InvalidTxError::InvalidChain => {
639 write!(f, "Transaction parent block hash doesn't belong to the current chain")
640 }
641 InvalidTxError::Expired => {
642 write!(f, "Transaction has expired")
643 }
644 InvalidTxError::ActionsValidation(error) => {
645 write!(f, "Transaction actions validation error: {}", error)
646 }
647 InvalidTxError::NonceTooLarge { tx_nonce, upper_bound } => {
648 write!(
649 f,
650 "Transaction nonce {} must be smaller than the access key nonce upper bound {}",
651 tx_nonce, upper_bound
652 )
653 }
654 InvalidTxError::TransactionSizeExceeded { size, limit } => {
655 write!(f, "Size of serialized transaction {} exceeded the limit {}", size, limit)
656 }
657 InvalidTxError::InvalidTransactionVersion => {
658 write!(f, "Transaction version is invalid")
659 }
660 InvalidTxError::StorageError(error) => {
661 write!(f, "Storage error: {}", error)
662 }
663 InvalidTxError::ShardCongested { shard_id, congestion_level } => {
664 write!(f, "Shard {shard_id} is currently at congestion level {congestion_level:.3} and rejects new transactions.")
665 }
666 InvalidTxError::ShardStuck { shard_id, missed_chunks } => {
667 write!(
668 f,
669 "Shard {shard_id} missed {missed_chunks} chunks and rejects new transactions."
670 )
671 }
672 }
673 }
674}
675
676impl From<InvalidAccessKeyError> for InvalidTxError {
677 fn from(error: InvalidAccessKeyError) -> Self {
678 InvalidTxError::InvalidAccessKeyError(error)
679 }
680}
681
682impl Display for InvalidAccessKeyError {
683 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
684 match self {
685 InvalidAccessKeyError::AccessKeyNotFound { account_id, public_key } => write!(
686 f,
687 "Signer {:?} doesn't have access key with the given public_key {}",
688 account_id, public_key
689 ),
690 InvalidAccessKeyError::ReceiverMismatch { tx_receiver, ak_receiver } => write!(
691 f,
692 "Transaction receiver_id {:?} doesn't match the access key receiver_id {:?}",
693 tx_receiver, ak_receiver
694 ),
695 InvalidAccessKeyError::MethodNameMismatch { method_name } => write!(
696 f,
697 "Transaction method name {:?} isn't allowed by the access key",
698 method_name
699 ),
700 InvalidAccessKeyError::RequiresFullAccess => {
701 write!(f, "Invalid access key type. Full-access keys are required for transactions that have multiple or non-function-call actions")
702 }
703 InvalidAccessKeyError::NotEnoughAllowance {
704 account_id,
705 public_key,
706 allowance,
707 cost,
708 } => write!(
709 f,
710 "Access Key {:?}:{} does not have enough balance {} for transaction costing {}",
711 account_id, public_key, allowance, cost
712 ),
713 InvalidAccessKeyError::DepositWithFunctionCall => {
714 write!(f, "Having a deposit with a function call action is not allowed with a function call access key.")
715 }
716 }
717 }
718}
719
720impl std::error::Error for InvalidAccessKeyError {}
721
722#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, ProtocolSchema)]
724pub struct BalanceMismatchError {
725 #[serde(with = "dec_format")]
727 pub incoming_validator_rewards: Balance,
728 #[serde(with = "dec_format")]
729 pub initial_accounts_balance: Balance,
730 #[serde(with = "dec_format")]
731 pub incoming_receipts_balance: Balance,
732 #[serde(with = "dec_format")]
733 pub processed_delayed_receipts_balance: Balance,
734 #[serde(with = "dec_format")]
735 pub initial_postponed_receipts_balance: Balance,
736 #[serde(with = "dec_format")]
737 pub forwarded_buffered_receipts_balance: Balance,
738 #[serde(with = "dec_format")]
740 pub final_accounts_balance: Balance,
741 #[serde(with = "dec_format")]
742 pub outgoing_receipts_balance: Balance,
743 #[serde(with = "dec_format")]
744 pub new_delayed_receipts_balance: Balance,
745 #[serde(with = "dec_format")]
746 pub final_postponed_receipts_balance: Balance,
747 #[serde(with = "dec_format")]
748 pub tx_burnt_amount: Balance,
749 #[serde(with = "dec_format")]
750 pub slashed_burnt_amount: Balance,
751 #[serde(with = "dec_format")]
752 pub new_buffered_receipts_balance: Balance,
753 #[serde(with = "dec_format")]
754 pub other_burnt_amount: Balance,
755}
756
757impl Display for BalanceMismatchError {
758 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
759 let initial_balance = self
761 .incoming_validator_rewards
762 .saturating_add(self.initial_accounts_balance)
763 .saturating_add(self.incoming_receipts_balance)
764 .saturating_add(self.processed_delayed_receipts_balance)
765 .saturating_add(self.initial_postponed_receipts_balance)
766 .saturating_add(self.forwarded_buffered_receipts_balance);
767 let final_balance = self
768 .final_accounts_balance
769 .saturating_add(self.outgoing_receipts_balance)
770 .saturating_add(self.new_delayed_receipts_balance)
771 .saturating_add(self.final_postponed_receipts_balance)
772 .saturating_add(self.tx_burnt_amount)
773 .saturating_add(self.slashed_burnt_amount)
774 .saturating_add(self.other_burnt_amount)
775 .saturating_add(self.new_buffered_receipts_balance);
776
777 write!(
778 f,
779 "Balance Mismatch Error. The input balance {} doesn't match output balance {}\n\
780 Inputs:\n\
781 \tIncoming validator rewards sum: {}\n\
782 \tInitial accounts balance sum: {}\n\
783 \tIncoming receipts balance sum: {}\n\
784 \tProcessed delayed receipts balance sum: {}\n\
785 \tInitial postponed receipts balance sum: {}\n\
786 \tForwarded buffered receipts sum: {}\n\
787 Outputs:\n\
788 \tFinal accounts balance sum: {}\n\
789 \tOutgoing receipts balance sum: {}\n\
790 \tNew delayed receipts balance sum: {}\n\
791 \tFinal postponed receipts balance sum: {}\n\
792 \tTx fees burnt amount: {}\n\
793 \tSlashed amount: {}\n\
794 \tNew buffered receipts balance sum: {}\n\
795 \tOther burnt amount: {}",
796 initial_balance,
797 final_balance,
798 self.incoming_validator_rewards,
799 self.initial_accounts_balance,
800 self.incoming_receipts_balance,
801 self.processed_delayed_receipts_balance,
802 self.initial_postponed_receipts_balance,
803 self.forwarded_buffered_receipts_balance,
804 self.final_accounts_balance,
805 self.outgoing_receipts_balance,
806 self.new_delayed_receipts_balance,
807 self.final_postponed_receipts_balance,
808 self.tx_burnt_amount,
809 self.slashed_burnt_amount,
810 self.new_buffered_receipts_balance,
811 self.other_burnt_amount,
812 )
813 }
814}
815
816impl std::error::Error for BalanceMismatchError {}
817
818#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, ProtocolSchema)]
819pub struct IntegerOverflowError;
820
821impl std::fmt::Display for IntegerOverflowError {
822 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
823 f.write_str(&format!("{:?}", self))
824 }
825}
826
827impl std::error::Error for IntegerOverflowError {}
828
829impl From<IntegerOverflowError> for InvalidTxError {
830 fn from(_: IntegerOverflowError) -> Self {
831 InvalidTxError::CostOverflow
832 }
833}
834
835impl From<IntegerOverflowError> for RuntimeError {
836 fn from(err: IntegerOverflowError) -> Self {
837 RuntimeError::UnexpectedIntegerOverflow(err.to_string())
838 }
839}
840
841impl From<StorageError> for RuntimeError {
842 fn from(e: StorageError) -> Self {
843 RuntimeError::StorageError(e)
844 }
845}
846
847impl From<BalanceMismatchError> for RuntimeError {
848 fn from(e: BalanceMismatchError) -> Self {
849 RuntimeError::BalanceMismatchError(Box::new(e))
850 }
851}
852
853impl From<InvalidTxError> for RuntimeError {
854 fn from(e: InvalidTxError) -> Self {
855 RuntimeError::InvalidTxError(e)
856 }
857}
858
859impl From<EpochError> for RuntimeError {
860 fn from(e: EpochError) -> Self {
861 RuntimeError::ValidatorError(e)
862 }
863}
864
865impl Display for ActionError {
866 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
867 write!(f, "Action #{}: {}", self.index.unwrap_or_default(), self.kind)
868 }
869}
870
871impl Display for ActionErrorKind {
872 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
873 match self {
874 ActionErrorKind::AccountAlreadyExists { account_id } => {
875 write!(f, "Can't create a new account {:?}, because it already exists", account_id)
876 }
877 ActionErrorKind::AccountDoesNotExist { account_id } => write!(
878 f,
879 "Can't complete the action because account {:?} doesn't exist",
880 account_id
881 ),
882 ActionErrorKind::ActorNoPermission { actor_id, account_id } => write!(
883 f,
884 "Actor {:?} doesn't have permission to account {:?} to complete the action",
885 actor_id, account_id
886 ),
887 ActionErrorKind::LackBalanceForState { account_id, amount } => write!(
888 f,
889 "The account {} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more",
890 account_id, amount
891 ),
892 ActionErrorKind::TriesToUnstake { account_id } => {
893 write!(f, "Account {:?} is not yet staked, but tries to unstake", account_id)
894 }
895 ActionErrorKind::TriesToStake { account_id, stake, locked, balance } => write!(
896 f,
897 "Account {:?} tries to stake {}, but has staked {} and only has {}",
898 account_id, stake, locked, balance
899 ),
900 ActionErrorKind::CreateAccountOnlyByRegistrar { account_id, registrar_account_id, predecessor_id } => write!(
901 f,
902 "A top-level account ID {:?} can't be created by {:?}, short top-level account IDs can only be created by {:?}",
903 account_id, predecessor_id, registrar_account_id,
904 ),
905 ActionErrorKind::CreateAccountNotAllowed { account_id, predecessor_id } => write!(
906 f,
907 "A sub-account ID {:?} can't be created by account {:?}",
908 account_id, predecessor_id,
909 ),
910 ActionErrorKind::DeleteKeyDoesNotExist { account_id, .. } => write!(
911 f,
912 "Account {:?} tries to remove an access key that doesn't exist",
913 account_id
914 ),
915 ActionErrorKind::AddKeyAlreadyExists { public_key, .. } => write!(
916 f,
917 "The public key {:?} is already used for an existing access key",
918 public_key
919 ),
920 ActionErrorKind::DeleteAccountStaking { account_id } => {
921 write!(f, "Account {:?} is staking and can not be deleted", account_id)
922 }
923 ActionErrorKind::FunctionCallError(s) => write!(f, "{:?}", s),
924 ActionErrorKind::NewReceiptValidationError(e) => {
925 write!(f, "An new action receipt created during a FunctionCall is not valid: {}", e)
926 }
927 ActionErrorKind::InsufficientStake { account_id, stake, minimum_stake } => write!(f, "Account {} tries to stake {} but minimum required stake is {}", account_id, stake, minimum_stake),
928 ActionErrorKind::OnlyImplicitAccountCreationAllowed { account_id } => write!(f, "CreateAccount action is called on hex-characters account of length 64 {}", account_id),
929 ActionErrorKind::DeleteAccountWithLargeState { account_id } => write!(f, "The state of account {} is too large and therefore cannot be deleted", account_id),
930 ActionErrorKind::DelegateActionInvalidSignature => write!(f, "DelegateAction is not signed with the given public key"),
931 ActionErrorKind::DelegateActionSenderDoesNotMatchTxReceiver { sender_id, receiver_id } => write!(f, "Transaction receiver {} doesn't match DelegateAction sender {}", receiver_id, sender_id),
932 ActionErrorKind::DelegateActionExpired => write!(f, "DelegateAction has expired"),
933 ActionErrorKind::DelegateActionAccessKeyError(access_key_error) => Display::fmt(&access_key_error, f),
934 ActionErrorKind::DelegateActionInvalidNonce { delegate_nonce, ak_nonce } => write!(f, "DelegateAction nonce {} must be larger than nonce of the used access key {}", delegate_nonce, ak_nonce),
935 ActionErrorKind::DelegateActionNonceTooLarge { delegate_nonce, upper_bound } => write!(f, "DelegateAction nonce {} must be smaller than the access key nonce upper bound {}", delegate_nonce, upper_bound),
936 ActionErrorKind::NonRefundableTransferToExistingAccount { account_id} => {
937 write!(f, "Can't make non-refundable storage transfer to {} because it already exists", account_id)
938 }
939 }
940 }
941}
942
943#[derive(Eq, PartialEq, Clone)]
944pub enum EpochError {
945 ThresholdError {
948 stake_sum: Balance,
949 num_seats: u64,
950 },
951 EpochOutOfBounds(EpochId),
953 MissingBlock(CryptoHash),
955 IOErr(String),
957 NotAValidator(AccountId, EpochId),
959 ShardingError(String),
961 NotEnoughValidators {
962 num_validators: u64,
963 num_shards: u64,
964 },
965 ChunkValidatorSelectionError(String),
967 ChunkProducerSelectionError(String),
969}
970
971impl std::error::Error for EpochError {}
972
973impl Display for EpochError {
974 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
975 match self {
976 EpochError::ThresholdError { stake_sum, num_seats } => write!(
977 f,
978 "Total stake {} must be higher than the number of seats {}",
979 stake_sum, num_seats
980 ),
981 EpochError::EpochOutOfBounds(epoch_id) => {
982 write!(f, "Epoch {:?} is out of bounds", epoch_id)
983 }
984 EpochError::MissingBlock(hash) => write!(f, "Missing block {}", hash),
985 EpochError::IOErr(err) => write!(f, "IO: {}", err),
986 EpochError::NotAValidator(account_id, epoch_id) => {
987 write!(f, "{} is not a validator in epoch {:?}", account_id, epoch_id)
988 }
989 EpochError::ShardingError(err) => write!(f, "Sharding Error: {}", err),
990 EpochError::NotEnoughValidators { num_shards, num_validators } => {
991 write!(f, "There were not enough validator proposals to fill all shards. num_proposals: {}, num_shards: {}", num_validators, num_shards)
992 }
993 EpochError::ChunkValidatorSelectionError(err) => {
994 write!(f, "Error selecting validators for a chunk: {}", err)
995 }
996 EpochError::ChunkProducerSelectionError(err) => {
997 write!(f, "Error selecting chunk producer: {}", err)
998 }
999 }
1000 }
1001}
1002
1003impl Debug for EpochError {
1004 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1005 match self {
1006 EpochError::ThresholdError { stake_sum, num_seats } => {
1007 write!(f, "ThresholdError({}, {})", stake_sum, num_seats)
1008 }
1009 EpochError::EpochOutOfBounds(epoch_id) => write!(f, "EpochOutOfBounds({:?})", epoch_id),
1010 EpochError::MissingBlock(hash) => write!(f, "MissingBlock({})", hash),
1011 EpochError::IOErr(err) => write!(f, "IOErr({})", err),
1012 EpochError::NotAValidator(account_id, epoch_id) => {
1013 write!(f, "NotAValidator({}, {:?})", account_id, epoch_id)
1014 }
1015 EpochError::ShardingError(err) => write!(f, "ShardingError({})", err),
1016 EpochError::NotEnoughValidators { num_shards, num_validators } => {
1017 write!(f, "NotEnoughValidators({}, {})", num_validators, num_shards)
1018 }
1019 EpochError::ChunkValidatorSelectionError(err) => {
1020 write!(f, "ChunkValidatorSelectionError({})", err)
1021 }
1022 EpochError::ChunkProducerSelectionError(err) => {
1023 write!(f, "ChunkProducerSelectionError({})", err)
1024 }
1025 }
1026 }
1027}
1028
1029impl From<std::io::Error> for EpochError {
1030 fn from(error: std::io::Error) -> Self {
1031 EpochError::IOErr(error.to_string())
1032 }
1033}
1034
1035impl From<ShardLayoutError> for EpochError {
1036 fn from(error: ShardLayoutError) -> Self {
1037 EpochError::ShardingError(error.to_string())
1038 }
1039}
1040
1041#[derive(
1042 Debug,
1043 Clone,
1044 PartialEq,
1045 Eq,
1046 BorshDeserialize,
1047 BorshSerialize,
1048 serde::Deserialize,
1049 serde::Serialize,
1050 ProtocolSchema,
1051)]
1052pub enum PrepareError {
1054 Serialization,
1056 Deserialization,
1058 InternalMemoryDeclared,
1060 GasInstrumentation,
1064 StackHeightInstrumentation,
1068 Instantiate,
1073 Memory,
1075 TooManyFunctions,
1077 TooManyLocals,
1079}
1080
1081#[derive(
1083 Debug,
1084 Clone,
1085 PartialEq,
1086 Eq,
1087 BorshDeserialize,
1088 BorshSerialize,
1089 serde::Deserialize,
1090 serde::Serialize,
1091 strum::IntoStaticStr,
1092 ProtocolSchema,
1093)]
1094pub enum WasmTrap {
1095 Unreachable,
1097 IncorrectCallIndirectSignature,
1099 MemoryOutOfBounds,
1101 CallIndirectOOB,
1103 IllegalArithmetic,
1105 MisalignedAtomicAccess,
1107 IndirectCallToNull,
1109 StackOverflow,
1111 GenericTrap,
1113}
1114
1115#[derive(
1116 Debug,
1117 Clone,
1118 PartialEq,
1119 Eq,
1120 BorshDeserialize,
1121 BorshSerialize,
1122 serde::Deserialize,
1123 serde::Serialize,
1124 strum::IntoStaticStr,
1125 ProtocolSchema,
1126)]
1127pub enum HostError {
1128 BadUTF16,
1130 BadUTF8,
1132 GasExceeded,
1134 GasLimitExceeded,
1136 BalanceExceeded,
1138 EmptyMethodName,
1140 GuestPanic { panic_msg: String },
1142 IntegerOverflow,
1144 InvalidPromiseIndex { promise_idx: u64 },
1146 CannotAppendActionToJointPromise,
1148 CannotReturnJointPromise,
1150 InvalidPromiseResultIndex { result_idx: u64 },
1152 InvalidRegisterId { register_id: u64 },
1154 IteratorWasInvalidated { iterator_index: u64 },
1156 MemoryAccessViolation,
1158 InvalidReceiptIndex { receipt_index: u64 },
1160 InvalidIteratorIndex { iterator_index: u64 },
1162 InvalidAccountId,
1164 InvalidMethodName,
1166 InvalidPublicKey,
1168 ProhibitedInView { method_name: String },
1170 NumberOfLogsExceeded { limit: u64 },
1172 KeyLengthExceeded { length: u64, limit: u64 },
1174 ValueLengthExceeded { length: u64, limit: u64 },
1176 TotalLogLengthExceeded { length: u64, limit: u64 },
1178 NumberPromisesExceeded { number_of_promises: u64, limit: u64 },
1180 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 },
1182 ReturnedValueLengthExceeded { length: u64, limit: u64 },
1184 ContractSizeExceeded { size: u64, limit: u64 },
1186 Deprecated { method_name: String },
1188 ECRecoverError { msg: String },
1190 AltBn128InvalidInput { msg: String },
1193 Ed25519VerifyInvalidInput { msg: String },
1196}
1197
1198#[derive(
1199 Debug,
1200 Clone,
1201 PartialEq,
1202 Eq,
1203 BorshDeserialize,
1204 BorshSerialize,
1205 serde::Deserialize,
1206 serde::Serialize,
1207 strum::IntoStaticStr,
1208 ProtocolSchema,
1209)]
1210pub enum MethodResolveError {
1211 MethodEmptyName,
1212 MethodNotFound,
1213 MethodInvalidSignature,
1214}
1215
1216#[derive(
1217 Debug,
1218 Clone,
1219 PartialEq,
1220 Eq,
1221 BorshDeserialize,
1222 BorshSerialize,
1223 serde::Deserialize,
1224 serde::Serialize,
1225 strum::IntoStaticStr,
1226 ProtocolSchema,
1227)]
1228pub enum CompilationError {
1229 CodeDoesNotExist {
1230 account_id: AccountId,
1231 },
1232 PrepareError(PrepareError),
1233 WasmerCompileError {
1237 msg: String,
1238 },
1239}
1240
1241#[derive(
1246 Debug,
1247 Clone,
1248 PartialEq,
1249 Eq,
1250 BorshDeserialize,
1251 BorshSerialize,
1252 serde::Serialize,
1253 serde::Deserialize,
1254 ProtocolSchema,
1255)]
1256pub enum FunctionCallError {
1257 CompilationError(CompilationError),
1259 LinkError {
1263 msg: String,
1264 },
1265 MethodResolveError(MethodResolveError),
1267 WasmTrap(WasmTrap),
1271 WasmUnknownError,
1272 HostError(HostError),
1274 _EVMError,
1277 ExecutionError(String),
1278}
1279
1280#[derive(Debug)]
1281pub enum ChunkAccessError {
1282 ChunkMissing(ChunkHash),
1283}
1284
1285impl std::fmt::Display for ChunkAccessError {
1286 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
1287 f.write_str(&format!("{:?}", self))
1288 }
1289}
1290
1291impl std::error::Error for ChunkAccessError {}