use {
crate::{
instruction::InstructionError, message::SanitizeMessageError, sanitize::SanitizeError,
},
serde::Serialize,
thiserror::Error,
};
#[derive(
Error, Serialize, Deserialize, Debug, PartialEq, Eq, Clone, AbiExample, AbiEnumVisitor,
)]
pub enum TransactionError {
#[error("Account in use")]
AccountInUse,
#[error("Account loaded twice")]
AccountLoadedTwice,
#[error("Attempt to debit an account but found no record of a prior credit.")]
AccountNotFound,
#[error("Attempt to load a program that does not exist")]
ProgramAccountNotFound,
#[error("Insufficient funds for fee")]
InsufficientFundsForFee,
#[error("This account may not be used to pay transaction fees")]
InvalidAccountForFee,
#[error("This transaction has already been processed")]
AlreadyProcessed,
#[error("Blockhash not found")]
BlockhashNotFound,
#[error("Error processing Instruction {0}: {1}")]
InstructionError(u8, InstructionError),
#[error("Loader call chain is too deep")]
CallChainTooDeep,
#[error("Transaction requires a fee but has no signature present")]
MissingSignatureForFee,
#[error("Transaction contains an invalid account reference")]
InvalidAccountIndex,
#[error("Transaction did not pass signature verification")]
SignatureFailure,
#[error("This program may not be used for executing instructions")]
InvalidProgramForExecution,
#[error("Transaction failed to sanitize accounts offsets correctly")]
SanitizeFailure,
#[error("Transactions are currently disabled due to cluster maintenance")]
ClusterMaintenance,
#[error("Transaction processing left an account with an outstanding borrowed reference")]
AccountBorrowOutstanding,
#[error("Transaction would exceed max Block Cost Limit")]
WouldExceedMaxBlockCostLimit,
#[error("Transaction version is unsupported")]
UnsupportedVersion,
#[error("Transaction loads a writable account that cannot be written")]
InvalidWritableAccount,
#[error("Transaction would exceed max account limit within the block")]
WouldExceedMaxAccountCostLimit,
#[error("Transaction would exceed max account data limit within the block")]
WouldExceedMaxAccountDataCostLimit,
#[error("Transaction locked too many accounts")]
TooManyAccountLocks,
#[error("Transaction loads an address table account that doesn't exist")]
AddressLookupTableNotFound,
#[error("Transaction loads an address table account with an invalid owner")]
InvalidAddressLookupTableOwner,
#[error("Transaction loads an address table account with invalid data")]
InvalidAddressLookupTableData,
#[error("Transaction address table lookup uses an invalid index")]
InvalidAddressLookupTableIndex,
#[error(
"Transaction leaves an account with data with a lower balance than rent-exempt minimum"
)]
InvalidRentPayingAccount,
#[error("Transaction would exceed max Vote Cost Limit")]
WouldExceedMaxVoteCostLimit,
}
impl From<SanitizeError> for TransactionError {
fn from(_: SanitizeError) -> Self {
Self::SanitizeFailure
}
}
impl From<SanitizeMessageError> for TransactionError {
fn from(_err: SanitizeMessageError) -> Self {
Self::SanitizeFailure
}
}
#[derive(Debug, Error, PartialEq, Eq, Clone)]
pub enum AddressLookupError {
#[error("Attempted to lookup addresses from a table that does not exist")]
LookupTableAccountNotFound,
#[error("Attempted to lookup addresses from an account owned by the wrong program")]
InvalidAccountOwner,
#[error("Attempted to lookup addresses from an invalid account")]
InvalidAccountData,
#[error("Address lookup contains an invalid index")]
InvalidLookupIndex,
}
impl From<AddressLookupError> for TransactionError {
fn from(err: AddressLookupError) -> Self {
match err {
AddressLookupError::LookupTableAccountNotFound => Self::AddressLookupTableNotFound,
AddressLookupError::InvalidAccountOwner => Self::InvalidAddressLookupTableOwner,
AddressLookupError::InvalidAccountData => Self::InvalidAddressLookupTableData,
AddressLookupError::InvalidLookupIndex => Self::InvalidAddressLookupTableIndex,
}
}
}