chains Merkle shreds in broadcast fake shreds (#35061)

The commit migrates
    turbine/src/broadcast_stage/broadcast_fake_shreds_run.rs
to use chained Merkle shreds variant.
This commit is contained in:
behzad nouri 2024-02-06 20:02:38 +00:00 committed by GitHub
parent d52b1ac795
commit 8d0ca9db78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 7 deletions

View File

@ -692,7 +692,7 @@ pub mod layout {
Ok(flags & ShredFlags::SHRED_TICK_REFERENCE_MASK.bits())
}
pub(crate) fn get_merkle_root(shred: &[u8]) -> Option<Hash> {
pub fn get_merkle_root(shred: &[u8]) -> Option<Hash> {
match get_shred_variant(shred).ok()? {
ShredVariant::LegacyCode | ShredVariant::LegacyData => None,
ShredVariant::MerkleCode(proof_size, chained) => {

View File

@ -66,6 +66,8 @@ pub enum Error {
Blockstore(#[from] solana_ledger::blockstore::BlockstoreError),
#[error(transparent)]
ClusterInfo(#[from] solana_gossip::cluster_info::ClusterInfoError),
#[error("Invalid Merkle root, slot: {slot}, index: {index}")]
InvalidMerkleRoot { slot: Slot, index: u64 },
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
@ -76,8 +78,14 @@ pub enum Error {
Send,
#[error(transparent)]
Serialize(#[from] std::boxed::Box<bincode::ErrorKind>),
#[error("Shred not found, slot: {slot}, index: {index}")]
ShredNotFound { slot: Slot, index: u64 },
#[error(transparent)]
TransportError(#[from] solana_sdk::transport::TransportError),
#[error("Unknown last index, slot: {0}")]
UnknownLastIndex(Slot),
#[error("Unknown slot meta, slot: {0}")]
UnknownSlotMeta(Slot),
}
type Result<T> = std::result::Result<T, Error>;

View File

@ -1,7 +1,7 @@
use {
super::*,
solana_entry::entry::Entry,
solana_ledger::shred::{ProcessShredsStats, ReedSolomonCache, Shredder},
solana_ledger::shred::{self, ProcessShredsStats, ReedSolomonCache, Shredder},
solana_sdk::{hash::Hash, signature::Keypair},
};
@ -45,6 +45,21 @@ impl BroadcastRun for BroadcastFakeShredsRun {
.expect("Database error")
.map(|meta| meta.consumed)
.unwrap_or(0) as u32;
let chained_merkle_root = match next_shred_index.checked_sub(1) {
None => broadcast_utils::get_chained_merkle_root_from_parent(
bank.slot(),
bank.parent_slot(),
blockstore,
)
.unwrap(),
Some(index) => {
let shred = blockstore
.get_data_shred(bank.slot(), u64::from(index))
.unwrap()
.unwrap();
shred::layout::get_merkle_root(&shred).unwrap()
}
};
let num_entries = receive_results.entries.len();
@ -60,7 +75,7 @@ impl BroadcastRun for BroadcastFakeShredsRun {
keypair,
&receive_results.entries,
last_tick_height == bank.max_tick_height(),
None, // chained_merkle_root
Some(chained_merkle_root),
next_shred_index,
self.next_code_index,
true, // merkle_variant
@ -82,7 +97,7 @@ impl BroadcastRun for BroadcastFakeShredsRun {
keypair,
&fake_entries,
last_tick_height == bank.max_tick_height(),
None, // chained_merkle_root
Some(chained_merkle_root),
next_shred_index,
self.next_code_index,
true, // merkle_variant

View File

@ -1,12 +1,15 @@
use {
super::Result,
super::{Error, Result},
bincode::serialized_size,
crossbeam_channel::Receiver,
solana_entry::entry::Entry,
solana_ledger::shred::ShredData,
solana_ledger::{
blockstore::Blockstore,
shred::{self, ShredData},
},
solana_poh::poh_recorder::WorkingBankEntry,
solana_runtime::bank::Bank,
solana_sdk::clock::Slot,
solana_sdk::{clock::Slot, hash::Hash},
std::{
sync::Arc,
time::{Duration, Instant},
@ -96,6 +99,34 @@ pub(super) fn recv_slot_entries(receiver: &Receiver<WorkingBankEntry>) -> Result
})
}
// Returns the Merkle root of the last erasure batch of the parent slot.
pub(super) fn get_chained_merkle_root_from_parent(
slot: Slot,
parent: Slot,
blockstore: &Blockstore,
) -> Result<Hash> {
if slot == parent {
debug_assert_eq!(slot, 0u64);
return Ok(Hash::default());
}
debug_assert!(parent < slot, "parent: {parent} >= slot: {slot}");
let index = blockstore
.meta(parent)?
.ok_or_else(|| Error::UnknownSlotMeta(parent))?
.last_index
.ok_or_else(|| Error::UnknownLastIndex(parent))?;
let shred = blockstore
.get_data_shred(parent, index)?
.ok_or(Error::ShredNotFound {
slot: parent,
index,
})?;
shred::layout::get_merkle_root(&shred).ok_or(Error::InvalidMerkleRoot {
slot: parent,
index,
})
}
#[cfg(test)]
mod tests {
use {