Add block_time to getConfirmedSignaturesForAddress2 and getConfirmedTransaction (#14572)
* add block_time to get_confirmed_signatures_for_address2 and protobuf implementation for tx_by_addr * add tests for convert * update cargo lock * run cargo format after rebase * introduce legacy TransactionByAddrInfo * move LegacyTransactionByAddrInfo back to storage-bigtable
This commit is contained in:
@@ -8,9 +8,10 @@ use solana_sdk::{
|
||||
transaction::{Transaction, TransactionError},
|
||||
};
|
||||
use solana_storage_proto::convert::generated;
|
||||
use solana_storage_proto::convert::tx_by_addr;
|
||||
use solana_transaction_status::{
|
||||
ConfirmedBlock, ConfirmedTransaction, ConfirmedTransactionStatusWithSignature, Reward,
|
||||
TransactionConfirmationStatus, TransactionStatus, TransactionStatusMeta,
|
||||
TransactionByAddrInfo, TransactionConfirmationStatus, TransactionStatus, TransactionStatusMeta,
|
||||
TransactionWithStatusMeta,
|
||||
};
|
||||
use std::{collections::HashMap, convert::TryInto};
|
||||
@@ -263,14 +264,31 @@ impl From<TransactionInfo> for TransactionStatus {
|
||||
}
|
||||
}
|
||||
|
||||
// A serialized `Vec<TransactionByAddrInfo>` is stored in the `tx-by-addr` table. The row keys are
|
||||
// the one's compliment of the slot so that rows may be listed in reverse order
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct TransactionByAddrInfo {
|
||||
signature: Signature, // The transaction signature
|
||||
err: Option<TransactionError>, // None if the transaction executed successfully
|
||||
index: u32, // Where the transaction is located in the block
|
||||
memo: Option<String>, // Transaction memo
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
struct LegacyTransactionByAddrInfo {
|
||||
pub signature: Signature, // The transaction signature
|
||||
pub err: Option<TransactionError>, // None if the transaction executed successfully
|
||||
pub index: u32, // Where the transaction is located in the block
|
||||
pub memo: Option<String>, // Transaction memo
|
||||
}
|
||||
|
||||
impl From<LegacyTransactionByAddrInfo> for TransactionByAddrInfo {
|
||||
fn from(legacy: LegacyTransactionByAddrInfo) -> Self {
|
||||
let LegacyTransactionByAddrInfo {
|
||||
signature,
|
||||
err,
|
||||
index,
|
||||
memo,
|
||||
} = legacy;
|
||||
|
||||
Self {
|
||||
signature,
|
||||
err,
|
||||
index,
|
||||
memo,
|
||||
block_time: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -363,6 +381,7 @@ impl LedgerStorage {
|
||||
Ok(Some(ConfirmedTransaction {
|
||||
slot,
|
||||
transaction: bucket_block_transaction,
|
||||
block_time: block.block_time,
|
||||
}))
|
||||
}
|
||||
}
|
||||
@@ -417,12 +436,17 @@ impl LedgerStorage {
|
||||
let mut infos = vec![];
|
||||
|
||||
let starting_slot_tx_len = bigtable
|
||||
.get_bincode_cell::<Vec<TransactionByAddrInfo>>(
|
||||
.get_protobuf_or_bincode_cell::<Vec<LegacyTransactionByAddrInfo>, tx_by_addr::TransactionByAddr>(
|
||||
"tx-by-addr",
|
||||
format!("{}{}", address_prefix, slot_to_key(!first_slot)),
|
||||
)
|
||||
.await
|
||||
.map(|txs| txs.len())
|
||||
.map(|cell_data| {
|
||||
match cell_data {
|
||||
bigtable::CellData::Bincode(tx_by_addr) => tx_by_addr.len(),
|
||||
bigtable::CellData::Protobuf(tx_by_addr) => tx_by_addr.tx_by_addrs.len(),
|
||||
}
|
||||
})
|
||||
.unwrap_or(0);
|
||||
|
||||
// Return the next tx-by-addr data of amount `limit` plus extra to account for the largest
|
||||
@@ -443,8 +467,27 @@ impl LedgerStorage {
|
||||
row_key
|
||||
))
|
||||
})?;
|
||||
let mut cell_data: Vec<TransactionByAddrInfo> =
|
||||
bigtable::deserialize_bincode_cell_data(&data, "tx-by-addr", row_key)?;
|
||||
|
||||
let deserialized_cell_data = bigtable::deserialize_protobuf_or_bincode_cell_data::<
|
||||
Vec<LegacyTransactionByAddrInfo>,
|
||||
tx_by_addr::TransactionByAddr,
|
||||
>(&data, "tx-by-addr", row_key.clone())?;
|
||||
|
||||
let mut cell_data: Vec<TransactionByAddrInfo> = match deserialized_cell_data {
|
||||
bigtable::CellData::Bincode(tx_by_addr) => {
|
||||
tx_by_addr.into_iter().map(|legacy| legacy.into()).collect()
|
||||
}
|
||||
bigtable::CellData::Protobuf(tx_by_addr) => {
|
||||
tx_by_addr.try_into().map_err(|error| {
|
||||
bigtable::Error::ObjectCorrupt(format!(
|
||||
"Failed to deserialize: {}: tx-by-addr/{}",
|
||||
error,
|
||||
row_key.clone()
|
||||
))
|
||||
})?
|
||||
}
|
||||
};
|
||||
|
||||
cell_data.reverse();
|
||||
for tx_by_addr_info in cell_data.into_iter() {
|
||||
// Filter out records before `before_transaction_index`
|
||||
@@ -461,6 +504,7 @@ impl LedgerStorage {
|
||||
slot,
|
||||
err: tx_by_addr_info.err,
|
||||
memo: tx_by_addr_info.memo,
|
||||
block_time: tx_by_addr_info.block_time,
|
||||
},
|
||||
tx_by_addr_info.index,
|
||||
));
|
||||
@@ -500,6 +544,7 @@ impl LedgerStorage {
|
||||
err: err.clone(),
|
||||
index,
|
||||
memo: None, // TODO
|
||||
block_time: confirmed_block.block_time,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -520,7 +565,12 @@ impl LedgerStorage {
|
||||
.map(|(address, transaction_info_by_addr)| {
|
||||
(
|
||||
format!("{}/{}", address, slot_to_key(!slot)),
|
||||
transaction_info_by_addr,
|
||||
tx_by_addr::TransactionByAddr {
|
||||
tx_by_addrs: transaction_info_by_addr
|
||||
.into_iter()
|
||||
.map(|by_addr| by_addr.into())
|
||||
.collect(),
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
@@ -535,7 +585,7 @@ impl LedgerStorage {
|
||||
if !tx_by_addr_cells.is_empty() {
|
||||
bytes_written += self
|
||||
.connection
|
||||
.put_bincode_cells_with_retry::<Vec<TransactionByAddrInfo>>(
|
||||
.put_protobuf_cells_with_retry::<tx_by_addr::TransactionByAddr>(
|
||||
"tx-by-addr",
|
||||
&tx_by_addr_cells,
|
||||
)
|
||||
|
Reference in New Issue
Block a user