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:
Josh
2021-01-20 22:10:35 -08:00
committed by GitHub
parent 447e3de1f2
commit 1de6d28eaf
10 changed files with 1219 additions and 20 deletions

View File

@@ -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,
)