Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 835183a

Browse files
steviezAshwinSekar
steviez
andauthored
v1.16: add merkle root meta column to blockstore (backport of #33979) (#34665)
* add merkle root meta column to blockstore (#33979) * add merkle root meta column to blockstore * pr feedback: remove write/reads to column * pr feedback: u64 -> u32 + revert * pr feedback: fec_set_index u32, use Self::Index * pr feedback: key size 16 -> 12 (cherry picked from commit e457c02) # Conflicts: # ledger/src/blockstore.rs * fix conflicts * blockstore: make merkle root Optional in MerkleRootMeta column (#34091) --------- Co-authored-by: Ashwin Sekar <[email protected]>
1 parent 471956c commit 835183a

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

ledger/src/blockstore.rs

+4
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ pub struct Blockstore {
193193
program_costs_cf: LedgerColumn<cf::ProgramCosts>,
194194
bank_hash_cf: LedgerColumn<cf::BankHash>,
195195
optimistic_slots_cf: LedgerColumn<cf::OptimisticSlots>,
196+
merkle_root_meta_cf: LedgerColumn<cf::MerkleRootMeta>,
196197
last_root: RwLock<Slot>,
197198
insert_shreds_lock: Mutex<()>,
198199
new_shreds_signals: Mutex<Vec<Sender<bool>>>,
@@ -301,6 +302,7 @@ impl Blockstore {
301302
let program_costs_cf = db.column();
302303
let bank_hash_cf = db.column();
303304
let optimistic_slots_cf = db.column();
305+
let merkle_root_meta_cf = db.column();
304306

305307
let db = Arc::new(db);
306308

@@ -353,6 +355,7 @@ impl Blockstore {
353355
program_costs_cf,
354356
bank_hash_cf,
355357
optimistic_slots_cf,
358+
merkle_root_meta_cf,
356359
new_shreds_signals: Mutex::default(),
357360
completed_slots_senders: Mutex::default(),
358361
shred_timing_point_sender: None,
@@ -721,6 +724,7 @@ impl Blockstore {
721724
self.program_costs_cf.submit_rocksdb_cf_metrics();
722725
self.bank_hash_cf.submit_rocksdb_cf_metrics();
723726
self.optimistic_slots_cf.submit_rocksdb_cf_metrics();
727+
self.merkle_root_meta_cf.submit_rocksdb_cf_metrics();
724728
}
725729

726730
fn try_shred_recovery(

ledger/src/blockstore/blockstore_purge.rs

+8
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ impl Blockstore {
214214
& self
215215
.db
216216
.delete_range_cf::<cf::OptimisticSlots>(&mut write_batch, from_slot, to_slot)
217+
.is_ok()
218+
& self
219+
.db
220+
.delete_range_cf::<cf::MerkleRootMeta>(&mut write_batch, from_slot, to_slot)
217221
.is_ok();
218222
let mut w_active_transaction_status_index =
219223
self.active_transaction_status_index.write().unwrap();
@@ -337,6 +341,10 @@ impl Blockstore {
337341
.db
338342
.delete_file_in_range_cf::<cf::OptimisticSlots>(from_slot, to_slot)
339343
.is_ok()
344+
& self
345+
.db
346+
.delete_file_in_range_cf::<cf::MerkleRootMeta>(from_slot, to_slot)
347+
.is_ok()
340348
}
341349

342350
/// Purges special columns (using a non-Slot primary-index) exactly, by

ledger/src/blockstore_db.rs

+51
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub use rocksdb::Direction as IteratorDirection;
22
use {
33
crate::{
44
blockstore_meta,
5+
blockstore_meta::MerkleRootMeta,
56
blockstore_metrics::{
67
maybe_enable_rocksdb_perf, report_rocksdb_read_perf, report_rocksdb_write_perf,
78
BlockstoreRocksDbColumnFamilyMetrics, PerfSamplingStatus, PERF_METRIC_OP_NAME_GET,
@@ -102,6 +103,8 @@ const BLOCK_HEIGHT_CF: &str = "block_height";
102103
const PROGRAM_COSTS_CF: &str = "program_costs";
103104
/// Column family for optimistic slots
104105
const OPTIMISTIC_SLOTS_CF: &str = "optimistic_slots";
106+
/// Column family for merkle roots
107+
const MERKLE_ROOT_META_CF: &str = "merkle_root_meta";
105108

106109
#[derive(Error, Debug)]
107110
pub enum BlockstoreError {
@@ -322,6 +325,19 @@ pub mod columns {
322325
/// * value type: [`blockstore_meta::OptimisticSlotMetaVersioned`]
323326
pub struct OptimisticSlots;
324327

328+
#[derive(Debug)]
329+
/// The merkle root meta column
330+
///
331+
/// Each merkle shred is part of a merkle tree for
332+
/// its FEC set. This column stores that merkle root and associated
333+
/// meta information about the first shred received.
334+
///
335+
/// Its index type is (Slot, fec_set_index).
336+
///
337+
/// * index type: `crate::shred::ErasureSetId` `(Slot, fec_set_index: u32)`
338+
/// * value type: [`blockstore_meta::MerkleRootMeta`]`
339+
pub struct MerkleRootMeta;
340+
325341
// When adding a new column ...
326342
// - Add struct below and implement `Column` and `ColumnName` traits
327343
// - Add descriptor in Rocks::cf_descriptors() and name in Rocks::columns()
@@ -446,6 +462,7 @@ impl Rocks {
446462
new_cf_descriptor::<BlockHeight>(options, oldest_slot),
447463
new_cf_descriptor::<ProgramCosts>(options, oldest_slot),
448464
new_cf_descriptor::<OptimisticSlots>(options, oldest_slot),
465+
new_cf_descriptor::<MerkleRootMeta>(options, oldest_slot),
449466
]
450467
}
451468

@@ -473,6 +490,7 @@ impl Rocks {
473490
BlockHeight::NAME,
474491
ProgramCosts::NAME,
475492
OptimisticSlots::NAME,
493+
MerkleRootMeta::NAME,
476494
]
477495
}
478496

@@ -1072,6 +1090,39 @@ impl TypedColumn for columns::OptimisticSlots {
10721090
type Type = blockstore_meta::OptimisticSlotMetaVersioned;
10731091
}
10741092

1093+
impl Column for columns::MerkleRootMeta {
1094+
type Index = (Slot, /*fec_set_index:*/ u32);
1095+
1096+
fn index(key: &[u8]) -> Self::Index {
1097+
let slot = BigEndian::read_u64(&key[..8]);
1098+
let fec_set_index = BigEndian::read_u32(&key[8..]);
1099+
1100+
(slot, fec_set_index)
1101+
}
1102+
1103+
fn key((slot, fec_set_index): Self::Index) -> Vec<u8> {
1104+
let mut key = vec![0; 12];
1105+
BigEndian::write_u64(&mut key[..8], slot);
1106+
BigEndian::write_u32(&mut key[8..], fec_set_index);
1107+
key
1108+
}
1109+
1110+
fn primary_index((slot, _fec_set_index): Self::Index) -> Slot {
1111+
slot
1112+
}
1113+
1114+
fn as_index(slot: Slot) -> Self::Index {
1115+
(slot, 0)
1116+
}
1117+
}
1118+
1119+
impl ColumnName for columns::MerkleRootMeta {
1120+
const NAME: &'static str = MERKLE_ROOT_META_CF;
1121+
}
1122+
impl TypedColumn for columns::MerkleRootMeta {
1123+
type Type = MerkleRootMeta;
1124+
}
1125+
10751126
#[derive(Debug)]
10761127
pub struct Database {
10771128
backend: Arc<Rocks>,

ledger/src/blockstore_meta.rs

+10
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ pub(crate) struct ErasureConfig {
138138
num_coding: usize,
139139
}
140140

141+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
142+
pub struct MerkleRootMeta {
143+
/// The merkle root, `None` for legacy shreds
144+
merkle_root: Option<Hash>,
145+
/// The first received shred index
146+
first_received_shred_index: u32,
147+
/// The shred type of the first received shred
148+
first_received_shred_type: ShredType,
149+
}
150+
141151
#[derive(Deserialize, Serialize)]
142152
pub struct DuplicateSlotProof {
143153
#[serde(with = "serde_bytes")]

0 commit comments

Comments
 (0)