Skip to content

Commit a3669ab

Browse files
committed
Avoid processing redundant RPC blocks (#4179)
## Proposed Changes We already make some attempts to avoid processing RPC blocks when a block from the same proposer is already being processed through gossip. This PR strengthens that guarantee by using the existing cache for `observed_block_producers` to inform whether an RPC block's processing should be delayed.
1 parent b90c0c3 commit a3669ab

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ pub struct BeaconChain<T: BeaconChainTypes> {
352352
/// in recent epochs.
353353
pub(crate) observed_sync_aggregators: RwLock<ObservedSyncAggregators<T::EthSpec>>,
354354
/// Maintains a record of which validators have proposed blocks for each slot.
355-
pub(crate) observed_block_producers: RwLock<ObservedBlockProducers<T::EthSpec>>,
355+
pub observed_block_producers: RwLock<ObservedBlockProducers<T::EthSpec>>,
356356
/// Maintains a record of which validators have submitted voluntary exits.
357357
pub(crate) observed_voluntary_exits: Mutex<ObservedOperations<SignedVoluntaryExit, T::EthSpec>>,
358358
/// Maintains a record of which validators we've seen proposer slashings for.

beacon_node/network/src/beacon_processor/work_reprocessing_queue.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub const QUEUED_ATTESTATION_DELAY: Duration = Duration::from_secs(12);
5656
pub const QUEUED_LIGHT_CLIENT_UPDATE_DELAY: Duration = Duration::from_secs(12);
5757

5858
/// For how long to queue rpc blocks before sending them back for reprocessing.
59-
pub const QUEUED_RPC_BLOCK_DELAY: Duration = Duration::from_secs(3);
59+
pub const QUEUED_RPC_BLOCK_DELAY: Duration = Duration::from_secs(4);
6060

6161
/// Set an arbitrary upper-bound on the number of queued blocks to avoid DoS attacks. The fact that
6262
/// we signature-verify blocks before putting them in the queue *should* protect against this, but
@@ -521,7 +521,7 @@ impl<T: BeaconChainTypes> ReprocessQueue<T> {
521521
return;
522522
}
523523

524-
// Queue the block for 1/4th of a slot
524+
// Queue the block for 1/3rd of a slot
525525
self.rpc_block_delay_queue
526526
.insert(rpc_block, QUEUED_RPC_BLOCK_DELAY);
527527
}

beacon_node/network/src/beacon_processor/worker/sync_methods.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,52 @@ impl<T: BeaconChainTypes> Worker<T> {
8383
return;
8484
}
8585
};
86+
// Check if a block from this proposer is already known. If so, defer processing until later
87+
// to avoid wasting time processing duplicates.
88+
let proposal_already_known = self
89+
.chain
90+
.observed_block_producers
91+
.read()
92+
.proposer_has_been_observed(block.message())
93+
.map_err(|e| {
94+
error!(
95+
self.log,
96+
"Failed to check observed proposers";
97+
"error" => ?e,
98+
"source" => "rpc",
99+
"block_root" => %block_root
100+
);
101+
})
102+
.unwrap_or(true);
103+
if proposal_already_known {
104+
debug!(
105+
self.log,
106+
"Delaying processing of duplicate RPC block";
107+
"block_root" => ?block_root,
108+
"proposer" => block.message().proposer_index(),
109+
"slot" => block.slot()
110+
);
111+
112+
// Send message to work reprocess queue to retry the block
113+
let reprocess_msg = ReprocessQueueMessage::RpcBlock(QueuedRpcBlock {
114+
block_root,
115+
block: block.clone(),
116+
process_type,
117+
seen_timestamp,
118+
should_process: true,
119+
});
120+
121+
if reprocess_tx.try_send(reprocess_msg).is_err() {
122+
error!(
123+
self.log,
124+
"Failed to inform block import";
125+
"source" => "rpc",
126+
"block_root" => %block_root
127+
);
128+
}
129+
return;
130+
}
131+
86132
let slot = block.slot();
87133
let parent_root = block.message().parent_root();
88134
let result = self

0 commit comments

Comments
 (0)