Speed up `bigtable transaction-history` command

This commit is contained in:
Michael Vines 2020-09-09 20:21:52 -07:00 committed by mergify[bot]
parent 1db5c9d346
commit 10ce839ec0
3 changed files with 58 additions and 27 deletions

View File

@ -902,8 +902,8 @@ impl JsonRpcRequestProcessor {
), ),
); );
match bigtable_results { match bigtable_results {
Ok(mut bigtable_results) => { Ok(bigtable_results) => {
results.append(&mut bigtable_results); results.extend(bigtable_results.into_iter().map(|x| x.0));
} }
Err(err) => { Err(err) => {
warn!("{:?}", err); warn!("{:?}", err);

View File

@ -138,6 +138,7 @@ pub async fn transaction_history(
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
let bigtable = solana_storage_bigtable::LedgerStorage::new(true).await?; let bigtable = solana_storage_bigtable::LedgerStorage::new(true).await?;
let mut loaded_block: Option<(Slot, solana_transaction_status::ConfirmedBlock)> = None;
while limit > 0 { while limit > 0 {
let results = bigtable let results = bigtable
.get_confirmed_signatures_for_address( .get_confirmed_signatures_for_address(
@ -151,11 +152,11 @@ pub async fn transaction_history(
if results.is_empty() { if results.is_empty() {
break; break;
} }
before = Some(results.last().unwrap().signature); before = Some(results.last().unwrap().0.signature);
assert!(limit >= results.len()); assert!(limit >= results.len());
limit = limit.saturating_sub(results.len()); limit = limit.saturating_sub(results.len());
for result in results { for (result, index) in results {
if verbose { if verbose {
println!( println!(
"{}, slot={}, memo=\"{}\", status={}", "{}, slot={}, memo=\"{}\", status={}",
@ -172,23 +173,45 @@ pub async fn transaction_history(
} }
if show_transactions { if show_transactions {
match bigtable // Instead of using `bigtable.get_confirmed_transaction()`, fetch the entire block
.get_confirmed_transaction(&result.signature, UiTransactionEncoding::Base64) // and keep it around. This helps reduce BigTable query traffic and speeds up the
.await // results for high-volume addresses
{ loop {
Ok(Some(confirmed_transaction)) => { if let Some((slot, block)) = &loaded_block {
if *slot == result.slot {
match block.transactions.get(index as usize) {
None => {
println!(
" Transaction info for {} is corrupt",
result.signature
);
}
Some(transaction_with_meta) => {
println_transaction( println_transaction(
&confirmed_transaction &transaction_with_meta
.transaction
.transaction .transaction
.decode() .decode()
.expect("Successful decode"), .expect("Successful decode"),
&confirmed_transaction.transaction.meta, &transaction_with_meta.meta,
" ", " ",
); );
} }
Ok(None) => println!(" Confirmed transaction details not available"), }
Err(err) => println!(" Unable to get confirmed transaction details: {}", err), break;
}
}
match bigtable
.get_confirmed_block(result.slot, UiTransactionEncoding::Base64)
.await
{
Err(err) => {
println!(" Unable to get confirmed transaction details: {}", err);
break;
}
Ok(block) => {
loaded_block = Some((result.slot, block));
}
}
} }
println!(); println!();
} }

View File

@ -367,7 +367,12 @@ impl LedgerStorage {
before_signature: Option<&Signature>, before_signature: Option<&Signature>,
until_signature: Option<&Signature>, until_signature: Option<&Signature>,
limit: usize, limit: usize,
) -> Result<Vec<(ConfirmedTransactionStatusWithSignature, u32 /*slot index*/)>> { ) -> Result<
Vec<(
ConfirmedTransactionStatusWithSignature,
u32, /*slot index*/
)>,
> {
let mut bigtable = self.connection.client(); let mut bigtable = self.connection.client();
let address_prefix = format!("{}/", address); let address_prefix = format!("{}/", address);
@ -436,12 +441,15 @@ impl LedgerStorage {
if slot == last_slot && tx_by_addr_info.index <= until_transaction_index { if slot == last_slot && tx_by_addr_info.index <= until_transaction_index {
continue; continue;
} }
infos.push((ConfirmedTransactionStatusWithSignature { infos.push((
ConfirmedTransactionStatusWithSignature {
signature: tx_by_addr_info.signature, signature: tx_by_addr_info.signature,
slot, slot,
err: tx_by_addr_info.err, err: tx_by_addr_info.err,
memo: tx_by_addr_info.memo, memo: tx_by_addr_info.memo,
}, tx_by_addr_info.index)); },
tx_by_addr_info.index,
));
// Respect limit // Respect limit
if infos.len() >= limit { if infos.len() >= limit {
break 'outer; break 'outer;