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 {
Ok(mut bigtable_results) => {
results.append(&mut bigtable_results);
Ok(bigtable_results) => {
results.extend(bigtable_results.into_iter().map(|x| x.0));
}
Err(err) => {
warn!("{:?}", err);

View File

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

View File

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