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

Hierarchical state diffs #5978

Merged
merged 71 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
ec974b8
Start extracting freezer changes for tree-states
michaelsproul Jun 21, 2024
df5e716
Remove unused config args
dapplion Jun 21, 2024
17ce7d0
Add comments
dapplion Jun 21, 2024
3c5d722
Remove unwraps
dapplion Jun 21, 2024
31bcd84
Subjective more clear implementation
dapplion Jun 21, 2024
394abba
Clean up hdiff
michaelsproul Jul 2, 2024
cac7672
Update xdelta3
michaelsproul Jul 4, 2024
b87c6bb
Tree states archive metrics (#6040)
dapplion Jul 4, 2024
e578f5d
Port and clean up forwards iterator changes
michaelsproul Jul 5, 2024
bdcc818
Add and polish hierarchy-config flag
michaelsproul Jul 5, 2024
1501ba5
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Jul 5, 2024
aba6b8b
Cleaner errors
michaelsproul Jul 5, 2024
420e524
Fix beacon_chain test compilation
michaelsproul Jul 5, 2024
3bec78b
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Jul 9, 2024
0500e64
Patch a few more freezer block roots
michaelsproul Jul 9, 2024
2715f60
Fix genesis block root bug
michaelsproul Jul 11, 2024
fa1a941
Fix test failing due to pending updates
michaelsproul Jul 12, 2024
ee032df
Beacon chain tests passing
michaelsproul Jul 16, 2024
8b7b362
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Jul 16, 2024
3f87cd8
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Jul 29, 2024
d2049ca
Fix doc lint
michaelsproul Jul 29, 2024
57b73df
Implement DB schema upgrade for hierarchical state diffs (#6193)
dapplion Aug 19, 2024
71738b8
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Aug 19, 2024
17985a6
Fix test compilation
michaelsproul Aug 19, 2024
b2f785a
Update schema downgrade test
michaelsproul Aug 19, 2024
7789725
Fix tests
michaelsproul Aug 19, 2024
a4582c5
Fix null anchor migration
michaelsproul Aug 26, 2024
c8cea79
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Sep 2, 2024
47afa49
Fix tree states upgrade migration (#6328)
michaelsproul Sep 3, 2024
1e6b2d6
Clean hdiff CLI flag and metrics
michaelsproul Sep 5, 2024
45a0762
Fix "staged reconstruction"
michaelsproul Sep 9, 2024
ca7a7d7
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Sep 9, 2024
e00f639
Fix alloy issues
michaelsproul Sep 9, 2024
907a7c0
Fix staged reconstruction logic
michaelsproul Sep 9, 2024
024843e
Prevent weird slot drift
michaelsproul Sep 9, 2024
bdf04c8
Remove "allow" flag
michaelsproul Sep 9, 2024
2d9ce8f
Update CLI help
michaelsproul Sep 9, 2024
9de88fd
Remove FIXME about downgrade
michaelsproul Sep 9, 2024
05f93dd
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Sep 11, 2024
8a50f2a
Remove some unnecessary error variants
michaelsproul Sep 11, 2024
bcbf9b8
Fix new test
michaelsproul Sep 11, 2024
cf75901
Tree states archive - review comments and metrics (#6386)
dapplion Sep 16, 2024
dbd52f3
Update beacon_node/store/src/hot_cold_store.rs
michaelsproul Sep 16, 2024
5d3a83d
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Sep 16, 2024
3d90ac6
Clarify comment and remove anchor_slot garbage
michaelsproul Sep 16, 2024
1890278
Simplify database anchor (#6397)
michaelsproul Sep 19, 2024
f6118d2
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Sep 19, 2024
5d69f9c
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Sep 24, 2024
b66aa9a
More metrics
michaelsproul Sep 27, 2024
a33130a
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Oct 8, 2024
ab9c275
New historic state cache (#6475)
michaelsproul Oct 16, 2024
e87a618
Update database docs
michaelsproul Oct 18, 2024
62ee6af
Update diagram
michaelsproul Oct 21, 2024
f36f49b
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Oct 21, 2024
9405faa
Update lockbud to work with bindgen/etc
michaelsproul Oct 21, 2024
a69ce78
Correct pkg name for Debian
michaelsproul Oct 21, 2024
237de37
Remove vestigial epochs_per_state_diff
michaelsproul Oct 28, 2024
ddf7f9c
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Oct 28, 2024
5b43b99
Markdown lint
michaelsproul Oct 28, 2024
d4f23e0
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Oct 29, 2024
c4d6ef3
Address Jimmy's review comments
michaelsproul Oct 31, 2024
f6412f3
Simplify ReplayFrom case
michaelsproul Oct 31, 2024
6c32733
Fix and document genesis_state_root
michaelsproul Oct 31, 2024
f8a80dc
Typo
michaelsproul Oct 31, 2024
f5b42e2
Merge branch 'unstable' into tree-states-archive
jimmygchen Oct 31, 2024
b14a924
Compute diff of validators list manually (#6556)
dapplion Nov 14, 2024
dc2b665
Test hdiff binary format stability (#6585)
michaelsproul Nov 16, 2024
fa79803
Merge remote-tracking branch 'origin/unstable' into tree-states-archive
michaelsproul Nov 18, 2024
6b6f796
Add deprecation warning for SPRP
michaelsproul Nov 18, 2024
9b4b069
Update xdelta to get rid of duplicate deps
michaelsproul Nov 18, 2024
b0a5bbe
Document test
michaelsproul Nov 18, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install dependencies
run: apt update && apt install -y cmake
- name: Generate code coverage
run: apt update && apt install -y cmake libclang-dev
- name: Check for deadlocks
run: |
cargo lockbud -k deadlock -b -l tokio_util

Expand Down
78 changes: 76 additions & 2 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ validator_http_metrics = { path = "validator_client/http_metrics" }
validator_metrics = { path = "validator_client/validator_metrics" }
validator_store= { path = "validator_client/validator_store" }
warp_utils = { path = "common/warp_utils" }
xdelta3 = { git = "http://github.com/sigp/xdelta3-rs", rev = "50d63cdf1878e5cf3538e9aae5eed34a22c64e4a" }
zstd = "0.13"

[profile.maxperf]
inherits = "release"
Expand Down
24 changes: 10 additions & 14 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
start_slot,
local_head.beacon_state.clone(),
local_head.beacon_block_root,
&self.spec,
)?;

Ok(iter.map(|result| result.map_err(Into::into)))
Expand All @@ -790,12 +789,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}

self.with_head(move |head| {
let iter = self.store.forwards_block_roots_iterator_until(
start_slot,
end_slot,
|| Ok((head.beacon_state.clone(), head.beacon_block_root)),
&self.spec,
)?;
let iter =
self.store
.forwards_block_roots_iterator_until(start_slot, end_slot, || {
Ok((head.beacon_state.clone(), head.beacon_block_root))
})?;
Ok(iter
.map(|result| result.map_err(Into::into))
.take_while(move |result| {
Expand Down Expand Up @@ -865,7 +863,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
start_slot,
local_head.beacon_state_root(),
local_head.beacon_state.clone(),
&self.spec,
)?;

Ok(iter.map(|result| result.map_err(Into::into)))
Expand All @@ -882,12 +879,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
end_slot: Slot,
) -> Result<impl Iterator<Item = Result<(Hash256, Slot), Error>> + '_, Error> {
self.with_head(move |head| {
let iter = self.store.forwards_state_roots_iterator_until(
start_slot,
end_slot,
|| Ok((head.beacon_state.clone(), head.beacon_state_root())),
&self.spec,
)?;
let iter =
self.store
.forwards_state_roots_iterator_until(start_slot, end_slot, || {
Ok((head.beacon_state.clone(), head.beacon_state_root()))
})?;
Ok(iter
.map(|result| result.map_err(Into::into))
.take_while(move |result| {
Expand Down
19 changes: 0 additions & 19 deletions beacon_node/beacon_chain/src/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,9 +839,6 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {

let block_root = get_block_header_root(block_header);

// Disallow blocks that conflict with the anchor (weak subjectivity checkpoint), if any.
check_block_against_anchor_slot(block.message(), chain)?;

// Do not gossip a block from a finalized slot.
check_block_against_finalized_slot(block.message(), block_root, chain)?;

Expand Down Expand Up @@ -1074,9 +1071,6 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
.fork_name(&chain.spec)
.map_err(BlockError::InconsistentFork)?;

// Check the anchor slot before loading the parent, to avoid spurious lookups.
check_block_against_anchor_slot(block.message(), chain)?;

let (mut parent, block) = load_parent(block, chain)?;

let state = cheap_state_advance_to_obtain_committees::<_, BlockError>(
Expand Down Expand Up @@ -1688,19 +1682,6 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
}
}

/// Returns `Ok(())` if the block's slot is greater than the anchor block's slot (if any).
fn check_block_against_anchor_slot<T: BeaconChainTypes>(
block: BeaconBlockRef<'_, T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<(), BlockError> {
if let Some(anchor_slot) = chain.store.get_anchor_slot() {
if block.slot() <= anchor_slot {
return Err(BlockError::WeakSubjectivityConflict);
}
}
Ok(())
}

/// Returns `Ok(())` if the block is later than the finalized slot on `chain`.
///
/// Returns an error if the block is earlier or equal to the finalized slot, or there was an error
Expand Down
4 changes: 4 additions & 0 deletions beacon_node/beacon_chain/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,10 @@ where
store
.put_block(&beacon_block_root, beacon_block.clone())
.map_err(|e| format!("Failed to store genesis block: {:?}", e))?;
store
.store_frozen_block_root_at_skip_slots(Slot::new(0), Slot::new(1), beacon_block_root)
.and_then(|ops| store.cold_db.do_atomically(ops))
.map_err(|e| format!("Failed to store genesis block root: {e:?}"))?;

// Store the genesis block under the `ZERO_HASH` key.
store
Expand Down
30 changes: 14 additions & 16 deletions beacon_node/beacon_chain/src/historical_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use std::iter;
use std::time::Duration;
use store::metadata::DataColumnInfo;
use store::{
chunked_vector::BlockRoots, AnchorInfo, BlobInfo, ChunkWriter, Error as StoreError,
KeyValueStore,
get_key_for_col, AnchorInfo, BlobInfo, DBColumn, Error as StoreError, KeyValueStore,
KeyValueStoreOp,
};
use strum::IntoStaticStr;
use types::{FixedBytesExtended, Hash256, Slot};
Expand All @@ -35,8 +35,6 @@ pub enum HistoricalBlockError {
InvalidSignature,
/// Transitory error, caller should retry with the same blocks.
ValidatorPubkeyCacheTimeout,
/// No historical sync needed.
NoAnchorInfo,
/// Logic error: should never occur.
IndexOutOfBounds,
/// Internal store error
Expand Down Expand Up @@ -72,10 +70,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
&self,
mut blocks: Vec<AvailableBlock<T::EthSpec>>,
) -> Result<usize, HistoricalBlockError> {
let anchor_info = self
.store
.get_anchor_info()
.ok_or(HistoricalBlockError::NoAnchorInfo)?;
let anchor_info = self.store.get_anchor_info();
let blob_info = self.store.get_blob_info();
let data_column_info = self.store.get_data_column_info();

Expand Down Expand Up @@ -119,8 +114,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

let mut expected_block_root = anchor_info.oldest_block_parent;
let mut prev_block_slot = anchor_info.oldest_block_slot;
let mut chunk_writer =
ChunkWriter::<BlockRoots, _, _>::new(&self.store.cold_db, prev_block_slot.as_usize())?;
let mut new_oldest_blob_slot = blob_info.oldest_blob_slot;
let mut new_oldest_data_column_slot = data_column_info.oldest_data_column_slot;

Expand Down Expand Up @@ -158,8 +151,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}

// Store block roots, including at all skip slots in the freezer DB.
for slot in (block.slot().as_usize()..prev_block_slot.as_usize()).rev() {
chunk_writer.set(slot, block_root, &mut cold_batch)?;
for slot in (block.slot().as_u64()..prev_block_slot.as_u64()).rev() {
cold_batch.push(KeyValueStoreOp::PutKeyValue(
get_key_for_col(DBColumn::BeaconBlockRoots.into(), &slot.to_be_bytes()),
block_root.as_slice().to_vec(),
));
}

prev_block_slot = block.slot();
Expand All @@ -171,15 +167,17 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// completion.
if expected_block_root == self.genesis_block_root {
let genesis_slot = self.spec.genesis_slot;
for slot in genesis_slot.as_usize()..prev_block_slot.as_usize() {
chunk_writer.set(slot, self.genesis_block_root, &mut cold_batch)?;
for slot in genesis_slot.as_u64()..prev_block_slot.as_u64() {
cold_batch.push(KeyValueStoreOp::PutKeyValue(
get_key_for_col(DBColumn::BeaconBlockRoots.into(), &slot.to_be_bytes()),
self.genesis_block_root.as_slice().to_vec(),
));
}
prev_block_slot = genesis_slot;
expected_block_root = Hash256::zero();
break;
}
}
chunk_writer.write(&mut cold_batch)?;
// these were pushed in reverse order so we reverse again
signed_blocks.reverse();

Expand Down Expand Up @@ -271,7 +269,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let backfill_complete = new_anchor.block_backfill_complete(self.genesis_backfill_slot);
anchor_and_blob_batch.push(
self.store
.compare_and_set_anchor_info(Some(anchor_info), Some(new_anchor))?,
.compare_and_set_anchor_info(anchor_info, new_anchor)?,
);
self.store.hot_db.do_atomically(anchor_and_blob_batch)?;

Expand Down
3 changes: 3 additions & 0 deletions beacon_node/beacon_chain/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,7 @@ pub fn scrape_for_metrics<T: BeaconChainTypes>(beacon_chain: &BeaconChain<T>) {
let attestation_stats = beacon_chain.op_pool.attestation_stats();
let chain_metrics = beacon_chain.metrics();

// Kept duplicated for backwards compatibility
set_gauge_by_usize(
&BLOCK_PROCESSING_SNAPSHOT_CACHE_SIZE,
beacon_chain.store.state_cache_len(),
Expand Down Expand Up @@ -2067,6 +2068,8 @@ pub fn scrape_for_metrics<T: BeaconChainTypes>(beacon_chain: &BeaconChain<T>) {
.canonical_head
.fork_choice_read_lock()
.scrape_for_metrics();

beacon_chain.store.register_metrics();
}

/// Scrape the given `state` assuming it's the head state, updating the `DEFAULT_REGISTRY`.
Expand Down
Loading
Loading