mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 05:44:44 +00:00
Unknown block for envelope (#8992)
Add a queue that allows us to reprocess an envelope when it arrives over gossip references a unknown block root. When the block is finally imported, we immediately reprocess the queued envelope. Note that we don't trigger a block lookup sync. Incoming attestations for this block root will already trigger a lookup for us. I think thats good enough Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>
This commit is contained in:
@@ -20,7 +20,9 @@ use beacon_chain::{
|
||||
};
|
||||
use beacon_chain::{
|
||||
blob_verification::{GossipBlobError, GossipVerifiedBlob},
|
||||
payload_envelope_verification::gossip_verified_envelope::GossipVerifiedEnvelope,
|
||||
payload_envelope_verification::{
|
||||
EnvelopeError, gossip_verified_envelope::GossipVerifiedEnvelope,
|
||||
},
|
||||
};
|
||||
use beacon_processor::{Work, WorkEvent};
|
||||
use lighthouse_network::{Client, MessageAcceptance, MessageId, PeerAction, PeerId, ReportSource};
|
||||
@@ -49,8 +51,8 @@ use beacon_processor::work_reprocessing_queue::QueuedColumnReconstruction;
|
||||
use beacon_processor::{
|
||||
DuplicateCache, GossipAggregatePackage, GossipAttestationBatch,
|
||||
work_reprocessing_queue::{
|
||||
QueuedAggregate, QueuedGossipBlock, QueuedLightClientUpdate, QueuedUnaggregate,
|
||||
ReprocessQueueMessage,
|
||||
QueuedAggregate, QueuedGossipBlock, QueuedGossipEnvelope, QueuedLightClientUpdate,
|
||||
QueuedUnaggregate, ReprocessQueueMessage,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3332,6 +3334,61 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
||||
|
||||
verified_envelope
|
||||
}
|
||||
|
||||
Err(EnvelopeError::BlockRootUnknown { block_root }) => {
|
||||
let envelope_slot = envelope.slot();
|
||||
|
||||
debug!(
|
||||
?block_root,
|
||||
%envelope_slot,
|
||||
"Envelope references unknown block, deferring to reprocess queue"
|
||||
);
|
||||
|
||||
self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore);
|
||||
|
||||
let inner_self = self.clone();
|
||||
let chain = self.chain.clone();
|
||||
let process_fn = Box::pin(async move {
|
||||
match chain.verify_envelope_for_gossip(envelope).await {
|
||||
Ok(verified_envelope) => {
|
||||
inner_self
|
||||
.process_gossip_verified_execution_payload_envelope(
|
||||
peer_id,
|
||||
verified_envelope,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Err(e) => {
|
||||
debug!(
|
||||
error = ?e,
|
||||
"Deferred envelope failed verification"
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if self
|
||||
.beacon_processor_send
|
||||
.try_send(WorkEvent {
|
||||
drop_during_sync: false,
|
||||
work: Work::Reprocess(ReprocessQueueMessage::UnknownBlockForEnvelope(
|
||||
QueuedGossipEnvelope {
|
||||
beacon_block_slot: envelope_slot,
|
||||
beacon_block_root: block_root,
|
||||
process_fn,
|
||||
},
|
||||
)),
|
||||
})
|
||||
.is_err()
|
||||
{
|
||||
error!(
|
||||
%envelope_slot,
|
||||
?block_root,
|
||||
"Failed to defer envelope import"
|
||||
);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
// TODO(gloas) penalize peers accordingly
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
@@ -2090,3 +2090,8 @@ async fn test_data_columns_by_range_no_duplicates_with_skip_slots() {
|
||||
unique_roots.len(),
|
||||
);
|
||||
}
|
||||
|
||||
// TODO(ePBS): Add integration tests for envelope deferral (UnknownBlockForEnvelope):
|
||||
// 1. Gossip envelope arrives before its block → queued via UnknownBlockForEnvelope
|
||||
// 2. Block imported → envelope released and processed successfully
|
||||
// 3. Timeout path → envelope released and re-verified
|
||||
|
||||
Reference in New Issue
Block a user