Skip to content

Commit

Permalink
reworks blockstore Column trait and LedgerColumn struct (#4416)
Browse files Browse the repository at this point in the history
Column::serialize_index assumes that the &mut [u8] buffer is of size
Column::KEY_LEN but there is no type-safety to ensure that:
https://github.com/anza-xyz/agave/blob/c33c0392e/ledger/src/blockstore_db.rs#L779

Column::serialize_index also forces a non-idiomatic usage, e.g:
https://github.com/anza-xyz/agave/blob/c33c0392e/ledger/src/blockstore_db.rs#L1624-L1627
https://github.com/anza-xyz/agave/blob/c33c0392e/ledger/src/blockstore_db.rs#L1636-L1639

Separately, Column::key allocates a vector on heap whereas an array
suffices:
https://github.com/anza-xyz/agave/blob/c33c0392e/ledger/src/blockstore_db.rs#L781

LedgerColumn takes a const K: usize type parameter which duplicates what
Column::KEY_LEN is supposed to do:
https://github.com/anza-xyz/agave/blob/c33c0392e/ledger/src/blockstore_db.rs#L1335

This also results in a very verbose LedgerColumn type specification
which repeats Column::KEY_LEN in the type:
https://github.com/anza-xyz/agave/blob/c33c0392e/ledger/src/blockstore.rs#L239-L260

LedgerColumn also duplicates Column::{key,serialize_index} by
implementing key_from_index:
https://github.com/anza-xyz/agave/blob/c33c0392e/ledger/src/blockstore_db.rs#L1427-L1432

This commit removes:

    const KEY_LEN: usize;
    fn serialize_index(key: &mut [u8], index: Self::Index);

from the definition of Column trait and instead adds:

    type Key: AsRef<[u8]>;

This also allows to remove const K: usize type parameter from the
definition of LedgerColumn, remove LedgerColumn::key_from_index and
avoid heap allocation in Collumn::key.
  • Loading branch information
behzadnouri authored Jan 14, 2025
1 parent 535ea1e commit 8a0c9b4
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 179 deletions.
47 changes: 23 additions & 24 deletions ledger/src/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,28 +236,27 @@ pub struct Blockstore {
ledger_path: PathBuf,
db: Arc<Rocks>,
// Column families
address_signatures_cf: LedgerColumn<cf::AddressSignatures, { cf::AddressSignatures::KEY_LEN }>,
bank_hash_cf: LedgerColumn<cf::BankHash, { cf::BankHash::KEY_LEN }>,
block_height_cf: LedgerColumn<cf::BlockHeight, { cf::BlockHeight::KEY_LEN }>,
blocktime_cf: LedgerColumn<cf::Blocktime, { cf::Blocktime::KEY_LEN }>,
code_shred_cf: LedgerColumn<cf::ShredCode, { cf::ShredCode::KEY_LEN }>,
data_shred_cf: LedgerColumn<cf::ShredData, { cf::ShredData::KEY_LEN }>,
dead_slots_cf: LedgerColumn<cf::DeadSlots, { cf::DeadSlots::KEY_LEN }>,
duplicate_slots_cf: LedgerColumn<cf::DuplicateSlots, { cf::DuplicateSlots::KEY_LEN }>,
erasure_meta_cf: LedgerColumn<cf::ErasureMeta, { cf::ErasureMeta::KEY_LEN }>,
index_cf: LedgerColumn<cf::Index, { cf::Index::KEY_LEN }>,
merkle_root_meta_cf: LedgerColumn<cf::MerkleRootMeta, { cf::MerkleRootMeta::KEY_LEN }>,
meta_cf: LedgerColumn<cf::SlotMeta, { cf::SlotMeta::KEY_LEN }>,
optimistic_slots_cf: LedgerColumn<cf::OptimisticSlots, { cf::OptimisticSlots::KEY_LEN }>,
orphans_cf: LedgerColumn<cf::Orphans, { cf::Orphans::KEY_LEN }>,
perf_samples_cf: LedgerColumn<cf::PerfSamples, { cf::PerfSamples::KEY_LEN }>,
program_costs_cf: LedgerColumn<cf::ProgramCosts, { cf::ProgramCosts::KEY_LEN }>,
rewards_cf: LedgerColumn<cf::Rewards, { cf::Rewards::KEY_LEN }>,
roots_cf: LedgerColumn<cf::Root, { cf::Root::KEY_LEN }>,
transaction_memos_cf: LedgerColumn<cf::TransactionMemos, { cf::TransactionMemos::KEY_LEN }>,
transaction_status_cf: LedgerColumn<cf::TransactionStatus, { cf::TransactionStatus::KEY_LEN }>,
transaction_status_index_cf:
LedgerColumn<cf::TransactionStatusIndex, { cf::TransactionStatusIndex::KEY_LEN }>,
address_signatures_cf: LedgerColumn<cf::AddressSignatures>,
bank_hash_cf: LedgerColumn<cf::BankHash>,
block_height_cf: LedgerColumn<cf::BlockHeight>,
blocktime_cf: LedgerColumn<cf::Blocktime>,
code_shred_cf: LedgerColumn<cf::ShredCode>,
data_shred_cf: LedgerColumn<cf::ShredData>,
dead_slots_cf: LedgerColumn<cf::DeadSlots>,
duplicate_slots_cf: LedgerColumn<cf::DuplicateSlots>,
erasure_meta_cf: LedgerColumn<cf::ErasureMeta>,
index_cf: LedgerColumn<cf::Index>,
merkle_root_meta_cf: LedgerColumn<cf::MerkleRootMeta>,
meta_cf: LedgerColumn<cf::SlotMeta>,
optimistic_slots_cf: LedgerColumn<cf::OptimisticSlots>,
orphans_cf: LedgerColumn<cf::Orphans>,
perf_samples_cf: LedgerColumn<cf::PerfSamples>,
program_costs_cf: LedgerColumn<cf::ProgramCosts>,
rewards_cf: LedgerColumn<cf::Rewards>,
roots_cf: LedgerColumn<cf::Root>,
transaction_memos_cf: LedgerColumn<cf::TransactionMemos>,
transaction_status_cf: LedgerColumn<cf::TransactionStatus>,
transaction_status_index_cf: LedgerColumn<cf::TransactionStatusIndex>,

highest_primary_index_slot: RwLock<Option<Slot>>,
max_root: AtomicU64,
Expand Down Expand Up @@ -2507,7 +2506,7 @@ impl Blockstore {
DEFAULT_TICKS_PER_SECOND * timestamp().saturating_sub(first_timestamp) / 1000;

// Seek to the first shred with index >= start_index
db_iterator.seek(C::key((slot, start_index)));
db_iterator.seek(C::key(&(slot, start_index)));

// The index of the first missing shred in the slot
let mut prev_index = start_index;
Expand Down Expand Up @@ -3022,7 +3021,7 @@ impl Blockstore {
.is_some_and(|highest_slot| highest_slot >= slot)
{
self.transaction_memos_cf
.get_raw(&cf::TransactionMemos::deprecated_key(signature))
.get_raw(cf::TransactionMemos::deprecated_key(signature))
} else {
Ok(memos)
}
Expand Down
7 changes: 6 additions & 1 deletion ledger/src/blockstore/blockstore_purge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,12 @@ pub mod tests {
assert_eq!(status_entry_iterator.next(), None);
}

fn get_index_bounds(blockstore: &Blockstore) -> (Box<[u8]>, Box<[u8]>) {
fn get_index_bounds(
blockstore: &Blockstore,
) -> (
<cf::TransactionStatus as Column>::Key,
<cf::TransactionStatus as Column>::Key,
) {
let (first_index, _value) = blockstore
.transaction_status_cf
.iterator_cf_raw_key(IteratorMode::Start)
Expand Down
Loading

0 comments on commit 8a0c9b4

Please sign in to comment.