Add Blockstore::get_rooted_block_with_entries method (#33995)
* Add helper structs to hold block and entry summaries * Add Blockstore::get_rooted_block_with_entries and dedupe innards * Review comments
This commit is contained in:
parent
a9509f56b7
commit
28e08ac141
|
@ -59,7 +59,7 @@ use {
|
||||||
solana_transaction_status::{
|
solana_transaction_status::{
|
||||||
ConfirmedTransactionStatusWithSignature, ConfirmedTransactionWithStatusMeta, Rewards,
|
ConfirmedTransactionStatusWithSignature, ConfirmedTransactionWithStatusMeta, Rewards,
|
||||||
TransactionStatusMeta, TransactionWithStatusMeta, VersionedConfirmedBlock,
|
TransactionStatusMeta, TransactionWithStatusMeta, VersionedConfirmedBlock,
|
||||||
VersionedTransactionWithStatusMeta,
|
VersionedConfirmedBlockWithEntries, VersionedTransactionWithStatusMeta,
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
@ -2031,6 +2031,33 @@ impl Blockstore {
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
require_previous_blockhash: bool,
|
require_previous_blockhash: bool,
|
||||||
) -> Result<VersionedConfirmedBlock> {
|
) -> Result<VersionedConfirmedBlock> {
|
||||||
|
self.get_complete_block_with_entries(slot, require_previous_blockhash, false)
|
||||||
|
.map(|result| result.block)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_rooted_block_with_entries(
|
||||||
|
&self,
|
||||||
|
slot: Slot,
|
||||||
|
require_previous_blockhash: bool,
|
||||||
|
) -> Result<VersionedConfirmedBlockWithEntries> {
|
||||||
|
datapoint_info!(
|
||||||
|
"blockstore-rpc-api",
|
||||||
|
("method", "get_rooted_block_with_entries", String)
|
||||||
|
);
|
||||||
|
let _lock = self.check_lowest_cleanup_slot(slot)?;
|
||||||
|
|
||||||
|
if self.is_root(slot) {
|
||||||
|
return self.get_complete_block_with_entries(slot, require_previous_blockhash, true);
|
||||||
|
}
|
||||||
|
Err(BlockstoreError::SlotNotRooted)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_complete_block_with_entries(
|
||||||
|
&self,
|
||||||
|
slot: Slot,
|
||||||
|
require_previous_blockhash: bool,
|
||||||
|
populate_entries: bool,
|
||||||
|
) -> Result<VersionedConfirmedBlockWithEntries> {
|
||||||
let Some(slot_meta) = self.meta_cf.get(slot)? else {
|
let Some(slot_meta) = self.meta_cf.get(slot)? else {
|
||||||
info!("SlotMeta not found for slot {}", slot);
|
info!("SlotMeta not found for slot {}", slot);
|
||||||
return Err(BlockstoreError::SlotUnavailable);
|
return Err(BlockstoreError::SlotUnavailable);
|
||||||
|
@ -2042,9 +2069,26 @@ impl Blockstore {
|
||||||
.last()
|
.last()
|
||||||
.map(|entry| entry.hash)
|
.map(|entry| entry.hash)
|
||||||
.unwrap_or_else(|| panic!("Rooted slot {slot:?} must have blockhash"));
|
.unwrap_or_else(|| panic!("Rooted slot {slot:?} must have blockhash"));
|
||||||
|
let mut starting_transaction_index = 0;
|
||||||
|
let mut entries = if populate_entries {
|
||||||
|
Vec::with_capacity(slot_entries.len())
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
let slot_transaction_iterator = slot_entries
|
let slot_transaction_iterator = slot_entries
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|entry| entry.transactions)
|
.flat_map(|entry| {
|
||||||
|
if populate_entries {
|
||||||
|
entries.push(solana_transaction_status::EntrySummary {
|
||||||
|
num_hashes: entry.num_hashes,
|
||||||
|
hash: entry.hash,
|
||||||
|
num_transactions: entry.transactions.len() as u64,
|
||||||
|
starting_transaction_index,
|
||||||
|
});
|
||||||
|
starting_transaction_index += entry.transactions.len();
|
||||||
|
}
|
||||||
|
entry.transactions
|
||||||
|
})
|
||||||
.map(|transaction| {
|
.map(|transaction| {
|
||||||
if let Err(err) = transaction.sanitize() {
|
if let Err(err) = transaction.sanitize() {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -2096,7 +2140,7 @@ impl Blockstore {
|
||||||
block_time,
|
block_time,
|
||||||
block_height,
|
block_height,
|
||||||
};
|
};
|
||||||
return Ok(block);
|
return Ok(VersionedConfirmedBlockWithEntries { block, entries });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(BlockstoreError::SlotUnavailable)
|
Err(BlockstoreError::SlotUnavailable)
|
||||||
|
|
|
@ -12,6 +12,7 @@ use {
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{Slot, UnixTimestamp},
|
clock::{Slot, UnixTimestamp},
|
||||||
commitment_config::CommitmentConfig,
|
commitment_config::CommitmentConfig,
|
||||||
|
hash::Hash,
|
||||||
instruction::CompiledInstruction,
|
instruction::CompiledInstruction,
|
||||||
message::{
|
message::{
|
||||||
v0::{self, LoadedAddresses, LoadedMessage, MessageAddressTableLookup},
|
v0::{self, LoadedAddresses, LoadedMessage, MessageAddressTableLookup},
|
||||||
|
@ -793,6 +794,23 @@ pub struct UiConfirmedBlock {
|
||||||
pub block_height: Option<u64>,
|
pub block_height: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Confirmed block with type guarantees that transaction metadata is always
|
||||||
|
// present, as well as a list of the entry data needed to cryptographically
|
||||||
|
// verify the block. Used for uploading to BigTable.
|
||||||
|
pub struct VersionedConfirmedBlockWithEntries {
|
||||||
|
pub block: VersionedConfirmedBlock,
|
||||||
|
pub entries: Vec<EntrySummary>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data needed to reconstruct an Entry, given an ordered list of transactions in
|
||||||
|
// a block. Used for uploading to BigTable.
|
||||||
|
pub struct EntrySummary {
|
||||||
|
pub num_hashes: u64,
|
||||||
|
pub hash: Hash,
|
||||||
|
pub num_transactions: u64,
|
||||||
|
pub starting_transaction_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum TransactionWithStatusMeta {
|
pub enum TransactionWithStatusMeta {
|
||||||
|
|
Loading…
Reference in New Issue