Skip to content

v7.0.0-beta.2 (Holesky Rescue) #7041

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

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
bbc1200
Add flag to disable attestation APIs
michaelsproul Feb 25, 2025
d472689
Fix flag
michaelsproul Feb 25, 2025
11f17e5
Disable liveness risk
michaelsproul Feb 25, 2025
1b9b61b
lcli http-sync hacks
michaelsproul Feb 25, 2025
d4586ea
Remove more liveness risks
michaelsproul Feb 25, 2025
ff2376e
Implement invalidation API
michaelsproul Feb 25, 2025
19fc31a
Allow invalidation of "valid" nodes
michaelsproul Feb 25, 2025
2883429
MORE
michaelsproul Feb 25, 2025
c61cf26
Blacklist invalid block root in block verification and blacklist inva…
jimmygchen Feb 25, 2025
88c0f9d
Blacklist invalid block root in block verification and blacklist inva…
jimmygchen Feb 25, 2025
df3038d
Add log
jimmygchen Feb 25, 2025
fd1ca8e
Ban peers with banned payloads
michaelsproul Feb 25, 2025
279afb0
Add vc --disable-attesting flag
michaelsproul Feb 25, 2025
0c5580f
Bump sync-tolerance-epoch and make it a cli param
pawanjay176 Feb 25, 2025
627c1ba
take config value
pawanjay176 Feb 25, 2025
e473500
discard unused code
eserilev Feb 25, 2025
dc320e3
Bump version
paulhauner Feb 26, 2025
9f15f31
Optimise status processing for holesky-rescue (#7054)
jimmygchen Feb 27, 2025
8706040
Load block roots from fork choice where possible when serving `Blocks…
jimmygchen Feb 28, 2025
73b7cad
Change state cache size default to 32. (#7055)
jimmygchen Feb 28, 2025
8f43cb9
Manual finalization endpoint (#7059)
eserilev Mar 3, 2025
6399ad4
Reuse milhouse subtrees to shrink inactivity_scores in memory (#7062)
michaelsproul Mar 3, 2025
fcf1e3f
Revert "Reuse milhouse subtrees to shrink inactivity_scores in memory…
michaelsproul Mar 3, 2025
8f62b19
Split block root lookups between fork choice and store on BBR respons…
realbigsean Mar 3, 2025
defdc59
Prevent writing to state cache when migrating the database (#7067)
eserilev Mar 4, 2025
e12719c
Add backtrace logging. (#7063)
jimmygchen Mar 4, 2025
9436f23
Add http endpoint to add trusted peer (#7068)
pawanjay176 Mar 4, 2025
feedf5d
Add CI fixes to `holesky-rescue` (#7071)
jimmygchen Mar 4, 2025
1b58597
Manual compaction endpoint (#7072)
eserilev Mar 4, 2025
9bb0e13
Bump version to v7.0.0-beta.2 (#7073)
jimmygchen Mar 4, 2025
3645d57
Fix descent from split check (#7105)
michaelsproul Mar 11, 2025
8d058e4
Release v7.0.0-beta.3
michaelsproul Mar 12, 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
8 changes: 4 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion beacon_node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "beacon_node"
version = "7.0.0-beta.0"
version = "7.0.0-beta.2"
authors = [
"Paul Hauner <[email protected]>",
"Age Manning <[email protected]",
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/beacon_chain/src/attestation_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.ok_or(BeaconChainError::NoStateForSlot(state_slot))?;

let state = self
.get_state(&state_root, Some(state_slot))?
.get_state(&state_root, Some(state_slot), true)?
.ok_or(BeaconChainError::MissingBeaconState(state_root))?;

if state.fork_name_unchecked().altair_enabled() {
Expand Down
3 changes: 2 additions & 1 deletion beacon_node/beacon_chain/src/attester_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ impl AttesterCache {
Ok(())
}

// TODO(holesky) check this out
/// Read the state identified by `state_root` from the database, advance it to the required
/// slot, use it to prime the cache and return the values for the provided `slot` and
/// `committee_index`.
Expand Down Expand Up @@ -326,7 +327,7 @@ impl AttesterCache {
}

let mut state: BeaconState<T::EthSpec> = chain
.get_state(&state_root, None)?
.get_state(&state_root, None, true)?
.ok_or(Error::MissingBeaconState(state_root))?;

if state.slot() > slot {
Expand Down
90 changes: 79 additions & 11 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use crate::light_client_optimistic_update_verification::{
Error as LightClientOptimisticUpdateError, VerifiedLightClientOptimisticUpdate,
};
use crate::light_client_server_cache::LightClientServerCache;
use crate::migrate::BackgroundMigrator;
use crate::migrate::{BackgroundMigrator, ManualFinalizationNotification};
use crate::naive_aggregation_pool::{
AggregatedAttestationMap, Error as NaiveAggregationError, NaiveAggregationPool,
SyncContributionAggregateMap,
Expand Down Expand Up @@ -118,8 +118,8 @@ use std::sync::Arc;
use std::time::Duration;
use store::iter::{BlockRootsIterator, ParentRootBlockIterator, StateRootsIterator};
use store::{
BlobSidecarListFromRoot, DatabaseBlock, Error as DBError, HotColdDB, KeyValueStore,
KeyValueStoreOp, StoreItem, StoreOp,
BlobSidecarListFromRoot, DatabaseBlock, Error as DBError, HotColdDB, HotStateSummary,
KeyValueStore, KeyValueStoreOp, StoreItem, StoreOp,
};
use task_executor::{ShutdownReason, TaskExecutor};
use tokio::sync::oneshot;
Expand Down Expand Up @@ -821,7 +821,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.get_blinded_block(&block_root)?
.ok_or(Error::MissingBeaconBlock(block_root))?;
let state = self
.get_state(&block.state_root(), Some(block.slot()))?
.get_state(&block.state_root(), Some(block.slot()), true)?
.ok_or_else(|| Error::MissingBeaconState(block.state_root()))?;
let iter = BlockRootsIterator::owned(&self.store, state);
Ok(std::iter::once(Ok((block_root, block.slot())))
Expand Down Expand Up @@ -1348,8 +1348,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
&self,
state_root: &Hash256,
slot: Option<Slot>,
update_cache: bool,
) -> Result<Option<BeaconState<T::EthSpec>>, Error> {
Ok(self.store.get_state(state_root, slot)?)
Ok(self.store.get_state(state_root, slot, update_cache)?)
}

/// Return the sync committee at `slot + 1` from the canonical chain.
Expand Down Expand Up @@ -1524,8 +1525,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
})?
.ok_or(Error::NoStateForSlot(slot))?;

// Since this slot is less than the current head, don't cache the state
Ok(self
.get_state(&state_root, Some(slot))?
.get_state(&state_root, Some(slot), false)?
.ok_or(Error::NoStateForSlot(slot))?)
}
}
Expand Down Expand Up @@ -1707,6 +1709,45 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}
}

pub fn manually_compact_database(&self) {
self.store_migrator.process_manual_compaction();
}

pub fn manually_finalize_state(
&self,
state_root: Hash256,
checkpoint: Checkpoint,
) -> Result<(), Error> {
let HotStateSummary {
slot,
latest_block_root,
..
} = self
.store
.load_hot_state_summary(&state_root)
.map_err(BeaconChainError::DBError)?
.ok_or(BeaconChainError::MissingHotStateSummary(state_root))?;

if slot != checkpoint.epoch.start_slot(T::EthSpec::slots_per_epoch())
|| latest_block_root != *checkpoint.root
{
return Err(BeaconChainError::InvalidCheckpoint {
state_root,
checkpoint,
});
}

let notif = ManualFinalizationNotification {
state_root: state_root.into(),
checkpoint,
head_tracker: self.head_tracker.clone(),
genesis_block_root: self.genesis_block_root,
};

self.store_migrator.process_manual_finalization(notif);
Ok(())
}

/// Returns an aggregated `Attestation`, if any, that has a matching `attestation.data`.
///
/// The attestation will be obtained from `self.naive_aggregation_pool`.
Expand Down Expand Up @@ -4848,7 +4889,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let proposer_index = if let Some(proposer) = cached_proposer {
proposer.index as u64
} else {
if head_epoch + 2 < proposal_epoch {
if 2 + 2 == 5 && head_epoch + 2 < proposal_epoch {
warn!(
self.log,
"Skipping proposer preparation";
Expand Down Expand Up @@ -6089,8 +6130,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
//
// This prevents the routine from running during sync.
let head_slot = cached_head.head_slot();
if head_slot + T::EthSpec::slots_per_epoch() * PREPARE_PROPOSER_HISTORIC_EPOCHS
< current_slot
if 2 + 2 == 5
&& head_slot
+ T::EthSpec::slots_per_epoch() * PREPARE_PROPOSER_HISTORIC_EPOCHS
< current_slot
{
debug!(
chain.log,
Expand Down Expand Up @@ -6906,7 +6949,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

let mut beacon_state = self
.store
.get_state(&beacon_state_root, Some(beacon_block.slot()))?
.get_state(&beacon_state_root, Some(beacon_block.slot()), true)?
.ok_or_else(|| {
Error::DBInconsistent(format!("Missing state {:?}", beacon_state_root))
})?;
Expand Down Expand Up @@ -7059,7 +7102,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
if signed_beacon_block.slot() % T::EthSpec::slots_per_epoch() == 0 {
let block = self.get_blinded_block(&block_hash).unwrap().unwrap();
let state = self
.get_state(&block.state_root(), Some(block.slot()))
.get_state(&block.state_root(), Some(block.slot()), true)
.unwrap()
.unwrap();
finalized_blocks.insert(state.finalized_checkpoint().root);
Expand Down Expand Up @@ -7280,6 +7323,31 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

Ok(None)
}

/// Retrieves block roots (in ascending slot order) within some slot range from fork choice.
pub fn block_roots_from_fork_choice(&self, start_slot: u64, count: u64) -> Vec<Hash256> {
let head_block_root = self.canonical_head.cached_head().head_block_root();
let fork_choice_read_lock = self.canonical_head.fork_choice_read_lock();
let block_roots_iter = fork_choice_read_lock
.proto_array()
.iter_block_roots(&head_block_root);
let end_slot = start_slot.saturating_add(count);
let mut roots = vec![];

for (root, slot) in block_roots_iter {
if slot < end_slot && slot >= start_slot {
roots.push(root);
}
if slot < start_slot {
break;
}
}

drop(fork_choice_read_lock);
// return in ascending slot order
roots.reverse();
roots
}
}

impl<T: BeaconChainTypes> Drop for BeaconChain<T> {
Expand Down
46 changes: 39 additions & 7 deletions beacon_node/beacon_chain/src/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ use std::borrow::Cow;
use std::fmt::Debug;
use std::fs;
use std::io::Write;
use std::str::FromStr;
use std::sync::Arc;
use store::{Error as DBError, HotStateSummary, KeyValueStore, StoreOp};
use strum::AsRefStr;
Expand Down Expand Up @@ -146,7 +147,9 @@ pub enum BlockError {
///
/// It's unclear if this block is valid, but it cannot be processed without already knowing
/// its parent.
ParentUnknown { parent_root: Hash256 },
ParentUnknown {
parent_root: Hash256,
},
/// The block slot is greater than the present slot.
///
/// ## Peer scoring
Expand All @@ -161,7 +164,10 @@ pub enum BlockError {
/// ## Peer scoring
///
/// The peer has incompatible state transition logic and is faulty.
StateRootMismatch { block: Hash256, local: Hash256 },
StateRootMismatch {
block: Hash256,
local: Hash256,
},
/// The block was a genesis block, these blocks cannot be re-imported.
GenesisBlock,
/// The slot is finalized, no need to import.
Expand All @@ -180,7 +186,9 @@ pub enum BlockError {
///
/// It's unclear if this block is valid, but it conflicts with finality and shouldn't be
/// imported.
NotFinalizedDescendant { block_parent_root: Hash256 },
NotFinalizedDescendant {
block_parent_root: Hash256,
},
/// Block is already known and valid, no need to re-import.
///
/// ## Peer scoring
Expand All @@ -207,7 +215,10 @@ pub enum BlockError {
/// ## Peer scoring
///
/// The block is invalid and the peer is faulty.
IncorrectBlockProposer { block: u64, local_shuffling: u64 },
IncorrectBlockProposer {
block: u64,
local_shuffling: u64,
},
/// The `block.proposal_index` is not known.
///
/// ## Peer scoring
Expand All @@ -225,7 +236,10 @@ pub enum BlockError {
/// ## Peer scoring
///
/// The block is invalid and the peer is faulty.
BlockIsNotLaterThanParent { block_slot: Slot, parent_slot: Slot },
BlockIsNotLaterThanParent {
block_slot: Slot,
parent_slot: Slot,
},
/// At least one block in the chain segment did not have it's parent root set to the root of
/// the prior block.
///
Expand Down Expand Up @@ -281,7 +295,10 @@ pub enum BlockError {
/// If it's actually our fault (e.g. our execution node database is corrupt) we have bigger
/// problems to worry about than losing peers, and we're doing the network a favour by
/// disconnecting.
ParentExecutionPayloadInvalid { parent_root: Hash256 },
ParentExecutionPayloadInvalid {
parent_root: Hash256,
},
KnownInvalidExecutionPayload(Hash256),
/// The block is a slashable equivocation from the proposer.
///
/// ## Peer scoring
Expand Down Expand Up @@ -1326,6 +1343,13 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
chain: &Arc<BeaconChain<T>>,
notify_execution_layer: NotifyExecutionLayer,
) -> Result<Self, BlockError> {
if block_root
== Hash256::from_str("2db899881ed8546476d0b92c6aa9110bea9a4cd0dbeb5519eb0ea69575f1f359")
.expect("valid hash")
{
return Err(BlockError::KnownInvalidExecutionPayload(block_root));
}

chain
.observed_slashable
.write()
Expand Down Expand Up @@ -1758,7 +1782,15 @@ pub fn check_block_is_finalized_checkpoint_or_descendant<
fork_choice: &BeaconForkChoice<T>,
block: B,
) -> Result<B, BlockError> {
if fork_choice.is_finalized_checkpoint_or_descendant(block.parent_root()) {
// If we have a split block newer than finalization then we also ban blocks which are not
// descended from that split block.
let split = chain.store.get_split_info();
let is_descendant_from_split_block =
split.slot == 0 || fork_choice.is_descendant(split.block_root, block.parent_root());

if fork_choice.is_finalized_checkpoint_or_descendant(block.parent_root())
&& is_descendant_from_split_block
{
Ok(block)
} else {
// If fork choice does *not* consider the parent to be a descendant of the finalized block,
Expand Down
6 changes: 5 additions & 1 deletion beacon_node/beacon_chain/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,11 @@ where
.map_err(|e| descriptive_db_error("genesis block", &e))?
.ok_or("Genesis block not found in store")?;
let genesis_state = store
.get_state(&genesis_block.state_root(), Some(genesis_block.slot()))
.get_state(
&genesis_block.state_root(),
Some(genesis_block.slot()),
true,
)
.map_err(|e| descriptive_db_error("genesis state", &e))?
.ok_or("Genesis state not found in store")?;

Expand Down
7 changes: 7 additions & 0 deletions beacon_node/beacon_chain/src/canonical_head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.get_full_block(&new_view.head_block_root)?
.ok_or(Error::MissingBeaconBlock(new_view.head_block_root))?;

// TODO(holesky) when we calculate the new snapshot we might be missing a state
let (_, beacon_state) = self
.store
.get_advanced_hot_state(
Expand Down Expand Up @@ -784,6 +785,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.execution_status
.is_optimistic_or_invalid();

// Update the state cache so it doesn't mistakenly prune the new head.
self.store
.state_cache
.lock()
.update_head_block_root(new_cached_head.head_block_root());

// Detect and potentially report any re-orgs.
let reorg_distance = detect_reorg(
&old_snapshot.beacon_state,
Expand Down
4 changes: 4 additions & 0 deletions beacon_node/beacon_chain/src/chain_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ pub struct ChainConfig {
/// The delay in milliseconds applied by the node between sending each blob or data column batch.
/// This doesn't apply if the node is the block proposer.
pub blob_publication_batch_interval: Duration,
pub disable_attesting: bool,
pub sync_tolerance_epochs: u64,
}

impl Default for ChainConfig {
Expand Down Expand Up @@ -129,6 +131,8 @@ impl Default for ChainConfig {
enable_sampling: false,
blob_publication_batches: 4,
blob_publication_batch_interval: Duration::from_millis(300),
disable_attesting: false,
sync_tolerance_epochs: 16,
}
}
}
Expand Down
Loading