Avoid deserializing alts all the time

This commit is contained in:
godmodegalactus 2023-12-22 16:42:17 +01:00
parent c51d8f87b5
commit bf15a3cd14
No known key found for this signature in database
GPG Key ID: 22DA4A30887FDA3C
4 changed files with 48 additions and 48 deletions

View File

@ -1,13 +1,10 @@
use dashmap::DashMap;
use itertools::Itertools;
use prometheus::{IntGauge, register_int_gauge, opts};
use prometheus::{opts, register_int_gauge, IntGauge};
use solana_address_lookup_table_program::state::AddressLookupTable;
use solana_rpc_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::{
commitment_config::CommitmentConfig, pubkey::Pubkey, slot_hashes::SlotHashes,
slot_history::Slot,
};
use std::sync::Arc;
use solana_sdk::{account::ReadableAccount, commitment_config::CommitmentConfig, pubkey::Pubkey};
use std::{sync::Arc, time::Duration};
use crate::block_info::TransactionAccount;
lazy_static::lazy_static! {
@ -17,7 +14,7 @@ lazy_static::lazy_static! {
pub struct ALTStore {
rpc_client: Arc<RpcClient>,
pub map: Arc<DashMap<Pubkey, Vec<u8>>>,
pub map: Arc<DashMap<Pubkey, Vec<Pubkey>>>,
}
impl ALTStore {
@ -41,42 +38,49 @@ impl ALTStore {
.await;
if let Ok(account_res) = response {
if let Some(account) = account_res.value {
if self.map.insert(*alt, account.data).is_none() {
let lookup_table = AddressLookupTable::deserialize(&account.data()).unwrap();
if self
.map
.insert(*alt, lookup_table.addresses.to_vec())
.is_none()
{
ALTS_IN_STORE.inc();
}
drop(lookup_table);
}
}
}
pub async fn load_accounts(
&self,
slot: Slot,
alt: &Pubkey,
write_accounts: &Vec<u8>,
read_account: &Vec<u8>,
) -> Option<Vec<TransactionAccount>> {
match self.map.get(&alt) {
Some(account) => {
let lookup_table = AddressLookupTable::deserialize(&account.value()).unwrap();
let write_accounts =
lookup_table.lookup(slot, write_accounts, &SlotHashes::default());
let read_account = lookup_table.lookup(slot, read_account, &SlotHashes::default());
let write_accounts = if let Ok(write_accounts) = write_accounts {
write_accounts
} else {
Some(lookup_table) => {
if write_accounts
.iter()
.any(|x| *x as usize >= lookup_table.len())
|| read_account
.iter()
.any(|x| *x as usize >= lookup_table.len())
{
return None;
};
let read_account = if let Ok(read_account) = read_account {
read_account
} else {
return None;
};
}
let write_accounts = write_accounts
.iter()
.map(|i| lookup_table[*i as usize])
.collect_vec();
let read_account = read_account
.iter()
.map(|i| lookup_table[*i as usize])
.collect_vec();
let wa = write_accounts
.iter()
.map(|key| TransactionAccount {
key: key.to_string(),
key: key.clone(),
is_writable: true,
is_signer: false,
is_alt: true,
@ -85,7 +89,7 @@ impl ALTStore {
let ra = read_account
.iter()
.map(|key| TransactionAccount {
key: key.to_string(),
key: key.clone(),
is_writable: false,
is_signer: false,
is_alt: true,
@ -99,26 +103,20 @@ impl ALTStore {
pub async fn get_accounts(
&self,
current_slot: Slot,
alt: &Pubkey,
write_accounts: &Vec<u8>,
read_account: &Vec<u8>,
) -> Vec<TransactionAccount> {
self.load_alt_from_rpc(&alt).await;
match self
.load_accounts(current_slot, alt, write_accounts, read_account)
.await
{
match self.load_accounts(alt, write_accounts, read_account).await {
Some(x) => x,
None => {
//load alt
self.reload_alt_from_rpc(&alt).await;
match self
.load_accounts(current_slot, alt, write_accounts, read_account)
.await
{
match self.load_accounts(alt, write_accounts, read_account).await {
Some(x) => x,
None => {
tokio::time::sleep(Duration::from_millis(500)).await;
// reloading did not work
log::error!("cannot load alt even after");
vec![]

View File

@ -80,7 +80,7 @@ pub struct PrioritizationFeesInfo {
#[derive(Clone)]
pub struct TransactionAccount {
pub key: String,
pub key: Pubkey,
pub is_writable: bool,
pub is_signer: bool,
pub is_alt: bool,
@ -117,8 +117,8 @@ impl BlockInfo {
slot: Slot,
message: &VersionedMessage,
prio_fees_in_block: &mut Vec<u64>,
writelocked_accounts: &mut HashMap<String, AccountData>,
readlocked_accounts: &mut HashMap<String, AccountData>,
writelocked_accounts: &mut HashMap<Pubkey, AccountData>,
readlocked_accounts: &mut HashMap<Pubkey, AccountData>,
cu_consumed: u64,
total_cu_requested: &mut u64,
is_vote: bool,
@ -178,7 +178,7 @@ impl BlockInfo {
.iter()
.enumerate()
.map(|(index, account)| TransactionAccount {
key: account.to_string(),
key: account.clone(),
is_writable: message.is_maybe_writable(index),
is_signer: message.is_signer(index),
is_alt: false,
@ -189,7 +189,6 @@ impl BlockInfo {
let atl_acc = atl_message.account_key;
let mut atl_accs = atl_store
.get_accounts(
slot,
&atl_acc,
&atl_message.writable_indexes,
&atl_message.readonly_indexes,
@ -214,7 +213,7 @@ impl BlockInfo {
writelocked_accounts.insert(
writable_account.clone(),
AccountData {
key: writable_account,
key: writable_account.to_string(),
cu_consumed,
cu_requested,
vec_pf: vec![prioritization_fees],
@ -239,7 +238,7 @@ impl BlockInfo {
readlocked_accounts.insert(
readable_account.clone(),
AccountData {
key: readable_account,
key: readable_account.to_string(),
cu_consumed,
cu_requested,
vec_pf: vec![prioritization_fees],
@ -265,8 +264,8 @@ impl BlockInfo {
}
pub fn calculate_account_usage(
writelocked_accounts: &HashMap<String, AccountData>,
readlocked_accounts: &HashMap<String, AccountData>,
writelocked_accounts: &HashMap<Pubkey, AccountData>,
readlocked_accounts: &HashMap<Pubkey, AccountData>,
) -> Vec<AccountUsage> {
let mut accounts = writelocked_accounts
.iter()
@ -335,8 +334,8 @@ impl BlockInfo {
.unwrap_or(0)
})
.sum::<u64>() as i64;
let mut writelocked_accounts: HashMap<String, AccountData> = HashMap::new();
let mut readlocked_accounts: HashMap<String, AccountData> = HashMap::new();
let mut writelocked_accounts: HashMap<Pubkey, AccountData> = HashMap::new();
let mut readlocked_accounts: HashMap<Pubkey, AccountData> = HashMap::new();
let mut total_cu_requested: u64 = 0;
let mut prio_fees_in_block = vec![];
let mut block_transactions = vec![];

View File

@ -1,5 +1,6 @@
use clap::Parser;
use itertools::Itertools;
use solana_address_lookup_table_program::state::AddressLookupTable;
use solana_rpc_client::nonblocking::rpc_client::{self, RpcClient};
use solana_sdk::pubkey::Pubkey;
use std::{
@ -230,7 +231,9 @@ async fn start_tracking_blocks(
if let Some(account) = account_update.account {
let bytes: [u8; 32] = account.pubkey.try_into().unwrap_or(Pubkey::default().to_bytes());
let pubkey = Pubkey::new_from_array(bytes);
atl_store.map.insert( pubkey, account.data);
let lookup_table = AddressLookupTable::deserialize(&account.data).unwrap();
atl_store.map.insert( pubkey, lookup_table.addresses.to_vec());
drop(lookup_table);
}
},
_ => {}

View File

@ -676,7 +676,7 @@ impl PostgresSession {
.accounts
.iter()
.map(|acc| AccountUsed {
key: acc.key.clone(),
key: acc.key.to_string(),
writable: acc.is_writable,
is_signer: acc.is_signer,
is_atl: acc.is_alt,