Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blockstore: Migrate ShredIndex type to more efficient data structure #3900

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
318a34b
Add ShredIndex benchmarks
cpubot Nov 26, 2024
a33db83
add custom serde for U64ShredIndex
cpubot Dec 3, 2024
46697c1
Add ShredIndex benchmarks
cpubot Nov 26, 2024
55f901e
add ShredIndexNext implementation
cpubot Nov 27, 2024
b52dc75
Add ShredIndexNext support to Blockstore::get_index
cpubot Dec 3, 2024
14507b3
Use custom serde for ShredIndexNext to avoid collisions
cpubot Dec 3, 2024
090d0c0
explicitly use bitwise ops for index / mask
cpubot Dec 6, 2024
9fe2353
&= !mask -> ^= mask
cpubot Dec 6, 2024
99b2dd2
assert index not out of bounds in `remove`
cpubot Dec 6, 2024
90ca29d
Round up `MAX_U64S_PER_SLOT` to accommodate %64!=0
cpubot Dec 6, 2024
12d31dd
Merge branch 'master' into shred-index-next
cpubot Dec 6, 2024
2c6a43e
Add comment about migration strategy
cpubot Dec 6, 2024
cac0912
IndexNext -> IndexV2
cpubot Dec 6, 2024
2a662d9
forward compatibility for increases in MAX_DATA_SHREDS_PER_SLOT
cpubot Dec 6, 2024
5da104c
use serialize_tuple to avoid recounting set bits
cpubot Dec 9, 2024
e416a70
remove "next" terminology
cpubot Dec 9, 2024
01bdfbb
address naming and alias nits
cpubot Dec 9, 2024
28a34db
add remove tests
cpubot Dec 9, 2024
a510eed
add `#[cfg(test)]` to `.remove` for clarity
cpubot Dec 9, 2024
c8cc254
next -> v2
cpubot Dec 9, 2024
b598fc2
Merge branch 'master' into shred-index-next
cpubot Dec 9, 2024
4fd710a
fix dangling reference to ShredIndexLegacy
cpubot Dec 10, 2024
a69f830
make ser/de portable with explicit LE conversion
cpubot Dec 10, 2024
e27c8d6
Merge branch 'master' into shred-index-next
cpubot Dec 11, 2024
345ee42
add exhaustive ShredIndexV2 range bound tests
cpubot Dec 11, 2024
7cf0c89
add note about `ShredIndex` & `ShredIndex2` ser/de
cpubot Dec 11, 2024
19a0dd3
improve readability of index version compatibility note
cpubot Dec 13, 2024
96bd583
decouple NUM_U64_PER_SHRED_INDEX_V2 from MAX_DATA_SHREDS_PER_SLOT
cpubot Dec 14, 2024
b22c49c
fix missing usage of `get_index` abstraction
cpubot Dec 16, 2024
336dbdb
add deserialize method to TypedColumn
cpubot Dec 20, 2024
e710dbf
Merge branch 'master' into shred-index-next
cpubot Dec 29, 2024
f9e4986
use simpler Vec<u8> implementation
cpubot Jan 7, 2025
caca0a0
Merge branch 'master' into shred-index-next
cpubot Jan 7, 2025
b545d79
update lock files
cpubot Jan 7, 2025
d1a816c
reject trailing bytes on serialize
cpubot Jan 7, 2025
069fb5d
remove unused import
cpubot Jan 7, 2025
32a5457
remove old comment
cpubot Jan 7, 2025
214d1b3
clippy
cpubot Jan 7, 2025
9d4cf1b
update outdated comment
cpubot Jan 7, 2025
bc9da48
Add padding to IndexV2 to prevent collisions
cpubot Jan 7, 2025
e676815
Merge branch 'master' into shred-index-next
cpubot Jan 7, 2025
28115a3
use bincode fixint encoding
cpubot Jan 9, 2025
5edeb17
re-introduce TypedColumn::serialize
cpubot Jan 9, 2025
c276d5b
add proptest regression file
cpubot Jan 9, 2025
77b0963
clean up ShredIndexV2 constants
cpubot Jan 9, 2025
02f8abc
use u8 bounds ShredIndexV2 boundary conditions test
cpubot Jan 10, 2025
c6d6b80
improve runtime of proptests
cpubot Jan 10, 2025
c7f7529
Merge branch 'master' into shred-index-next
cpubot Jan 10, 2025
674d6e7
Document (de)serialization failures between index types
cpubot Jan 11, 2025
adb13d6
Merge branch 'master' into shred-index-next
cpubot Jan 11, 2025
c222ef2
propagate Cargo.lock changes
cpubot Jan 11, 2025
0b6928e
Revert "fix missing usage of `get_index` abstraction"
cpubot Jan 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ledger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ lru = { workspace = true }
mockall = { workspace = true }
num_cpus = { workspace = true }
num_enum = { workspace = true }
proptest = { workspace = true }
prost = { workspace = true }
qualifier_attr = { workspace = true }
rand = { workspace = true }
Expand Down
3 changes: 1 addition & 2 deletions ledger/src/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4708,8 +4708,7 @@ impl Blockstore {
let mut total_start = Measure::start("Total elapsed");
let res = index_working_set.entry(slot).or_insert_with(|| {
let newly_inserted_meta = self
.index_cf
.get(slot)
.get_index(slot)
.unwrap()
.unwrap_or_else(|| Index::new(slot));
IndexMetaWorkingSetEntry {
Expand Down
46 changes: 38 additions & 8 deletions ledger/src/blockstore_db.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
pub use rocksdb::Direction as IteratorDirection;
use {
crate::{
blockstore_meta,
blockstore_meta::MerkleRootMeta,
blockstore_meta::{self, MerkleRootMeta},
blockstore_metrics::{
maybe_enable_rocksdb_perf, report_rocksdb_read_perf, report_rocksdb_write_perf,
BlockstoreRocksDbColumnFamilyMetrics, PerfSamplingStatus, PERF_METRIC_OP_NAME_GET,
Expand All @@ -11,7 +10,7 @@ use {
},
blockstore_options::{AccessType, BlockstoreOptions, LedgerColumnOptions},
},
bincode::{deserialize, serialize},
bincode::{deserialize, Options as BincodeOptions},
byteorder::{BigEndian, ByteOrder},
log::*,
prost::Message,
Expand Down Expand Up @@ -796,6 +795,14 @@ pub trait ColumnName {

pub trait TypedColumn: Column {
type Type: Serialize + DeserializeOwned;

fn deserialize(data: &[u8]) -> Result<Self::Type> {
Ok(bincode::deserialize(data)?)
}

fn serialize(data: &Self::Type) -> Result<Vec<u8>> {
Ok(bincode::serialize(data)?)
}
}

impl TypedColumn for columns::AddressSignatures {
Expand Down Expand Up @@ -1210,6 +1217,29 @@ impl ColumnName for columns::Index {
}
impl TypedColumn for columns::Index {
type Type = blockstore_meta::Index;

fn deserialize(data: &[u8]) -> Result<Self::Type> {
let config = bincode::DefaultOptions::new().reject_trailing_bytes();
// Migration strategy for new column format:
// 1. Release 1: Add ability to read new format as fallback, keep writing old format
// 2. Release 2: Switch to writing new format, keep reading old format as fallback
// 3. Release 3: Remove old format support once stable
// This allows safe downgrade to Release 1 since it can read both formats
// https://github.com/anza-xyz/agave/issues/3570
let index: bincode::Result<blockstore_meta::Index> = config.deserialize(data);
cpubot marked this conversation as resolved.
Show resolved Hide resolved
match index {
Ok(index) => Ok(index),
Err(_) => {
let index: blockstore_meta::IndexV2 = config.deserialize(data)?;
Ok(index.into())
}
}
}

fn serialize(data: &Self::Type) -> Result<Vec<u8>> {
let config = bincode::DefaultOptions::new().reject_trailing_bytes();
Ok(config.serialize(data)?)
}
cpubot marked this conversation as resolved.
Show resolved Hide resolved
}

impl SlotColumn for columns::DeadSlots {}
Expand Down Expand Up @@ -1662,7 +1692,7 @@ where
let result = self
.backend
.multi_get_cf(self.handle(), keys)
.map(|out| Ok(out?.as_deref().map(deserialize).transpose()?));
.map(|out| out?.as_deref().map(C::deserialize).transpose());

if let Some(op_start_instant) = is_perf_enabled {
// use multi-get instead
Expand All @@ -1689,7 +1719,7 @@ where
&self.read_perf_status,
);
if let Some(pinnable_slice) = self.backend.get_pinned_cf(self.handle(), key)? {
let value = deserialize(pinnable_slice.as_ref())?;
let value = C::deserialize(pinnable_slice.as_ref())?;
result = Ok(Some(value))
}

Expand All @@ -1709,7 +1739,7 @@ where
self.column_options.rocks_perf_sample_interval,
&self.write_perf_status,
);
let serialized_value = serialize(value)?;
let serialized_value = C::serialize(value)?;

let key = Self::key_from_index(index);
let result = self.backend.put_cf(self.handle(), &key, &serialized_value);
Expand All @@ -1732,7 +1762,7 @@ where
value: &C::Type,
) -> Result<()> {
let key = Self::key_from_index(index);
let serialized_value = serialize(value)?;
let serialized_value = C::serialize(value)?;
batch.put_cf(self.handle(), &key, &serialized_value)
}
}
Expand Down Expand Up @@ -2254,7 +2284,7 @@ pub mod tests {
C: ColumnIndexDeprecation + TypedColumn + ColumnName,
{
pub fn put_deprecated(&self, index: C::DeprecatedIndex, value: &C::Type) -> Result<()> {
let serialized_value = serialize(value)?;
let serialized_value = C::serialize(value)?;
self.backend
.put_cf(self.handle(), &C::deprecated_key(index), &serialized_value)
}
Expand Down
Loading
Loading