Implement status v2 version (#7590)

N/A


  Implements status v2 as defined in https://github.com/ethereum/consensus-specs/pull/4374/
This commit is contained in:
Pawan Dhananjay
2025-06-12 00:17:06 -07:00
committed by GitHub
parent 5f208bb858
commit 9803d69d80
13 changed files with 208 additions and 78 deletions

View File

@@ -70,14 +70,14 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
let local = self.chain.status_message();
let start_slot = |epoch: Epoch| epoch.start_slot(T::EthSpec::slots_per_epoch());
let irrelevant_reason = if local.fork_digest != remote.fork_digest {
let irrelevant_reason = if local.fork_digest() != remote.fork_digest() {
// The node is on a different network/fork
Some(format!(
"Incompatible forks Ours:{} Theirs:{}",
hex::encode(local.fork_digest),
hex::encode(remote.fork_digest)
hex::encode(local.fork_digest()),
hex::encode(remote.fork_digest())
))
} else if remote.head_slot
} else if *remote.head_slot()
> self
.chain
.slot()
@@ -88,11 +88,11 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
// current slot. This could be because they are using a different genesis time, or that
// their or our system's clock is incorrect.
Some("Different system clocks or genesis time".to_string())
} else if (remote.finalized_epoch == local.finalized_epoch
&& remote.finalized_root == local.finalized_root)
|| remote.finalized_root.is_zero()
|| local.finalized_root.is_zero()
|| remote.finalized_epoch > local.finalized_epoch
} else if (remote.finalized_epoch() == local.finalized_epoch()
&& remote.finalized_root() == local.finalized_root())
|| remote.finalized_root().is_zero()
|| local.finalized_root().is_zero()
|| remote.finalized_epoch() > local.finalized_epoch()
{
// Fast path. Remote finalized checkpoint is either identical, or genesis, or we are at
// genesis, or they are ahead. In all cases, we should allow this peer to connect to us
@@ -100,7 +100,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
None
} else {
// Remote finalized epoch is less than ours.
let remote_finalized_slot = start_slot(remote.finalized_epoch);
let remote_finalized_slot = start_slot(*remote.finalized_epoch());
if remote_finalized_slot < self.chain.store.get_oldest_block_slot() {
// Peer's finalized checkpoint is older than anything in our DB. We are unlikely
// to be able to help them sync.
@@ -112,7 +112,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
if self
.chain
.block_root_at_slot(remote_finalized_slot, WhenSlotSkipped::Prev)
.map(|root_opt| root_opt != Some(remote.finalized_root))
.map(|root_opt| root_opt != Some(*remote.finalized_root()))
.map_err(Box::new)?
{
Some("Different finalized chain".to_string())
@@ -138,10 +138,11 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
}
Ok(None) => {
let info = SyncInfo {
head_slot: status.head_slot,
head_root: status.head_root,
finalized_epoch: status.finalized_epoch,
finalized_root: status.finalized_root,
head_slot: *status.head_slot(),
head_root: *status.head_root(),
finalized_epoch: *status.finalized_epoch(),
finalized_root: *status.finalized_root(),
earliest_available_slot: status.earliest_available_slot().ok().cloned(),
};
self.send_sync_message(SyncMessage::AddPeer(peer_id, info));
}

View File

@@ -1,7 +1,7 @@
use beacon_chain::{BeaconChain, BeaconChainTypes};
use types::{EthSpec, FixedBytesExtended, Hash256};
use lighthouse_network::rpc::StatusMessage;
use lighthouse_network::rpc::{methods::StatusMessageV2, StatusMessage};
/// Trait to produce a `StatusMessage` representing the state of the given `beacon_chain`.
///
/// NOTE: The purpose of this is simply to obtain a `StatusMessage` from the `BeaconChain` without
@@ -29,11 +29,14 @@ pub(crate) fn status_message<T: BeaconChainTypes>(beacon_chain: &BeaconChain<T>)
finalized_checkpoint.root = Hash256::zero();
}
StatusMessage {
let earliest_available_slot = beacon_chain.store.get_anchor_info().oldest_block_slot;
StatusMessage::V2(StatusMessageV2 {
fork_digest,
finalized_root: finalized_checkpoint.root,
finalized_epoch: finalized_checkpoint.epoch,
head_root: cached_head.head_block_root(),
head_slot: cached_head.head_slot(),
}
earliest_available_slot,
})
}

View File

@@ -1243,6 +1243,7 @@ mod tests {
head_root: Hash256::random(),
finalized_epoch,
finalized_root: Hash256::random(),
earliest_available_slot: None,
},
},
);

View File

@@ -398,10 +398,11 @@ impl<T: BeaconChainTypes> SyncManager<T> {
// ensure the beacon chain still exists
let status = self.chain.status_message();
let local = SyncInfo {
head_slot: status.head_slot,
head_root: status.head_root,
finalized_epoch: status.finalized_epoch,
finalized_root: status.finalized_root,
head_slot: *status.head_slot(),
head_root: *status.head_root(),
finalized_epoch: *status.finalized_epoch(),
finalized_root: *status.finalized_root(),
earliest_available_slot: status.earliest_available_slot().ok().cloned(),
};
let sync_type = remote_sync_type(&local, &remote, &self.chain);
@@ -450,10 +451,11 @@ impl<T: BeaconChainTypes> SyncManager<T> {
) {
let status = self.chain.status_message();
let local = SyncInfo {
head_slot: status.head_slot,
head_root: status.head_root,
finalized_epoch: status.finalized_epoch,
finalized_root: status.finalized_root,
head_slot: *status.head_slot(),
head_root: *status.head_root(),
finalized_epoch: *status.finalized_epoch(),
finalized_root: *status.finalized_root(),
earliest_available_slot: status.earliest_available_slot().ok().cloned(),
};
let head_slot = head_slot.unwrap_or_else(|| {
@@ -471,6 +473,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
// Set finalized to same as local to trigger Head sync
finalized_epoch: local.finalized_epoch,
finalized_root: local.finalized_root,
earliest_available_slot: local.earliest_available_slot,
};
for peer_id in peers {

View File

@@ -384,11 +384,12 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
for peer_id in peers {
debug!(
peer = %peer_id,
fork_digest = ?status_message.fork_digest,
finalized_root = ?status_message.finalized_root,
finalized_epoch = ?status_message.finalized_epoch,
head_root = %status_message.head_root,
head_slot = %status_message.head_slot,
fork_digest = ?status_message.fork_digest(),
finalized_root = ?status_message.finalized_root(),
finalized_epoch = ?status_message.finalized_epoch(),
head_root = %status_message.head_root(),
head_slot = %status_message.head_slot(),
earliest_available_slot = ?status_message.earliest_available_slot(),
"Sending Status Request"
);

View File

@@ -411,10 +411,11 @@ where
let status = self.beacon_chain.status_message();
let local = SyncInfo {
head_slot: status.head_slot,
head_root: status.head_root,
finalized_epoch: status.finalized_epoch,
finalized_root: status.finalized_root,
head_slot: *status.head_slot(),
head_root: *status.head_root(),
finalized_epoch: *status.finalized_epoch(),
finalized_root: *status.finalized_root(),
earliest_available_slot: status.earliest_available_slot().ok().cloned(),
};
// update the state of the collection

View File

@@ -11,9 +11,9 @@ use beacon_chain::{block_verification_types::RpcBlock, EngineState, NotifyExecut
use beacon_processor::WorkType;
use lighthouse_network::rpc::methods::{
BlobsByRangeRequest, DataColumnsByRangeRequest, OldBlocksByRangeRequest,
OldBlocksByRangeRequestV2,
OldBlocksByRangeRequestV2, StatusMessageV2,
};
use lighthouse_network::rpc::{RequestType, StatusMessage};
use lighthouse_network::rpc::RequestType;
use lighthouse_network::service::api_types::{
AppRequestId, BlobsByRangeRequestId, BlocksByRangeRequestId, DataColumnsByRangeRequestId,
SyncRequestId,
@@ -98,6 +98,7 @@ impl TestRig {
finalized_root,
head_slot: finalized_epoch.start_slot(E::slots_per_epoch()),
head_root: Hash256::random(),
earliest_available_slot: None,
})
}
@@ -109,22 +110,25 @@ impl TestRig {
finalized_root: Hash256::random(),
head_slot: finalized_epoch.start_slot(E::slots_per_epoch()),
head_root: Hash256::random(),
earliest_available_slot: None,
}
}
fn local_info(&self) -> SyncInfo {
let StatusMessage {
let StatusMessageV2 {
fork_digest: _,
finalized_root,
finalized_epoch,
head_root,
head_slot,
} = self.harness.chain.status_message();
earliest_available_slot,
} = self.harness.chain.status_message().status_v2();
SyncInfo {
head_slot,
head_root,
finalized_epoch,
finalized_root,
earliest_available_slot: Some(earliest_available_slot),
}
}