RPC: Plug getConfirmedSignaturesForAddress2 into bigtable storage (bp #11395) (#11405)

* Plug getConfirmedSignaturesForAddress2 into bigtable storage

(cherry picked from commit 4222932e08)

# Conflicts:
#	ledger-tool/src/bigtable.rs
#	storage-bigtable/src/lib.rs

* Upgrade help description

(cherry picked from commit 9abb7db5f8)

Co-authored-by: Michael Vines <mvines@gmail.com>
This commit is contained in:
mergify[bot]
2020-08-06 07:49:30 +00:00
committed by GitHub
parent 0a4a3fd37e
commit 798a6db915
4 changed files with 67 additions and 43 deletions

View File

@ -256,9 +256,8 @@ impl ClusterQuerySubCommands for App<'_, '_> {
) )
.subcommand( .subcommand(
SubCommand::with_name("transaction-history") SubCommand::with_name("transaction-history")
.about("Show historical transactions affecting the given address, \ .about("Show historical transactions affecting the given address \
ordered based on the slot in which they were confirmed in \ from newest to oldest")
from lowest to highest slot")
.arg( .arg(
pubkey!(Arg::with_name("address") pubkey!(Arg::with_name("address")
.index(1) .index(1)

View File

@ -808,8 +808,8 @@ impl JsonRpcRequestProcessor {
pub fn get_confirmed_signatures_for_address2( pub fn get_confirmed_signatures_for_address2(
&self, &self,
address: Pubkey, address: Pubkey,
before: Option<Signature>, mut before: Option<Signature>,
limit: usize, mut limit: usize,
) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>> { ) -> Result<Vec<RpcConfirmedTransactionStatusWithSignature>> {
if self.config.enable_rpc_transaction_history { if self.config.enable_rpc_transaction_history {
let highest_confirmed_root = self let highest_confirmed_root = self
@ -818,7 +818,7 @@ impl JsonRpcRequestProcessor {
.unwrap() .unwrap()
.highest_confirmed_slot(); .highest_confirmed_slot();
let results = self let mut results = self
.blockstore .blockstore
.get_confirmed_signatures_for_address2( .get_confirmed_signatures_for_address2(
address, address,
@ -828,6 +828,27 @@ impl JsonRpcRequestProcessor {
) )
.map_err(|err| Error::invalid_params(format!("{}", err)))?; .map_err(|err| Error::invalid_params(format!("{}", err)))?;
if results.len() < limit {
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
if !results.is_empty() {
limit -= results.len();
before = results.last().map(|x| x.signature);
}
let mut bigtable_results = self
.runtime_handle
.block_on(
bigtable_ledger_storage.get_confirmed_signatures_for_address(
&address,
before.as_ref(),
limit,
),
)
.map_err(|err| Error::invalid_params(format!("{}", err)))?;
results.append(&mut bigtable_results)
}
}
Ok(results.into_iter().map(|x| x.into()).collect()) Ok(results.into_iter().map(|x| x.into()).collect())
} else { } else {
Ok(vec![]) Ok(vec![])

View File

@ -308,30 +308,39 @@ async fn confirm(signature: &Signature, verbose: bool) -> Result<(), Box<dyn std
pub async fn transaction_history( pub async fn transaction_history(
address: &Pubkey, address: &Pubkey,
limit: usize, mut limit: usize,
before: Option<&Signature>, mut before: Option<Signature>,
verbose: bool, verbose: bool,
) -> 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?;
while limit > 0 {
let results = bigtable let results = bigtable
.get_confirmed_signatures_for_address(address, before, limit) .get_confirmed_signatures_for_address(address, before.as_ref(), limit.min(1000))
.await?; .await?;
for (signature, slot, memo, err) in results { if results.is_empty() {
break;
}
before = Some(results.last().unwrap().signature);
assert!(limit >= results.len());
limit = limit.saturating_sub(results.len());
for result in results {
if verbose { if verbose {
println!( println!(
"{}, slot={}, memo=\"{}\", status={}", "{}, slot={}, memo=\"{}\", status={}",
signature, result.signature,
slot, result.slot,
memo.unwrap_or_else(|| "".to_string()), result.memo.unwrap_or_else(|| "".to_string()),
match err { match result.err {
None => "Confirmed".to_string(), None => "Confirmed".to_string(),
Some(err) => format!("Failed: {:?}", err), Some(err) => format!("Failed: {:?}", err),
} }
); );
} else { } else {
println!("{}", signature); println!("{}", result.signature);
}
} }
} }
Ok(()) Ok(())
@ -443,9 +452,8 @@ impl BigTableSubCommand for App<'_, '_> {
.subcommand( .subcommand(
SubCommand::with_name("transaction-history") SubCommand::with_name("transaction-history")
.about( .about(
"Show historical transactions affecting the given address, \ "Show historical transactions affecting the given address \
ordered based on the slot in which they were confirmed in \ from newest to oldest",
from lowest to highest slot",
) )
.arg( .arg(
Arg::with_name("address") Arg::with_name("address")
@ -462,7 +470,7 @@ impl BigTableSubCommand for App<'_, '_> {
.value_name("LIMIT") .value_name("LIMIT")
.validator(is_slot) .validator(is_slot)
.index(2) .index(2)
.default_value("1000") .default_value("18446744073709551615")
.help("Maximum number of transaction signatures to return"), .help("Maximum number of transaction signatures to return"),
) )
.arg( .arg(
@ -531,12 +539,7 @@ pub fn bigtable_process_command(ledger_path: &Path, matches: &ArgMatches<'_>) {
.map(|signature| signature.parse().expect("Invalid signature")); .map(|signature| signature.parse().expect("Invalid signature"));
let verbose = arg_matches.is_present("verbose"); let verbose = arg_matches.is_present("verbose");
runtime.block_on(transaction_history( runtime.block_on(transaction_history(&address, limit, before, verbose))
&address,
limit,
before.as_ref(),
verbose,
))
} }
_ => unreachable!(), _ => unreachable!(),
}; };

View File

@ -8,8 +8,9 @@ use solana_sdk::{
transaction::{Transaction, TransactionError}, transaction::{Transaction, TransactionError},
}; };
use solana_transaction_status::{ use solana_transaction_status::{
ConfirmedBlock, ConfirmedTransaction, EncodedTransaction, Rewards, TransactionStatus, ConfirmedBlock, ConfirmedTransaction, ConfirmedTransactionStatusWithSignature,
TransactionWithStatusMeta, UiTransactionEncoding, UiTransactionStatusMeta, EncodedTransaction, Rewards, TransactionStatus, TransactionWithStatusMeta,
UiTransactionEncoding, UiTransactionStatusMeta,
}; };
use std::{ use std::{
collections::HashMap, collections::HashMap,
@ -365,7 +366,7 @@ impl LedgerStorage {
address: &Pubkey, address: &Pubkey,
before_signature: Option<&Signature>, before_signature: Option<&Signature>,
limit: usize, limit: usize,
) -> Result<Vec<(Signature, Slot, Option<String>, Option<TransactionError>)>> { ) -> Result<Vec<ConfirmedTransactionStatusWithSignature>> {
let mut bigtable = self.connection.client(); let mut bigtable = self.connection.client();
let address_prefix = format!("{}/", address); let address_prefix = format!("{}/", address);
@ -414,12 +415,12 @@ impl LedgerStorage {
.into_iter() .into_iter()
.skip(first_transaction_index as usize) .skip(first_transaction_index as usize)
{ {
infos.push(( infos.push(ConfirmedTransactionStatusWithSignature {
tx_by_addr_info.signature, signature: tx_by_addr_info.signature,
slot, slot,
tx_by_addr_info.memo, err: tx_by_addr_info.err,
tx_by_addr_info.err, memo: tx_by_addr_info.memo,
)); });
if infos.len() >= limit { if infos.len() >= limit {
break 'outer; break 'outer;
} }