mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-17 18:58:23 +00:00
Gloas lookup sync
Rewrites the single block lookup state machine for Gloas, where block, data (blobs/columns), and execution payload envelope are independent components that can arrive and import out of order. - Three additive-only sub-state-machines for block / data / payload streams. Peer sets start empty for data/payload and grow as children arrive — the parent lookup's completion requirement can widen over time without mutating any state machine. - `AwaitingParent` becomes a struct carrying the child's `parent_block_hash` so the parent can be classified empty/full from the child's bid reference. - Wires `PayloadEnvelopesByRoot` RPC end-to-end through `SyncNetworkContext`: request sending, response routing (`SingleLookupReqId::SinglePayloadEnvelope`), and integration into `PayloadRequest`. Envelope *processing* is still a TODO; only the download path is wired. - Test rig: serves envelopes from a `network_envelopes_by_root` cache populated from the external harness; bumps test validator count to 8 so `proposer_lookahead` can populate at the Fulu → Gloas upgrade. - Enables gloas in `TEST_NETWORK_FORKS`. - Fixes: genesis parent check, infinite retry loop on repeated download failure, no-op in `on_completed_request`, and peer sets not being cleared on disconnect.
This commit is contained in:
@@ -43,9 +43,7 @@ use super::range_sync::{EPOCHS_PER_BATCH, RangeSync, RangeSyncType};
|
||||
use crate::network_beacon_processor::{ChainSegmentProcessId, NetworkBeaconProcessor};
|
||||
use crate::service::NetworkMessage;
|
||||
use crate::status::ToStatusMessage;
|
||||
use crate::sync::block_lookups::{
|
||||
BlobRequestState, BlockComponent, BlockRequestState, CustodyRequestState, DownloadResult,
|
||||
};
|
||||
use crate::sync::block_lookups::{BlockComponent, DownloadResult};
|
||||
use crate::sync::custody_backfill_sync::CustodyBackFillSync;
|
||||
use crate::sync::network_context::{PeerGroup, RpcResponseResult};
|
||||
use beacon_chain::block_verification_types::AsBlock;
|
||||
@@ -73,7 +71,8 @@ use strum::IntoStaticStr;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{debug, error, info, trace};
|
||||
use types::{
|
||||
BlobSidecar, DataColumnSidecar, EthSpec, ForkContext, Hash256, SignedBeaconBlock, Slot,
|
||||
BlobSidecar, DataColumnSidecar, EthSpec, ForkContext, Hash256, SignedBeaconBlock,
|
||||
SignedExecutionPayloadEnvelope, Slot,
|
||||
};
|
||||
|
||||
/// The number of slots ahead of us that is allowed before requesting a long-range (batch) Sync
|
||||
@@ -132,6 +131,14 @@ pub enum SyncMessage<E: EthSpec> {
|
||||
seen_timestamp: Duration,
|
||||
},
|
||||
|
||||
/// A payload envelope has been received from the RPC.
|
||||
RpcPayloadEnvelope {
|
||||
sync_request_id: SyncRequestId,
|
||||
peer_id: PeerId,
|
||||
envelope: Option<Arc<SignedExecutionPayloadEnvelope<E>>>,
|
||||
seen_timestamp: Duration,
|
||||
},
|
||||
|
||||
/// A block with an unknown parent has been received.
|
||||
UnknownParentBlock(PeerId, Arc<SignedBeaconBlock<E>>, Hash256),
|
||||
|
||||
@@ -492,6 +499,9 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
SyncRequestId::SingleBlob { id } => {
|
||||
self.on_single_blob_response(id, peer_id, RpcEvent::RPCError(error))
|
||||
}
|
||||
SyncRequestId::SinglePayloadEnvelope { id } => {
|
||||
self.on_single_payload_envelope_response(id, peer_id, RpcEvent::RPCError(error))
|
||||
}
|
||||
SyncRequestId::DataColumnsByRoot(req_id) => {
|
||||
self.on_data_columns_by_root_response(req_id, peer_id, RpcEvent::RPCError(error))
|
||||
}
|
||||
@@ -838,6 +848,17 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
} => {
|
||||
self.rpc_data_column_received(sync_request_id, peer_id, data_column, seen_timestamp)
|
||||
}
|
||||
SyncMessage::RpcPayloadEnvelope {
|
||||
sync_request_id,
|
||||
peer_id,
|
||||
envelope,
|
||||
seen_timestamp,
|
||||
} => self.rpc_payload_envelope_received(
|
||||
sync_request_id,
|
||||
peer_id,
|
||||
envelope,
|
||||
seen_timestamp,
|
||||
),
|
||||
SyncMessage::UnknownParentBlock(peer_id, block, block_root) => {
|
||||
let block_slot = block.slot();
|
||||
let parent_root = block.parent_root();
|
||||
@@ -897,9 +918,33 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
}),
|
||||
);
|
||||
}
|
||||
// TODO(gloas) support gloas data column variant
|
||||
// In Gloas, data columns identify the beacon block root but do not carry
|
||||
// parent root. Treat as an unknown block-root trigger (attestation-style).
|
||||
// The peer is marked as data-capable since it sent us a data column.
|
||||
DataColumnSidecar::Gloas(_) => {
|
||||
error!("Gloas variant not yet supported")
|
||||
match self.should_search_for_block(Some(data_column_slot), &peer_id) {
|
||||
Ok(_) => {
|
||||
if self.block_lookups.search_unknown_block_with_data_peer(
|
||||
block_root,
|
||||
&[peer_id],
|
||||
&mut self.network,
|
||||
) {
|
||||
debug!(
|
||||
?block_root,
|
||||
"Created unknown block lookup from Gloas data column"
|
||||
);
|
||||
} else {
|
||||
debug!(?block_root, "No lookup created from Gloas data column");
|
||||
}
|
||||
}
|
||||
Err(reason) => {
|
||||
debug!(
|
||||
%block_root,
|
||||
reason,
|
||||
"Ignoring Gloas data column unknown block request"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1140,14 +1185,13 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
block: RpcEvent<Arc<SignedBeaconBlock<T::EthSpec>>>,
|
||||
) {
|
||||
if let Some(resp) = self.network.on_single_block_response(id, peer_id, block) {
|
||||
self.block_lookups
|
||||
.on_download_response::<BlockRequestState<T::EthSpec>>(
|
||||
id,
|
||||
resp.map(|(value, seen_timestamp)| {
|
||||
(value, PeerGroup::from_single(peer_id), seen_timestamp)
|
||||
}),
|
||||
&mut self.network,
|
||||
)
|
||||
self.block_lookups.on_block_download_response(
|
||||
id,
|
||||
resp.map(|(value, seen_timestamp)| {
|
||||
(value, PeerGroup::from_single(peer_id), seen_timestamp)
|
||||
}),
|
||||
&mut self.network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1210,14 +1254,53 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
blob: RpcEvent<Arc<BlobSidecar<T::EthSpec>>>,
|
||||
) {
|
||||
if let Some(resp) = self.network.on_single_blob_response(id, peer_id, blob) {
|
||||
self.block_lookups
|
||||
.on_download_response::<BlobRequestState<T::EthSpec>>(
|
||||
self.block_lookups.on_blob_download_response(
|
||||
id,
|
||||
resp.map(|(value, seen_timestamp)| {
|
||||
(value, PeerGroup::from_single(peer_id), seen_timestamp)
|
||||
}),
|
||||
&mut self.network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn rpc_payload_envelope_received(
|
||||
&mut self,
|
||||
sync_request_id: SyncRequestId,
|
||||
peer_id: PeerId,
|
||||
envelope: Option<Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>>,
|
||||
seen_timestamp: Duration,
|
||||
) {
|
||||
match sync_request_id {
|
||||
SyncRequestId::SinglePayloadEnvelope { id } => self
|
||||
.on_single_payload_envelope_response(
|
||||
id,
|
||||
resp.map(|(value, seen_timestamp)| {
|
||||
(value, PeerGroup::from_single(peer_id), seen_timestamp)
|
||||
}),
|
||||
&mut self.network,
|
||||
)
|
||||
peer_id,
|
||||
RpcEvent::from_chunk(envelope, seen_timestamp),
|
||||
),
|
||||
_ => {
|
||||
crit!(%peer_id, "bad request id for payload_envelope");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_single_payload_envelope_response(
|
||||
&mut self,
|
||||
id: SingleLookupReqId,
|
||||
peer_id: PeerId,
|
||||
envelope: RpcEvent<Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>>,
|
||||
) {
|
||||
if let Some(resp) = self
|
||||
.network
|
||||
.on_single_payload_envelope_response(id, peer_id, envelope)
|
||||
{
|
||||
self.block_lookups.on_payload_download_response(
|
||||
id,
|
||||
resp.map(|(value, seen_timestamp)| {
|
||||
(value, PeerGroup::from_single(peer_id), seen_timestamp)
|
||||
}),
|
||||
&mut self.network,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1309,11 +1392,7 @@ impl<T: BeaconChainTypes> SyncManager<T> {
|
||||
response: CustodyByRootResult<T::EthSpec>,
|
||||
) {
|
||||
self.block_lookups
|
||||
.on_download_response::<CustodyRequestState<T::EthSpec>>(
|
||||
requester.0,
|
||||
response,
|
||||
&mut self.network,
|
||||
);
|
||||
.on_custody_download_response(requester.0, response, &mut self.network);
|
||||
}
|
||||
|
||||
/// Handles receiving a response for a range sync request that should have both blocks and
|
||||
|
||||
Reference in New Issue
Block a user