1use crate::hash::CryptoHash;
2use crate::serialize::dec_format;
3use crate::types::{AccountId, Balance, EpochId, Gas, Nonce};
4use borsh::{BorshDeserialize, BorshSerialize};
5use std::fmt::{Debug, Display};
6use unc_crypto::PublicKey;
7use unc_primitives_core::types::{BlockHeight, ProtocolVersion};
8use unc_rpc_error_macro::RpcError;
9
10#[derive(
12 BorshSerialize,
13 BorshDeserialize,
14 Debug,
15 Clone,
16 PartialEq,
17 Eq,
18 RpcError,
19 serde::Deserialize,
20 serde::Serialize,
21)]
22pub enum TxExecutionError {
23 ActionError(ActionError),
25 InvalidTxError(InvalidTxError),
27}
28
29impl std::error::Error for TxExecutionError {}
30
31impl Display for TxExecutionError {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
33 match self {
34 TxExecutionError::ActionError(e) => write!(f, "{}", e),
35 TxExecutionError::InvalidTxError(e) => write!(f, "{}", e),
36 }
37 }
38}
39
40impl From<ActionError> for TxExecutionError {
41 fn from(error: ActionError) -> Self {
42 TxExecutionError::ActionError(error)
43 }
44}
45
46impl From<InvalidTxError> for TxExecutionError {
47 fn from(error: InvalidTxError) -> Self {
48 TxExecutionError::InvalidTxError(error)
49 }
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
54pub enum RuntimeError {
55 UnexpectedIntegerOverflow,
57 InvalidTxError(InvalidTxError),
60 StorageError(StorageError),
63 BalanceMismatchError(Box<BalanceMismatchError>),
65 ReceiptValidationError(ReceiptValidationError),
67 ValidatorError(EpochError),
69}
70
71impl std::fmt::Display for RuntimeError {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
73 f.write_str(&format!("{:?}", self))
74 }
75}
76
77impl std::error::Error for RuntimeError {}
78
79#[derive(Debug, Clone, PartialEq, Eq)]
81pub enum MissingTrieValueContext {
82 TrieIterator,
84 TriePrefetchingStorage,
86 TrieMemoryPartialStorage,
88 TrieStorage,
90}
91
92#[derive(Debug, Clone, PartialEq, Eq)]
95pub enum StorageError {
96 StorageInternalError,
98 MissingTrieValue(MissingTrieValueContext, CryptoHash),
100 UnexpectedTrieValue,
104 StorageInconsistentState(String),
110 FlatStorageBlockNotSupported(String),
114 MemTrieLoadingError(String),
116}
117
118impl std::fmt::Display for StorageError {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
120 f.write_str(&format!("{:?}", self))
121 }
122}
123
124impl std::error::Error for StorageError {}
125
126#[derive(
128 BorshSerialize,
129 BorshDeserialize,
130 Debug,
131 Clone,
132 PartialEq,
133 Eq,
134 RpcError,
135 serde::Deserialize,
136 serde::Serialize,
137)]
138pub enum InvalidTxError {
139 InvalidAccessKeyError(InvalidAccessKeyError),
141 InvalidSignerId { signer_id: String },
143 SignerDoesNotExist { signer_id: AccountId },
145 InvalidNonce { tx_nonce: Nonce, ak_nonce: Nonce },
147 NonceTooLarge { tx_nonce: Nonce, upper_bound: Nonce },
149 InvalidReceiverId { receiver_id: String },
151 InvalidSignature,
153 NotEnoughBalance {
155 signer_id: AccountId,
156 #[serde(with = "dec_format")]
157 balance: Balance,
158 #[serde(with = "dec_format")]
159 cost: Balance,
160 },
161 LackBalanceForState {
163 signer_id: AccountId,
165 #[serde(with = "dec_format")]
167 amount: Balance,
168 },
169 CostOverflow,
171 InvalidChain,
173 Expired,
175 ActionsValidation(ActionsValidationError),
177 TransactionSizeExceeded { size: u64, limit: u64 },
179}
180
181impl std::error::Error for InvalidTxError {}
182
183#[derive(
184 BorshSerialize,
185 BorshDeserialize,
186 Debug,
187 Clone,
188 PartialEq,
189 Eq,
190 RpcError,
191 serde::Deserialize,
192 serde::Serialize,
193)]
194pub enum InvalidAccessKeyError {
195 AccessKeyNotFound { account_id: AccountId, public_key: Box<PublicKey> },
197 ReceiverMismatch { tx_receiver: AccountId, ak_receiver: String },
199 MethodNameMismatch { method_name: String },
201 RequiresFullAccess,
203 NotEnoughAllowance {
205 account_id: AccountId,
206 public_key: Box<PublicKey>,
207 #[serde(with = "dec_format")]
208 allowance: Balance,
209 #[serde(with = "dec_format")]
210 cost: Balance,
211 },
212 DepositWithFunctionCall,
214}
215
216#[derive(
218 BorshSerialize,
219 BorshDeserialize,
220 Debug,
221 Clone,
222 PartialEq,
223 Eq,
224 RpcError,
225 serde::Serialize,
226 serde::Deserialize,
227)]
228pub enum ActionsValidationError {
229 DeleteActionMustBeFinal,
231 TotalPrepaidGasExceeded { total_prepaid_gas: Gas, limit: Gas },
233 TotalNumberOfActionsExceeded { total_number_of_actions: u64, limit: u64 },
235 AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes: u64, limit: u64 },
237 AddKeyMethodNameLengthExceeded { length: u64, limit: u64 },
239 IntegerOverflow,
241 InvalidAccountId { account_id: String },
243 ContractSizeExceeded { size: u64, limit: u64 },
245 FunctionCallMethodNameLengthExceeded { length: u64, limit: u64 },
247 FunctionCallArgumentsLengthExceeded { length: u64, limit: u64 },
249 UnsuitablePledgingKey { public_key: Box<PublicKey> },
251 FunctionCallZeroAttachedGas,
253 DelegateActionMustBeOnlyOne,
255 UnsupportedProtocolFeature { protocol_feature: String, version: ProtocolVersion },
262
263 UnsuitableChallengingKey { public_key: Box<PublicKey> },
265}
266
267#[derive(
269 BorshSerialize,
270 BorshDeserialize,
271 Debug,
272 Clone,
273 PartialEq,
274 Eq,
275 RpcError,
276 serde::Serialize,
277 serde::Deserialize,
278)]
279pub enum ReceiptValidationError {
280 InvalidPredecessorId { account_id: String },
282 InvalidReceiverId { account_id: String },
284 InvalidSignerId { account_id: String },
286 InvalidDataReceiverId { account_id: String },
288 ReturnedValueLengthExceeded { length: u64, limit: u64 },
290 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 },
292 ActionsValidation(ActionsValidationError),
294}
295
296impl Display for ReceiptValidationError {
297 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
298 match self {
299 ReceiptValidationError::InvalidPredecessorId { account_id } => {
300 write!(f, "The predecessor_id `{}` of a Receipt is not valid.", account_id)
301 }
302 ReceiptValidationError::InvalidReceiverId { account_id } => {
303 write!(f, "The receiver_id `{}` of a Receipt is not valid.", account_id)
304 }
305 ReceiptValidationError::InvalidSignerId { account_id } => {
306 write!(f, "The signer_id `{}` of an ActionReceipt is not valid.", account_id)
307 }
308 ReceiptValidationError::InvalidDataReceiverId { account_id } => write!(
309 f,
310 "The receiver_id `{}` of a DataReceiver within an ActionReceipt is not valid.",
311 account_id
312 ),
313 ReceiptValidationError::ReturnedValueLengthExceeded { length, limit } => write!(
314 f,
315 "The length of the returned data {} exceeded the limit {} in a DataReceipt",
316 length, limit
317 ),
318 ReceiptValidationError::NumberInputDataDependenciesExceeded { number_of_input_data_dependencies, limit } => write!(
319 f,
320 "The number of input data dependencies {} exceeded the limit {} in an ActionReceipt",
321 number_of_input_data_dependencies, limit
322 ),
323 ReceiptValidationError::ActionsValidation(e) => write!(f, "{}", e),
324 }
325 }
326}
327
328impl std::error::Error for ReceiptValidationError {}
329
330impl Display for ActionsValidationError {
331 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
332 match self {
333 ActionsValidationError::DeleteActionMustBeFinal => {
334 write!(f, "The delete action must be the last action in transaction")
335 }
336 ActionsValidationError::TotalPrepaidGasExceeded { total_prepaid_gas, limit } => {
337 write!(f, "The total prepaid gas {} exceeds the limit {}", total_prepaid_gas, limit)
338 }
339 ActionsValidationError::TotalNumberOfActionsExceeded {total_number_of_actions, limit } => {
340 write!(
341 f,
342 "The total number of actions {} exceeds the limit {}",
343 total_number_of_actions, limit
344 )
345 }
346 ActionsValidationError::AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes, limit } => write!(
347 f,
348 "The total number of bytes in allowed method names {} exceeds the maximum allowed number {} in a AddKey action",
349 total_number_of_bytes, limit
350 ),
351 ActionsValidationError::AddKeyMethodNameLengthExceeded { length, limit } => write!(
352 f,
353 "The length of some method name {} exceeds the maximum allowed length {} in a AddKey action",
354 length, limit
355 ),
356 ActionsValidationError::IntegerOverflow => write!(
357 f,
358 "Integer overflow during a compute",
359 ),
360 ActionsValidationError::InvalidAccountId { account_id } => write!(
361 f,
362 "Invalid account ID `{}`",
363 account_id
364 ),
365 ActionsValidationError::ContractSizeExceeded { size, limit } => write!(
366 f,
367 "The length of the contract size {} exceeds the maximum allowed size {} in a DeployContract action",
368 size, limit
369 ),
370 ActionsValidationError::FunctionCallMethodNameLengthExceeded { length, limit } => write!(
371 f,
372 "The length of the method name {} exceeds the maximum allowed length {} in a FunctionCall action",
373 length, limit
374 ),
375 ActionsValidationError::FunctionCallArgumentsLengthExceeded { length, limit } => write!(
376 f,
377 "The length of the arguments {} exceeds the maximum allowed length {} in a FunctionCall action",
378 length, limit
379 ),
380 ActionsValidationError::UnsuitablePledgingKey { public_key } => write!(
381 f,
382 "The staking key must be ristretto compatible ED25519 key. {} is provided instead.",
383 public_key,
384 ),
385 ActionsValidationError::FunctionCallZeroAttachedGas => write!(
386 f,
387 "The attached amount of gas in a FunctionCall action has to be a positive number",
388 ),
389 ActionsValidationError::DelegateActionMustBeOnlyOne => write!(
390 f,
391 "The actions can contain the ony one DelegateAction"
392 ),
393 ActionsValidationError::UnsupportedProtocolFeature { protocol_feature, version } => write!(
394 f,
395 "Transaction requires protocol feature {} / version {} which is not supported by the current protocol version",
396 protocol_feature,
397 version,
398 ),
399 ActionsValidationError::UnsuitableChallengingKey { public_key } => write!(
400 f,
401 "The challenging key must be RSA2048 keys. {} is provided instead.",
402 public_key,
403 ),
404 }
405 }
406}
407
408impl std::error::Error for ActionsValidationError {}
409
410#[derive(
412 BorshSerialize,
413 BorshDeserialize,
414 Debug,
415 Clone,
416 PartialEq,
417 Eq,
418 RpcError,
419 serde::Deserialize,
420 serde::Serialize,
421)]
422pub struct ActionError {
423 pub index: Option<u64>,
426 pub kind: ActionErrorKind,
428}
429
430impl std::error::Error for ActionError {}
431
432#[derive(
433 BorshSerialize,
434 BorshDeserialize,
435 Debug,
436 Clone,
437 PartialEq,
438 Eq,
439 RpcError,
440 serde::Deserialize,
441 serde::Serialize,
442)]
443pub enum ActionErrorKind {
444 AccountAlreadyExists { account_id: AccountId },
446 AccountDoesNotExist { account_id: AccountId },
448 CreateAccountNotAllowed { account_id: AccountId, predecessor_id: AccountId },
450 ActorNoPermission { account_id: AccountId, actor_id: AccountId },
453 DeleteKeyDoesNotExist { account_id: AccountId, public_key: Box<PublicKey> },
455 AddKeyAlreadyExists { account_id: AccountId, public_key: Box<PublicKey> },
457 DeleteAccountPledging { account_id: AccountId },
459 LackBalanceForState {
461 account_id: AccountId,
463 #[serde(with = "dec_format")]
465 amount: Balance,
466 },
467 TriesToUnpledge { account_id: AccountId },
469 TriesToPledge {
471 account_id: AccountId,
472 #[serde(with = "dec_format")]
473 pledge: Balance,
474 #[serde(with = "dec_format")]
475 pledging: Balance,
476 #[serde(with = "dec_format")]
477 balance: Balance,
478 },
479 InsufficientPledge {
480 account_id: AccountId,
481 #[serde(with = "dec_format")]
482 pledge: Balance,
483 #[serde(with = "dec_format")]
484 minimum_pledge: Balance,
485 },
486 FunctionCallError(FunctionCallError),
488 NewReceiptValidationError(ReceiptValidationError),
491 OnlyImplicitAccountCreationAllowed { account_id: AccountId },
495 DeleteAccountWithLargeState { account_id: AccountId },
497 DelegateActionInvalidSignature,
499 DelegateActionSenderDoesNotMatchTxReceiver { sender_id: AccountId, receiver_id: AccountId },
501 DelegateActionExpired,
503 DelegateActionAccessKeyError(InvalidAccessKeyError),
505 DelegateActionInvalidNonce { delegate_nonce: Nonce, ak_nonce: Nonce },
507 DelegateActionNonceTooLarge { delegate_nonce: Nonce, upper_bound: Nonce },
509
510 RsaKeysNotFound { account_id: AccountId, public_key: Box<PublicKey> },
512}
513
514impl From<ActionErrorKind> for ActionError {
515 fn from(e: ActionErrorKind) -> ActionError {
516 ActionError { index: None, kind: e }
517 }
518}
519
520impl Display for InvalidTxError {
521 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
522 match self {
523 InvalidTxError::InvalidSignerId { signer_id } => {
524 write!(f, "Invalid signer account ID {:?} according to requirements", signer_id)
525 }
526 InvalidTxError::SignerDoesNotExist { signer_id } => {
527 write!(f, "Signer {:?} does not exist", signer_id)
528 }
529 InvalidTxError::InvalidAccessKeyError(access_key_error) => {
530 Display::fmt(&access_key_error, f)
531 }
532 InvalidTxError::InvalidNonce { tx_nonce, ak_nonce } => write!(
533 f,
534 "Transaction nonce {} must be larger than nonce of the used access key {}",
535 tx_nonce, ak_nonce
536 ),
537 InvalidTxError::InvalidReceiverId { receiver_id } => {
538 write!(f, "Invalid receiver account ID {:?} according to requirements", receiver_id)
539 }
540 InvalidTxError::InvalidSignature => {
541 write!(f, "Transaction is not signed with the given public key")
542 }
543 InvalidTxError::NotEnoughBalance { signer_id, balance, cost } => write!(
544 f,
545 "Sender {:?} does not have enough balance {} for operation costing {}",
546 signer_id, balance, cost
547 ),
548 InvalidTxError::LackBalanceForState { signer_id, amount } => {
549 write!(f, "Failed to execute, because the account {:?} wouldn't have enough balance to cover storage, required to have {} attoUNC more", signer_id, amount)
550 }
551 InvalidTxError::CostOverflow => {
552 write!(f, "Transaction gas or balance cost is too high")
553 }
554 InvalidTxError::InvalidChain => {
555 write!(f, "Transaction parent block hash doesn't belong to the current chain")
556 }
557 InvalidTxError::Expired => {
558 write!(f, "Transaction has expired")
559 }
560 InvalidTxError::ActionsValidation(error) => {
561 write!(f, "Transaction actions validation error: {}", error)
562 }
563 InvalidTxError::NonceTooLarge { tx_nonce, upper_bound } => {
564 write!(
565 f,
566 "Transaction nonce {} must be smaller than the access key nonce upper bound {}",
567 tx_nonce, upper_bound
568 )
569 }
570 InvalidTxError::TransactionSizeExceeded { size, limit } => {
571 write!(f, "Size of serialized transaction {} exceeded the limit {}", size, limit)
572 }
573 }
574 }
575}
576
577impl From<InvalidAccessKeyError> for InvalidTxError {
578 fn from(error: InvalidAccessKeyError) -> Self {
579 InvalidTxError::InvalidAccessKeyError(error)
580 }
581}
582
583impl Display for InvalidAccessKeyError {
584 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
585 match self {
586 InvalidAccessKeyError::AccessKeyNotFound { account_id, public_key } => write!(
587 f,
588 "Signer {:?} doesn't have access key with the given public_key {}",
589 account_id, public_key
590 ),
591 InvalidAccessKeyError::ReceiverMismatch { tx_receiver, ak_receiver } => write!(
592 f,
593 "Transaction receiver_id {:?} doesn't match the access key receiver_id {:?}",
594 tx_receiver, ak_receiver
595 ),
596 InvalidAccessKeyError::MethodNameMismatch { method_name } => write!(
597 f,
598 "Transaction method name {:?} isn't allowed by the access key",
599 method_name
600 ),
601 InvalidAccessKeyError::RequiresFullAccess => {
602 write!(f, "Invalid access key type. Full-access keys are required for transactions that have multiple or non-function-call actions")
603 }
604 InvalidAccessKeyError::NotEnoughAllowance {
605 account_id,
606 public_key,
607 allowance,
608 cost,
609 } => write!(
610 f,
611 "Access Key {:?}:{} does not have enough balance {} for transaction costing {}",
612 account_id, public_key, allowance, cost
613 ),
614 InvalidAccessKeyError::DepositWithFunctionCall => {
615 write!(f, "Having a deposit with a function call action is not allowed with a function call access key.")
616 }
617 }
618 }
619}
620
621impl std::error::Error for InvalidAccessKeyError {}
622
623#[derive(
625 BorshSerialize,
626 BorshDeserialize,
627 Debug,
628 Clone,
629 PartialEq,
630 Eq,
631 RpcError,
632 serde::Deserialize,
633 serde::Serialize,
634)]
635pub struct BalanceMismatchError {
636 #[serde(with = "dec_format")]
638 pub incoming_validator_rewards: Balance,
639 #[serde(with = "dec_format")]
640 pub initial_accounts_balance: Balance,
641 #[serde(with = "dec_format")]
642 pub incoming_receipts_balance: Balance,
643 #[serde(with = "dec_format")]
644 pub processed_delayed_receipts_balance: Balance,
645 #[serde(with = "dec_format")]
646 pub initial_postponed_receipts_balance: Balance,
647 #[serde(with = "dec_format")]
649 pub final_accounts_balance: Balance,
650 #[serde(with = "dec_format")]
651 pub outgoing_receipts_balance: Balance,
652 #[serde(with = "dec_format")]
653 pub new_delayed_receipts_balance: Balance,
654 #[serde(with = "dec_format")]
655 pub final_postponed_receipts_balance: Balance,
656 #[serde(with = "dec_format")]
657 pub tx_burnt_amount: Balance,
658 #[serde(with = "dec_format")]
659 pub slashed_burnt_amount: Balance,
660 #[serde(with = "dec_format")]
661 pub other_burnt_amount: Balance,
662}
663
664impl Display for BalanceMismatchError {
665 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
666 let initial_balance = self
668 .incoming_validator_rewards
669 .saturating_add(self.initial_accounts_balance)
670 .saturating_add(self.incoming_receipts_balance)
671 .saturating_add(self.processed_delayed_receipts_balance)
672 .saturating_add(self.initial_postponed_receipts_balance);
673 let final_balance = self
674 .final_accounts_balance
675 .saturating_add(self.outgoing_receipts_balance)
676 .saturating_add(self.new_delayed_receipts_balance)
677 .saturating_add(self.final_postponed_receipts_balance)
678 .saturating_add(self.tx_burnt_amount)
679 .saturating_add(self.slashed_burnt_amount)
680 .saturating_add(self.other_burnt_amount);
681 write!(
682 f,
683 "Balance Mismatch Error. The input balance {} doesn't match output balance {}\n\
684 Inputs:\n\
685 \tIncoming validator rewards sum: {}\n\
686 \tInitial accounts balance sum: {}\n\
687 \tIncoming receipts balance sum: {}\n\
688 \tProcessed delayed receipts balance sum: {}\n\
689 \tInitial postponed receipts balance sum: {}\n\
690 Outputs:\n\
691 \tFinal accounts balance sum: {}\n\
692 \tOutgoing receipts balance sum: {}\n\
693 \tNew delayed receipts balance sum: {}\n\
694 \tFinal postponed receipts balance sum: {}\n\
695 \tTx fees burnt amount: {}\n\
696 \tSlashed amount: {}\n\
697 \tOther burnt amount: {}",
698 initial_balance,
699 final_balance,
700 self.incoming_validator_rewards,
701 self.initial_accounts_balance,
702 self.incoming_receipts_balance,
703 self.processed_delayed_receipts_balance,
704 self.initial_postponed_receipts_balance,
705 self.final_accounts_balance,
706 self.outgoing_receipts_balance,
707 self.new_delayed_receipts_balance,
708 self.final_postponed_receipts_balance,
709 self.tx_burnt_amount,
710 self.slashed_burnt_amount,
711 self.other_burnt_amount,
712 )
713 }
714}
715
716impl std::error::Error for BalanceMismatchError {}
717
718#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq)]
719pub struct IntegerOverflowError;
720
721impl std::fmt::Display for IntegerOverflowError {
722 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
723 f.write_str(&format!("{:?}", self))
724 }
725}
726
727impl std::error::Error for IntegerOverflowError {}
728
729impl From<IntegerOverflowError> for InvalidTxError {
730 fn from(_: IntegerOverflowError) -> Self {
731 InvalidTxError::CostOverflow
732 }
733}
734
735impl From<IntegerOverflowError> for RuntimeError {
736 fn from(_: IntegerOverflowError) -> Self {
737 RuntimeError::UnexpectedIntegerOverflow
738 }
739}
740
741impl From<StorageError> for RuntimeError {
742 fn from(e: StorageError) -> Self {
743 RuntimeError::StorageError(e)
744 }
745}
746
747impl From<BalanceMismatchError> for RuntimeError {
748 fn from(e: BalanceMismatchError) -> Self {
749 RuntimeError::BalanceMismatchError(Box::new(e))
750 }
751}
752
753impl From<InvalidTxError> for RuntimeError {
754 fn from(e: InvalidTxError) -> Self {
755 RuntimeError::InvalidTxError(e)
756 }
757}
758
759impl From<EpochError> for RuntimeError {
760 fn from(e: EpochError) -> Self {
761 RuntimeError::ValidatorError(e)
762 }
763}
764
765impl Display for ActionError {
766 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
767 write!(f, "Action #{}: {}", self.index.unwrap_or_default(), self.kind)
768 }
769}
770
771impl Display for ActionErrorKind {
772 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
773 match self {
774 ActionErrorKind::AccountAlreadyExists { account_id } => {
775 write!(f, "Can't create a new account {:?}, because it already exists", account_id)
776 }
777 ActionErrorKind::AccountDoesNotExist { account_id } => write!(
778 f,
779 "Can't complete the action because account {:?} doesn't exist",
780 account_id
781 ),
782 ActionErrorKind::ActorNoPermission { actor_id, account_id } => write!(
783 f,
784 "Actor {:?} doesn't have permission to account {:?} to complete the action",
785 actor_id, account_id
786 ),
787 ActionErrorKind::LackBalanceForState { account_id, amount } => write!(
788 f,
789 "The account {} wouldn't have enough balance to cover storage, required to have {} attoUNC more",
790 account_id, amount
791 ),
792 ActionErrorKind::TriesToUnpledge { account_id } => {
793 write!(f, "Account {:?} is not yet pledging, but tries to unpledge", account_id)
794 }
795 ActionErrorKind::TriesToPledge { account_id, pledge, pledging, balance } => write!(
796 f,
797 "Account {:?} tries to pledge {}, but has pledging {} and only has {}",
798 account_id, pledge, pledging, balance
799 ),
800 ActionErrorKind::CreateAccountNotAllowed { account_id, predecessor_id } => write!(
801 f,
802 "A sub-account ID {:?} can't be created by account {:?}",
803 account_id, predecessor_id,
804 ),
805 ActionErrorKind::DeleteKeyDoesNotExist { account_id, .. } => write!(
806 f,
807 "Account {:?} tries to remove an access key that doesn't exist",
808 account_id
809 ),
810 ActionErrorKind::AddKeyAlreadyExists { public_key, .. } => write!(
811 f,
812 "The public key {:?} is already used for an existing access key",
813 public_key
814 ),
815 ActionErrorKind::DeleteAccountPledging{ account_id } => {
816 write!(f, "Account {:?} is staking and can not be deleted", account_id)
817 }
818 ActionErrorKind::FunctionCallError(s) => write!(f, "{:?}", s),
819 ActionErrorKind::NewReceiptValidationError(e) => {
820 write!(f, "An new action receipt created during a FunctionCall is not valid: {}", e)
821 }
822 ActionErrorKind::InsufficientPledge { account_id, pledge, minimum_pledge } => write!(f, "Account {} tries to pledge {} but minimum required pledge is {}", account_id, pledge, minimum_pledge),
823 ActionErrorKind::OnlyImplicitAccountCreationAllowed { account_id } => write!(f, "CreateAccount action is called on hex-characters account of length 64 {}", account_id),
824 ActionErrorKind::DeleteAccountWithLargeState { account_id } => write!(f, "The state of account {} is too large and therefore cannot be deleted", account_id),
825 ActionErrorKind::DelegateActionInvalidSignature => write!(f, "DelegateAction is not signed with the given public key"),
826 ActionErrorKind::DelegateActionSenderDoesNotMatchTxReceiver { sender_id, receiver_id } => write!(f, "Transaction receiver {} doesn't match DelegateAction sender {}", receiver_id, sender_id),
827 ActionErrorKind::DelegateActionExpired => write!(f, "DelegateAction has expired"),
828 ActionErrorKind::DelegateActionAccessKeyError(access_key_error) => Display::fmt(&access_key_error, f),
829 ActionErrorKind::DelegateActionInvalidNonce { delegate_nonce, ak_nonce } => write!(f, "DelegateAction nonce {} must be larger than nonce of the used access key {}", delegate_nonce, ak_nonce),
830 ActionErrorKind::DelegateActionNonceTooLarge { delegate_nonce, upper_bound } => write!(f, "DelegateAction nonce {} must be smaller than the access key nonce upper bound {}", delegate_nonce, upper_bound),
831 ActionErrorKind::RsaKeysNotFound { public_key, .. } => write!(
832 f,
833 "The public key {:?} is doesn't exist rsa key",
834 public_key
835 ),
836 }
837 }
838}
839#[derive(Eq, PartialEq, Clone)]
840pub enum BlockError {
841 ThresholdError {
844 pledge_sum: Balance,
845 num_seats: u64,
846 },
847 BlockOutOfBounds(CryptoHash),
849 MissingBlock(CryptoHash),
851 IOErr(String),
853 NotAValidator(AccountId, BlockHeight),
855 ShardingError(String),
857 NotEnoughValidators {
858 num_validators: u64,
859 num_shards: u64,
860 },
861 ChunkValidatorSelectionError(String),
863 ValidatorTotalPowerError(String),
865 NoAvailableValidator(String),
867}
868
869impl std::error::Error for crate::errors::BlockError {}
870
871impl Display for crate::errors::BlockError {
872 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
873 match self {
874 crate::errors::BlockError::ThresholdError { pledge_sum, num_seats } => write!(
875 f,
876 "Total pledge {} must be higher than the number of seats {}",
877 pledge_sum, num_seats
878 ),
879 crate::errors::BlockError::BlockOutOfBounds(block_height) => {
880 write!(f, "Block {:?} is out of bounds", block_height)
881 }
882 crate::errors::BlockError::MissingBlock(hash) => write!(f, "Missing block {}", hash),
883 crate::errors::BlockError::IOErr(err) => write!(f, "IO: {}", err),
884 crate::errors::BlockError::NotAValidator(account_id, block_height) => {
885 write!(f, "{} is not a validator in epoch {:?}", account_id, block_height)
886 }
887 crate::errors::BlockError::ShardingError(err) => write!(f, "Sharding Error: {}", err),
888 crate::errors::BlockError::NotEnoughValidators { num_shards, num_validators } => {
889 write!(f, "There were not enough validator proposals to fill all shards. num_proposals: {}, num_shards: {}", num_validators, num_shards)
890 }
891 crate::errors::BlockError::ChunkValidatorSelectionError(err) => {
892 write!(f, "Error selecting validators for a chunk: {}", err)
893 }
894 crate::errors::BlockError::ValidatorTotalPowerError(err) => {
895 write!(f, "Error when computing total power: {}", err)
896 }
897 crate::errors::BlockError::NoAvailableValidator(err) => {
898 write!(f, "Error selecting produce: {}", err)
899 }
900 }
901 }
902}
903
904impl Debug for crate::errors::BlockError {
905 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
906 match self {
907 crate::errors::BlockError::ThresholdError { pledge_sum, num_seats } => {
908 write!(f, "ThresholdError({}, {})", pledge_sum, num_seats)
909 }
910 crate::errors::BlockError::BlockOutOfBounds(block_height) => {
911 write!(f, "EpochOutOfBounds({:?})", block_height)
912 }
913 crate::errors::BlockError::MissingBlock(hash) => write!(f, "MissingBlock({})", hash),
914 crate::errors::BlockError::IOErr(err) => write!(f, "IOErr({})", err),
915 crate::errors::BlockError::NotAValidator(account_id, block_height) => {
916 write!(f, "NotAValidator({}, {:?})", account_id, block_height)
917 }
918 crate::errors::BlockError::ShardingError(err) => write!(f, "ShardingError({})", err),
919 crate::errors::BlockError::NotEnoughValidators { num_shards, num_validators } => {
920 write!(f, "NotEnoughValidators({}, {})", num_validators, num_shards)
921 }
922 crate::errors::BlockError::ChunkValidatorSelectionError(err) => {
923 write!(f, "ChunkValidatorSelectionError({})", err)
924 }
925 crate::errors::BlockError::ValidatorTotalPowerError(err) => {
926 write!(f, "Error when computing total power: {}", err)
927 }
928 crate::errors::BlockError::NoAvailableValidator(err) => {
929 write!(f, "Error selecting produce: {}", err)
930 }
931 }
932 }
933}
934
935impl From<std::io::Error> for crate::errors::BlockError {
936 fn from(error: std::io::Error) -> Self {
937 crate::errors::BlockError::IOErr(error.to_string())
938 }
939}
940
941impl From<EpochError> for BlockError {
942 fn from(error: EpochError) -> Self {
943 match error {
944 EpochError::IOErr(..) => BlockError::IOErr(error.to_string()),
945 EpochError::ChunkValidatorSelectionError(..) => {
946 BlockError::ChunkValidatorSelectionError(error.to_string())
947 }
948 EpochError::EpochOutOfBounds(..) => BlockError::BlockOutOfBounds(CryptoHash::default()),
949 EpochError::MissingBlock(block_hash) => BlockError::MissingBlock(block_hash),
950 EpochError::NotAValidator(account_id, _hash) => {
951 BlockError::NotAValidator(account_id, 0)
952 }
953 EpochError::NotEnoughValidators { num_validators: x, num_shards: y } => {
954 BlockError::NotEnoughValidators { num_validators: x, num_shards: y }
955 }
956 EpochError::ShardingError(..) => BlockError::ShardingError(error.to_string()),
957 EpochError::ThresholdError { pledge_sum: pledge, num_seats: seats } => {
958 BlockError::ThresholdError { pledge_sum: pledge, num_seats: seats }
959 }
960 }
961 }
962}
963#[derive(Eq, PartialEq, Clone)]
964pub enum EpochError {
965 ThresholdError {
968 pledge_sum: Balance,
969 num_seats: u64,
970 },
971 EpochOutOfBounds(EpochId),
973 MissingBlock(CryptoHash),
975 IOErr(String),
977 NotAValidator(AccountId, EpochId),
979 ShardingError(String),
981 NotEnoughValidators {
982 num_validators: u64,
983 num_shards: u64,
984 },
985 ChunkValidatorSelectionError(String),
987}
988
989impl std::error::Error for EpochError {}
990
991impl Display for EpochError {
992 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
993 match self {
994 EpochError::ThresholdError { pledge_sum, num_seats } => write!(
995 f,
996 "Total pledge {} must be higher than the number of seats {}",
997 pledge_sum, num_seats
998 ),
999 EpochError::EpochOutOfBounds(epoch_id) => {
1000 write!(f, "Epoch {:?} is out of bounds", epoch_id)
1001 }
1002 EpochError::MissingBlock(hash) => write!(f, "Missing block {}", hash),
1003 EpochError::IOErr(err) => write!(f, "IO: {}", err),
1004 EpochError::NotAValidator(account_id, epoch_id) => {
1005 write!(f, "{} is not a validator in epoch {:?}", account_id, epoch_id)
1006 }
1007 EpochError::ShardingError(err) => write!(f, "Sharding Error: {}", err),
1008 EpochError::NotEnoughValidators { num_shards, num_validators } => {
1009 write!(f, "There were not enough validator proposals to fill all shards. num_proposals: {}, num_shards: {}", num_validators, num_shards)
1010 }
1011 EpochError::ChunkValidatorSelectionError(err) => {
1012 write!(f, "Error selecting validators for a chunk: {}", err)
1013 }
1014 }
1015 }
1016}
1017
1018impl Debug for EpochError {
1019 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1020 match self {
1021 EpochError::ThresholdError { pledge_sum, num_seats } => {
1022 write!(f, "ThresholdError({}, {})", pledge_sum, num_seats)
1023 }
1024 EpochError::EpochOutOfBounds(epoch_id) => write!(f, "EpochOutOfBounds({:?})", epoch_id),
1025 EpochError::MissingBlock(hash) => write!(f, "MissingBlock({})", hash),
1026 EpochError::IOErr(err) => write!(f, "IOErr({})", err),
1027 EpochError::NotAValidator(account_id, epoch_id) => {
1028 write!(f, "NotAValidator({}, {:?})", account_id, epoch_id)
1029 }
1030 EpochError::ShardingError(err) => write!(f, "ShardingError({})", err),
1031 EpochError::NotEnoughValidators { num_shards, num_validators } => {
1032 write!(f, "NotEnoughValidators({}, {})", num_validators, num_shards)
1033 }
1034 EpochError::ChunkValidatorSelectionError(err) => {
1035 write!(f, "ChunkValidatorSelectionError({})", err)
1036 }
1037 }
1038 }
1039}
1040
1041impl From<std::io::Error> for EpochError {
1042 fn from(error: std::io::Error) -> Self {
1043 EpochError::IOErr(error.to_string())
1044 }
1045}
1046
1047impl From<BlockError> for EpochError {
1048 fn from(error: BlockError) -> Self {
1049 match error {
1050 BlockError::IOErr(..) => EpochError::IOErr(error.to_string()),
1051 BlockError::ChunkValidatorSelectionError(..) => {
1052 EpochError::ChunkValidatorSelectionError(error.to_string())
1053 }
1054 BlockError::BlockOutOfBounds(..) => EpochError::EpochOutOfBounds(EpochId::default()),
1055 BlockError::MissingBlock(block_hash) => EpochError::MissingBlock(block_hash),
1056 BlockError::NotAValidator(account_id, _block_height) => {
1057 EpochError::NotAValidator(account_id, EpochId::default())
1058 }
1059 BlockError::NotEnoughValidators { num_validators: x, num_shards: y } => {
1060 EpochError::NotEnoughValidators { num_validators: x, num_shards: y }
1061 }
1062 BlockError::ShardingError(..) => EpochError::ShardingError(error.to_string()),
1063 BlockError::ThresholdError { pledge_sum: pledge, num_seats: seats } => {
1064 EpochError::ThresholdError { pledge_sum: pledge, num_seats: seats }
1065 }
1066 BlockError::ValidatorTotalPowerError(..) => EpochError::IOErr(error.to_string()),
1067 BlockError::NoAvailableValidator(..) => EpochError::IOErr(error.to_string()),
1068 }
1069 }
1070}
1071
1072#[derive(
1073 Debug,
1074 Clone,
1075 PartialEq,
1076 Eq,
1077 BorshDeserialize,
1078 BorshSerialize,
1079 RpcError,
1080 serde::Deserialize,
1081 serde::Serialize,
1082)]
1083pub enum PrepareError {
1085 Serialization,
1087 Deserialization,
1089 InternalMemoryDeclared,
1091 GasInstrumentation,
1095 StackHeightInstrumentation,
1099 Instantiate,
1104 Memory,
1106 TooManyFunctions,
1108 TooManyLocals,
1110}
1111
1112#[derive(
1114 Debug,
1115 Clone,
1116 PartialEq,
1117 Eq,
1118 BorshDeserialize,
1119 BorshSerialize,
1120 RpcError,
1121 serde::Deserialize,
1122 serde::Serialize,
1123 strum::IntoStaticStr,
1124)]
1125pub enum WasmTrap {
1126 Unreachable,
1128 IncorrectCallIndirectSignature,
1130 MemoryOutOfBounds,
1132 CallIndirectOOB,
1134 IllegalArithmetic,
1136 MisalignedAtomicAccess,
1138 IndirectCallToNull,
1140 StackOverflow,
1142 GenericTrap,
1144}
1145
1146#[derive(
1147 Debug,
1148 Clone,
1149 PartialEq,
1150 Eq,
1151 BorshDeserialize,
1152 BorshSerialize,
1153 RpcError,
1154 serde::Deserialize,
1155 serde::Serialize,
1156 strum::IntoStaticStr,
1157)]
1158pub enum HostError {
1159 BadUTF16,
1161 BadUTF8,
1163 GasExceeded,
1165 GasLimitExceeded,
1167 BalanceExceeded,
1169 EmptyMethodName,
1171 GuestPanic { panic_msg: String },
1173 IntegerOverflow,
1175 InvalidPromiseIndex { promise_idx: u64 },
1177 CannotAppendActionToJointPromise,
1179 CannotReturnJointPromise,
1181 InvalidPromiseResultIndex { result_idx: u64 },
1183 InvalidRegisterId { register_id: u64 },
1185 IteratorWasInvalidated { iterator_index: u64 },
1187 MemoryAccessViolation,
1189 InvalidReceiptIndex { receipt_index: u64 },
1191 InvalidIteratorIndex { iterator_index: u64 },
1193 InvalidAccountId,
1195 InvalidMethodName,
1197 InvalidPublicKey,
1199 ProhibitedInView { method_name: String },
1201 NumberOfLogsExceeded { limit: u64 },
1203 KeyLengthExceeded { length: u64, limit: u64 },
1205 ValueLengthExceeded { length: u64, limit: u64 },
1207 TotalLogLengthExceeded { length: u64, limit: u64 },
1209 NumberPromisesExceeded { number_of_promises: u64, limit: u64 },
1211 NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 },
1213 ReturnedValueLengthExceeded { length: u64, limit: u64 },
1215 ContractSizeExceeded { size: u64, limit: u64 },
1217 Deprecated { method_name: String },
1219 ECRecoverError { msg: String },
1221 AltBn128InvalidInput { msg: String },
1224 Ed25519VerifyInvalidInput { msg: String },
1227}
1228
1229#[derive(
1230 Debug,
1231 Clone,
1232 PartialEq,
1233 Eq,
1234 BorshDeserialize,
1235 BorshSerialize,
1236 RpcError,
1237 serde::Deserialize,
1238 serde::Serialize,
1239 strum::IntoStaticStr,
1240)]
1241pub enum MethodResolveError {
1242 MethodEmptyName,
1243 MethodNotFound,
1244 MethodInvalidSignature,
1245}
1246
1247#[derive(
1248 Debug,
1249 Clone,
1250 PartialEq,
1251 Eq,
1252 BorshDeserialize,
1253 BorshSerialize,
1254 RpcError,
1255 serde::Deserialize,
1256 serde::Serialize,
1257 strum::IntoStaticStr,
1258)]
1259pub enum CompilationError {
1260 CodeDoesNotExist {
1261 account_id: AccountId,
1262 },
1263 PrepareError(PrepareError),
1264 WasmerCompileError {
1268 msg: String,
1269 },
1270}
1271
1272#[derive(
1277 Debug,
1278 Clone,
1279 PartialEq,
1280 Eq,
1281 BorshDeserialize,
1282 BorshSerialize,
1283 serde::Serialize,
1284 serde::Deserialize,
1285)]
1286pub enum FunctionCallError {
1287 CompilationError(CompilationError),
1289 LinkError {
1293 msg: String,
1294 },
1295 MethodResolveError(MethodResolveError),
1297 WasmTrap(WasmTrap),
1301 WasmUnknownError,
1302 HostError(HostError),
1304 _EVMError,
1307 ExecutionError(String),
1308}
1309
1310impl From<unc_vm_runner::logic::errors::MethodResolveError> for MethodResolveError {
1311 fn from(outer_err: unc_vm_runner::logic::errors::MethodResolveError) -> Self {
1312 use unc_vm_runner::logic::errors::MethodResolveError as MRE;
1313 match outer_err {
1314 MRE::MethodEmptyName => Self::MethodEmptyName,
1315 MRE::MethodNotFound => Self::MethodNotFound,
1316 MRE::MethodInvalidSignature => Self::MethodInvalidSignature,
1317 }
1318 }
1319}
1320
1321impl From<unc_vm_runner::logic::errors::PrepareError> for PrepareError {
1322 fn from(outer_err: unc_vm_runner::logic::errors::PrepareError) -> Self {
1323 use unc_vm_runner::logic::errors::PrepareError as PE;
1324 match outer_err {
1325 PE::Serialization => Self::Serialization,
1326 PE::Deserialization => Self::Deserialization,
1327 PE::InternalMemoryDeclared => Self::InternalMemoryDeclared,
1328 PE::GasInstrumentation => Self::GasInstrumentation,
1329 PE::StackHeightInstrumentation => Self::StackHeightInstrumentation,
1330 PE::Instantiate => Self::Instantiate,
1331 PE::Memory => Self::Memory,
1332 PE::TooManyFunctions => Self::TooManyFunctions,
1333 PE::TooManyLocals => Self::TooManyLocals,
1334 }
1335 }
1336}
1337
1338impl From<unc_vm_runner::logic::errors::CompilationError> for CompilationError {
1339 fn from(outer_err: unc_vm_runner::logic::errors::CompilationError) -> Self {
1340 use unc_vm_runner::logic::errors::CompilationError as CE;
1341 match outer_err {
1342 CE::CodeDoesNotExist { account_id } => Self::CodeDoesNotExist {
1343 account_id: account_id.parse().expect("account_id in error must be valid"),
1344 },
1345 CE::PrepareError(pe) => Self::PrepareError(pe.into()),
1346 CE::WasmerCompileError { msg } => Self::WasmerCompileError { msg },
1347 }
1348 }
1349}
1350
1351impl From<unc_vm_runner::logic::errors::FunctionCallError> for FunctionCallError {
1352 fn from(outer_err: unc_vm_runner::logic::errors::FunctionCallError) -> Self {
1353 use unc_vm_runner::logic::errors::FunctionCallError as FCE;
1354 match outer_err {
1355 FCE::CompilationError(e) => Self::CompilationError(e.into()),
1356 FCE::MethodResolveError(e) => Self::MethodResolveError(e.into()),
1357 FCE::HostError(ref _e) => Self::ExecutionError(outer_err.to_string()),
1361 FCE::LinkError { msg } => Self::ExecutionError(format!("Link Error: {}", msg)),
1362 FCE::WasmTrap(ref _e) => Self::ExecutionError(outer_err.to_string()),
1363 }
1364 }
1365}
1366
1367#[cfg(feature = "new_epoch_sync")]
1368pub mod epoch_sync {
1369 use std::fmt::Debug;
1370 use unc_primitives_core::hash::CryptoHash;
1371 use unc_primitives_core::types::EpochHeight;
1372
1373 #[derive(Eq, PartialEq, Clone, strum::Display, Debug)]
1374 pub enum EpochSyncHashType {
1375 LastEpochBlock,
1376 LastFinalBlock,
1377 FirstEpochBlock,
1378 NextEpochFirstBlock,
1379 Other,
1380 BlockToSave,
1381 }
1382
1383 #[derive(Eq, PartialEq, Clone, thiserror::Error, Debug)]
1384 pub enum EpochSyncInfoError {
1385 #[error("{hash_type} hash {hash:?} not a part of EpochSyncInfo for epoch {epoch_height}")]
1386 HashNotFound { hash: CryptoHash, hash_type: EpochSyncHashType, epoch_height: EpochHeight },
1387 #[error("all_block_hashes.len() < 2 for epoch {epoch_height}")]
1388 ShortEpoch { epoch_height: EpochHeight },
1389 }
1390}