BankingStageErrorsTrackingS.../src/transaction_info.rs

137 lines
4.7 KiB
Rust
Raw Normal View History

2023-11-24 04:39:48 -08:00
use std::{collections::HashMap, hash::Hash};
2024-04-25 00:01:05 -07:00
use std::rc::Rc;
use std::sync::Arc;
2023-09-28 07:26:09 -07:00
use chrono::{DateTime, Utc};
2023-11-24 04:39:48 -08:00
use itertools::Itertools;
use solana_sdk::transaction::TransactionError;
use yellowstone_grpc_proto::prelude::SubscribeUpdateBankingTransactionResults;
2023-09-28 07:26:09 -07:00
2023-10-02 01:51:38 -07:00
fn convert_transaction_error_into_int(error: &TransactionError) -> u8 {
2023-09-28 07:26:09 -07:00
match error {
2023-10-02 01:51:38 -07:00
TransactionError::AccountBorrowOutstanding => 0,
TransactionError::AccountInUse => 1,
TransactionError::AccountLoadedTwice => 2,
TransactionError::AccountNotFound => 3,
TransactionError::AddressLookupTableNotFound => 4,
TransactionError::AlreadyProcessed => 5,
TransactionError::BlockhashNotFound => 6,
TransactionError::CallChainTooDeep => 7,
TransactionError::ClusterMaintenance => 8,
TransactionError::DuplicateInstruction(_) => 9,
2023-09-28 07:26:09 -07:00
TransactionError::InstructionError(_, _) => 10,
2023-10-02 01:51:38 -07:00
TransactionError::InsufficientFundsForFee => 11,
2023-09-28 07:26:09 -07:00
TransactionError::InsufficientFundsForRent { .. } => 12,
TransactionError::InvalidAccountForFee => 13,
TransactionError::InvalidAccountIndex => 14,
2023-10-02 01:51:38 -07:00
TransactionError::InvalidAddressLookupTableData => 15,
TransactionError::InvalidAddressLookupTableIndex => 16,
TransactionError::InvalidAddressLookupTableOwner => 17,
TransactionError::InvalidLoadedAccountsDataSizeLimit => 18,
TransactionError::InvalidProgramForExecution => 19,
TransactionError::InvalidRentPayingAccount => 20,
TransactionError::InvalidWritableAccount => 21,
TransactionError::MaxLoadedAccountsDataSizeExceeded => 22,
TransactionError::MissingSignatureForFee => 23,
TransactionError::ProgramAccountNotFound => 24,
TransactionError::ResanitizationNeeded => 25,
TransactionError::SanitizeFailure => 26,
TransactionError::SignatureFailure => 27,
TransactionError::TooManyAccountLocks => 28,
TransactionError::UnbalancedTransaction => 29,
TransactionError::UnsupportedVersion => 30,
TransactionError::WouldExceedAccountDataBlockLimit => 31,
TransactionError::WouldExceedAccountDataTotalLimit => 32,
TransactionError::WouldExceedMaxAccountCostLimit => 33,
TransactionError::WouldExceedMaxBlockCostLimit => 34,
TransactionError::WouldExceedMaxVoteCostLimit => 35,
2023-09-28 07:26:09 -07:00
}
}
#[derive(Clone, PartialEq)]
pub struct ErrorKey {
pub error: TransactionError,
2023-09-28 07:26:09 -07:00
}
2023-10-02 06:23:32 -07:00
impl ToString for ErrorKey {
fn to_string(&self) -> String {
self.error.to_string()
2023-10-02 06:23:32 -07:00
}
}
2023-09-28 07:26:09 -07:00
impl Hash for ErrorKey {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
let tmp = convert_transaction_error_into_int(&self.error);
tmp.hash(state)
}
}
impl ErrorKey {
pub fn to_int(&self) -> i32 {
convert_transaction_error_into_int(&self.error) as i32
2023-09-28 07:26:09 -07:00
}
}
2023-10-02 01:51:38 -07:00
impl Eq for ErrorKey {}
2023-09-28 07:26:09 -07:00
2023-10-02 06:23:32 -07:00
#[derive(Clone)]
2023-09-28 07:26:09 -07:00
pub struct TransactionInfo {
2023-10-02 01:51:38 -07:00
pub signature: String,
2023-09-28 07:26:09 -07:00
pub errors: HashMap<ErrorKey, usize>,
pub slot: u64,
pub utc_timestamp: DateTime<Utc>,
2023-11-24 04:39:48 -08:00
pub account_used: Vec<(String, bool)>,
// local write_version used in lite-rpc
pub write_version: u64,
2023-09-28 07:26:09 -07:00
}
impl TransactionInfo {
pub fn new(notification: &SubscribeUpdateBankingTransactionResults, global_error_plugin_write_version: u64) -> Self {
2023-10-16 06:53:44 -07:00
let mut errors = HashMap::new();
// Get time
let utc_timestamp = Utc::now();
2023-10-16 06:53:44 -07:00
match &notification.error {
Some(e) => {
let error: TransactionError = bincode::deserialize(&e.err).unwrap();
let key = ErrorKey { error };
errors.insert(key, 1);
2023-10-16 06:53:44 -07:00
}
None => {}
2023-10-16 06:53:44 -07:00
};
let account_used = notification
.accounts
.iter()
2023-11-24 04:39:48 -08:00
.map(|x| (x.account.clone(), x.is_writable))
.collect_vec();
2024-04-25 00:01:05 -07:00
2023-10-02 01:51:38 -07:00
Self {
2024-04-25 00:01:05 -07:00
signature: notification.signature.clone().into(),
2023-10-16 06:53:44 -07:00
errors,
slot: notification.slot,
utc_timestamp,
account_used,
write_version: global_error_plugin_write_version,
2023-09-28 07:26:09 -07:00
}
}
pub fn add_notification(&mut self, notification: &SubscribeUpdateBankingTransactionResults) {
match &notification.error {
Some(error) => {
let error: TransactionError = bincode::deserialize(&error.err).unwrap();
let key = ErrorKey { error };
2023-09-28 07:26:09 -07:00
match self.errors.get_mut(&key) {
Some(x) => {
2023-11-24 02:41:19 -08:00
*x += 1;
2023-10-02 01:51:38 -07:00
}
2023-09-28 07:26:09 -07:00
None => {
self.errors.insert(key, 1);
}
}
2023-10-02 01:51:38 -07:00
}
None => {}
2023-09-28 07:26:09 -07:00
}
}
2023-10-02 01:51:38 -07:00
}