Skip to content

Commit 334aa2e

Browse files
authored
Single lookup improvements (#5488)
* Fix unexpected `UnrequestedBlobId` and `ExtraBlocksReturned` errors due to race conditions. * Continue chain segment processing and skip any blocks that are already known, rather than returning an error. * more de-dup checking * ensure we don't reset `requested_ids` during rpc download * better fix * Merge branch 'unstable' of https://github.com/sigp/lighthouse into more-dup-lookup-fixes * remove chain hash check * Merge branch 'fix-block-lookup-race' of https://github.com/jimmygchen/lighthouse into sean-test-lookups * remove block check * add back tests * Log and CI fixes * undue extra check * Merge branch 'sean-test-lookups' of https://github.com/realbigsean/lighthouse into sean-test-lookups * log improvements * Improve logging
1 parent 250a5bd commit 334aa2e

File tree

9 files changed

+64
-17
lines changed

9 files changed

+64
-17
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,6 +2796,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
27962796
}
27972797
}
27982798
}
2799+
Err(BlockError::BlockIsAlreadyKnown(block_root)) => {
2800+
debug!(self.log,
2801+
"Ignoring already known blocks while processing chain segment";
2802+
"block_root" => ?block_root);
2803+
continue;
2804+
}
27992805
Err(error) => {
28002806
return ChainSegmentResult::Failed {
28012807
imported_blocks,
@@ -3032,7 +3038,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
30323038
match import_block.await {
30333039
// The block was successfully verified and imported. Yay.
30343040
Ok(status @ AvailabilityProcessingStatus::Imported(block_root)) => {
3035-
trace!(
3041+
debug!(
30363042
self.log,
30373043
"Beacon block imported";
30383044
"block_root" => ?block_root,
@@ -3045,7 +3051,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
30453051
Ok(status)
30463052
}
30473053
Ok(status @ AvailabilityProcessingStatus::MissingComponents(slot, block_root)) => {
3048-
trace!(
3054+
debug!(
30493055
self.log,
30503056
"Beacon block awaiting blobs";
30513057
"block_root" => ?block_root,

beacon_node/beacon_chain/src/block_verification_types.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{get_block_root, GossipVerifiedBlock, PayloadVerificationOutcome};
77
use derivative::Derivative;
88
use ssz_types::VariableList;
99
use state_processing::ConsensusContext;
10+
use std::fmt::{Debug, Formatter};
1011
use std::sync::Arc;
1112
use types::blob_sidecar::{BlobIdentifier, BlobSidecarError, FixedBlobSidecarList};
1213
use types::{
@@ -27,13 +28,19 @@ use types::{
2728
/// Note: We make a distinction over blocks received over gossip because
2829
/// in a post-deneb world, the blobs corresponding to a given block that are received
2930
/// over rpc do not contain the proposer signature for dos resistance.
30-
#[derive(Debug, Clone, Derivative)]
31+
#[derive(Clone, Derivative)]
3132
#[derivative(Hash(bound = "E: EthSpec"))]
3233
pub struct RpcBlock<E: EthSpec> {
3334
block_root: Hash256,
3435
block: RpcBlockInner<E>,
3536
}
3637

38+
impl<E: EthSpec> Debug for RpcBlock<E> {
39+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40+
write!(f, "RpcBlock({:?})", self.block_root)
41+
}
42+
}
43+
3744
impl<E: EthSpec> RpcBlock<E> {
3845
pub fn block_root(&self) -> Hash256 {
3946
self.block_root

beacon_node/beacon_chain/src/data_availability_checker.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,6 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
110110
self.processing_cache.read().get(&block_root).cloned()
111111
}
112112

113-
/// A `None` indicates blobs are not required.
114-
///
115113
/// If there's no block, all possible ids will be returned that don't exist in the given blobs.
116114
/// If there no blobs, all possible ids will be returned.
117115
pub fn get_missing_blob_ids<V: AvailabilityView<T::EthSpec>>(

beacon_node/network/src/network_beacon_processor/sync_methods.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
117117
"Gossip block is being processed";
118118
"action" => "sending rpc block to reprocessing queue",
119119
"block_root" => %block_root,
120+
"process_type" => ?process_type,
120121
);
121122

122123
// Send message to work reprocess queue to retry the block
@@ -149,6 +150,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
149150
"proposer" => block.message().proposer_index(),
150151
"slot" => block.slot(),
151152
"commitments" => commitments_formatted,
153+
"process_type" => ?process_type,
152154
);
153155

154156
let result = self
@@ -418,7 +420,11 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
418420
}
419421
}
420422
(imported_blocks, Ok(_)) => {
421-
debug!(self.log, "Parent lookup processed successfully");
423+
debug!(
424+
self.log, "Parent lookup processed successfully";
425+
"chain_hash" => %chain_head,
426+
"imported_blocks" => imported_blocks
427+
);
422428
BatchProcessResult::Success {
423429
was_non_empty: imported_blocks > 0,
424430
}

beacon_node/network/src/sync/block_lookups/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ impl<L: Lookup, T: BeaconChainTypes> RequestState<L, T> for BlobRequestState<L,
380380
let received_id = blob.id();
381381
if !self.requested_ids.contains(&received_id) {
382382
self.state.register_failure_downloading();
383-
Err(LookupVerifyError::UnrequestedBlobId)
383+
Err(LookupVerifyError::UnrequestedBlobId(received_id))
384384
} else {
385385
// State should remain downloading until we receive the stream terminator.
386386
self.requested_ids.remove(&received_id);

beacon_node/network/src/sync/block_lookups/mod.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
152152
if let Some(components) = child_components {
153153
lookup.add_child_components(components);
154154
}
155+
debug!(self.log, "Already searching for block"; "block_root" => ?block_root);
155156
return;
156157
}
157158

@@ -162,6 +163,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
162163

163164
// If the block was already downloaded, or is being downloaded in this moment, do not
164165
// request it.
166+
debug!(self.log, "Already searching for block in a parent lookup request"; "block_root" => ?block_root);
165167
return;
166168
}
167169

@@ -171,6 +173,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
171173
.any(|(hashes, _last_parent_request)| hashes.contains(&block_root))
172174
{
173175
// we are already processing this block, ignore it.
176+
debug!(self.log, "Already processing block in a parent request"; "block_root" => ?block_root);
174177
return;
175178
}
176179

@@ -221,15 +224,23 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
221224
}) {
222225
parent_lookup.add_peer(peer_id);
223226
// we are already searching for this block, ignore it
227+
debug!(self.log, "Already searching for parent block";
228+
"block_root" => ?block_root, "parent_root" => ?parent_root);
224229
return;
225230
}
226231

227232
if self
228233
.processing_parent_lookups
229-
.values()
230-
.any(|(hashes, _peers)| hashes.contains(&block_root) || hashes.contains(&parent_root))
234+
.iter()
235+
.any(|(chain_hash, (hashes, _peers))| {
236+
chain_hash == &block_root
237+
|| hashes.contains(&block_root)
238+
|| hashes.contains(&parent_root)
239+
})
231240
{
232241
// we are already processing this block, ignore it.
242+
debug!(self.log, "Already processing parent block";
243+
"block_root" => ?block_root, "parent_root" => ?parent_root);
233244
return;
234245
}
235246
let parent_lookup = ParentLookup::new(
@@ -298,6 +309,12 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
298309
};
299310

300311
let expected_block_root = lookup.block_root();
312+
debug!(self.log,
313+
"Peer returned block for single lookup";
314+
"peer_id" => %peer_id ,
315+
"id" => ?id,
316+
"block_root" => ?expected_block_root,
317+
);
301318

302319
match self.single_lookup_response_inner::<R>(peer_id, response, seen_timestamp, cx, lookup)
303320
{
@@ -478,6 +495,13 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
478495
return;
479496
};
480497

498+
debug!(self.log,
499+
"Peer returned block for parent lookup";
500+
"peer_id" => %peer_id ,
501+
"id" => ?id,
502+
"block_root" => ?parent_lookup.current_parent_request.block_request_state.requested_block_root,
503+
);
504+
481505
match self.parent_lookup_response_inner::<R>(
482506
peer_id,
483507
response,
@@ -540,7 +564,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
540564
| ParentVerifyError::NoBlockReturned
541565
| ParentVerifyError::NotEnoughBlobsReturned
542566
| ParentVerifyError::ExtraBlocksReturned
543-
| ParentVerifyError::UnrequestedBlobId
567+
| ParentVerifyError::UnrequestedBlobId(_)
544568
| ParentVerifyError::ExtraBlobsReturned
545569
| ParentVerifyError::InvalidIndex(_) => {
546570
let e = e.into();
@@ -728,6 +752,8 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
728752
"Block component processed for lookup";
729753
"response_type" => ?R::response_type(),
730754
"block_root" => ?root,
755+
"result" => ?result,
756+
"id" => target_id,
731757
);
732758

733759
match result {
@@ -901,7 +927,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
901927
debug!(self.log, "Parent block processing succeeded"; &parent_lookup, "block_root" => ?block_root)
902928
}
903929
AvailabilityProcessingStatus::MissingComponents(_, block_root) => {
904-
debug!(self.log, "Parent missing parts, triggering single block lookup "; &parent_lookup,"block_root" => ?block_root)
930+
debug!(self.log, "Parent missing parts, triggering single block lookup"; &parent_lookup,"block_root" => ?block_root)
905931
}
906932
},
907933
BlockProcessingResult::Err(e) => {
@@ -1223,7 +1249,7 @@ impl<T: BeaconChainTypes> BlockLookups<T> {
12231249
) -> Result<(), LookupRequestError> {
12241250
match cx.beacon_processor_if_enabled() {
12251251
Some(beacon_processor) => {
1226-
trace!(self.log, "Sending block for processing"; "block" => ?block_root, "process" => ?process_type);
1252+
debug!(self.log, "Sending block for processing"; "block" => ?block_root, "process" => ?process_type);
12271253
if let Err(e) = beacon_processor.send_rpc_beacon_block(
12281254
block_root,
12291255
block,

beacon_node/network/src/sync/block_lookups/parent_lookup.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::collections::VecDeque;
1212
use std::sync::Arc;
1313
use store::Hash256;
1414
use strum::IntoStaticStr;
15+
use types::blob_sidecar::BlobIdentifier;
1516

1617
/// How many attempts we try to find a parent of a block before we give up trying.
1718
pub(crate) const PARENT_FAIL_TOLERANCE: u8 = 5;
@@ -36,7 +37,7 @@ pub enum ParentVerifyError {
3637
NoBlockReturned,
3738
NotEnoughBlobsReturned,
3839
ExtraBlocksReturned,
39-
UnrequestedBlobId,
40+
UnrequestedBlobId(BlobIdentifier),
4041
ExtraBlobsReturned,
4142
InvalidIndex(u64),
4243
PreviousFailure { parent_root: Hash256 },
@@ -242,7 +243,7 @@ impl From<LookupVerifyError> for ParentVerifyError {
242243
E::RootMismatch => ParentVerifyError::RootMismatch,
243244
E::NoBlockReturned => ParentVerifyError::NoBlockReturned,
244245
E::ExtraBlocksReturned => ParentVerifyError::ExtraBlocksReturned,
245-
E::UnrequestedBlobId => ParentVerifyError::UnrequestedBlobId,
246+
E::UnrequestedBlobId(blob_id) => ParentVerifyError::UnrequestedBlobId(blob_id),
246247
E::ExtraBlobsReturned => ParentVerifyError::ExtraBlobsReturned,
247248
E::InvalidIndex(index) => ParentVerifyError::InvalidIndex(index),
248249
E::NotEnoughBlobsReturned => ParentVerifyError::NotEnoughBlobsReturned,

beacon_node/network/src/sync/block_lookups/single_block_lookup.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::marker::PhantomData;
1616
use std::sync::Arc;
1717
use store::Hash256;
1818
use strum::IntoStaticStr;
19-
use types::blob_sidecar::FixedBlobSidecarList;
19+
use types::blob_sidecar::{BlobIdentifier, FixedBlobSidecarList};
2020
use types::EthSpec;
2121

2222
#[derive(Debug, PartialEq, Eq)]
@@ -31,7 +31,7 @@ pub enum LookupVerifyError {
3131
RootMismatch,
3232
NoBlockReturned,
3333
ExtraBlocksReturned,
34-
UnrequestedBlobId,
34+
UnrequestedBlobId(BlobIdentifier),
3535
ExtraBlobsReturned,
3636
NotEnoughBlobsReturned,
3737
InvalidIndex(u64),
@@ -257,7 +257,9 @@ impl<L: Lookup, T: BeaconChainTypes> SingleBlockLookup<L, T> {
257257
/// of which blobs still need to be requested. Returns `true` if there are no more blobs to
258258
/// request.
259259
pub(crate) fn blobs_already_downloaded(&mut self) -> bool {
260-
self.update_blobs_request();
260+
if matches!(self.blob_request_state.state.state, State::AwaitingDownload) {
261+
self.update_blobs_request();
262+
}
261263
self.blob_request_state.requested_ids.is_empty()
262264
}
263265

beacon_node/network/src/sync/block_lookups/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,6 +1803,7 @@ mod deneb_only {
18031803
.expect_blobs_request()
18041804
.expect_no_block_request();
18051805
}
1806+
18061807
#[test]
18071808
fn too_few_blobs_response_then_block_response_attestation() {
18081809
let Some(tester) = DenebTester::new(RequestTrigger::AttestationUnknownBlock) else {

0 commit comments

Comments
 (0)