1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
//! Home of the Proof of Stake contract's [`Error`] type. use alloc::vec::Vec; use core::result; use crate::{ bytesrepr::{self, ToBytes, U8_SERIALIZED_LENGTH}, CLType, CLTyped, }; /// Errors which can occur while executing the Proof of Stake contract. // TODO: Split this up into user errors vs. system errors. #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(u8)] pub enum Error { // ===== User errors ===== /// The given validator is not bonded. NotBonded = 0, /// There are too many bonding or unbonding attempts already enqueued to allow more. TooManyEventsInQueue, /// At least one validator must remain bonded. CannotUnbondLastValidator, /// Failed to bond or unbond as this would have resulted in exceeding the maximum allowed /// difference between the largest and smallest stakes. SpreadTooHigh, /// The given validator already has a bond or unbond attempt enqueued. MultipleRequests, /// Attempted to bond with a stake which was too small. BondTooSmall, /// Attempted to bond with a stake which was too large. BondTooLarge, /// Attempted to unbond an amount which was too large. UnbondTooLarge, /// While bonding, the transfer from source purse to the Proof of Stake internal purse failed. BondTransferFailed, /// While unbonding, the transfer from the Proof of Stake internal purse to the destination /// purse failed. UnbondTransferFailed, // ===== System errors ===== /// Internal error: a [`BlockTime`](crate::BlockTime) was unexpectedly out of sequence. TimeWentBackwards, /// Internal error: stakes were unexpectedly empty. StakesNotFound, /// Internal error: the PoS contract's payment purse wasn't found. PaymentPurseNotFound, /// Internal error: the PoS contract's payment purse key was the wrong type. PaymentPurseKeyUnexpectedType, /// Internal error: couldn't retrieve the balance for the PoS contract's payment purse. PaymentPurseBalanceNotFound, /// Internal error: the PoS contract's bonding purse wasn't found. BondingPurseNotFound, /// Internal error: the PoS contract's bonding purse key was the wrong type. BondingPurseKeyUnexpectedType, /// Internal error: the PoS contract's refund purse key was the wrong type. RefundPurseKeyUnexpectedType, /// Internal error: the PoS contract's rewards purse wasn't found. RewardsPurseNotFound, /// Internal error: the PoS contract's rewards purse key was the wrong type. RewardsPurseKeyUnexpectedType, // TODO: Put these in their own enum, and wrap them separately in `BondingError` and // `UnbondingError`. /// Internal error: failed to deserialize the stake's key. StakesKeyDeserializationFailed, /// Internal error: failed to deserialize the stake's balance. StakesDeserializationFailed, /// The invoked PoS function can only be called by system contracts, but was called by a user /// contract. SystemFunctionCalledByUserAccount, /// Internal error: while finalizing payment, the amount spent exceeded the amount available. InsufficientPaymentForAmountSpent, /// Internal error: while finalizing payment, failed to pay the validators (the transfer from /// the PoS contract's payment purse to rewards purse failed). FailedTransferToRewardsPurse, /// Internal error: while finalizing payment, failed to refund the caller's purse (the transfer /// from the PoS contract's payment purse to refund purse or account's main purse failed). FailedTransferToAccountPurse, /// PoS contract's "set_refund_purse" method can only be called by the payment code of a /// deploy, but was called by the session code. SetRefundPurseCalledOutsidePayment, } impl CLTyped for Error { fn cl_type() -> CLType { CLType::U8 } } impl ToBytes for Error { fn to_bytes(&self) -> result::Result<Vec<u8>, bytesrepr::Error> { let value = *self as u8; value.to_bytes() } fn serialized_length(&self) -> usize { U8_SERIALIZED_LENGTH } } /// An alias for `Result<T, pos::Error>`. pub type Result<T> = result::Result<T, Error>; // This error type is not intended to be used by third party crates. #[doc(hidden)] pub enum PurseLookupError { KeyNotFound, KeyUnexpectedType, } // This error type is not intended to be used by third party crates. #[doc(hidden)] impl PurseLookupError { pub fn bonding(err: PurseLookupError) -> Error { match err { PurseLookupError::KeyNotFound => Error::BondingPurseNotFound, PurseLookupError::KeyUnexpectedType => Error::BondingPurseKeyUnexpectedType, } } pub fn payment(err: PurseLookupError) -> Error { match err { PurseLookupError::KeyNotFound => Error::PaymentPurseNotFound, PurseLookupError::KeyUnexpectedType => Error::PaymentPurseKeyUnexpectedType, } } pub fn rewards(err: PurseLookupError) -> Error { match err { PurseLookupError::KeyNotFound => Error::RewardsPurseNotFound, PurseLookupError::KeyUnexpectedType => Error::RewardsPurseKeyUnexpectedType, } } }