Skip to content

Commit f343911

Browse files
committed
Return ResourceUnavailable if we are unable to reconstruct execution payloads (#3365)
## Issue Addressed Resolves #3351 ## Proposed Changes Returns a `ResourceUnavailable` rpc error if we are unable to serve full payloads to blocks by root and range requests because the execution layer is not synced. ## Additional Info This PR also changes the penalties such that a `ResourceUnavailable` error is only penalized if it is an outgoing request. If we are syncing and aren't getting full block responses, then we don't have use for the peer. However, this might not be true for the incoming request case. We let the peer decide in this case if we are still useful or if we should be banned. cc @divagant-martian please let me know if i'm missing something here.
1 parent 947ad9f commit f343911

File tree

2 files changed

+58
-9
lines changed
  • beacon_node

2 files changed

+58
-9
lines changed

beacon_node/lighthouse_network/src/peer_manager/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,15 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
481481
// implement a new sync type which tracks these peers and prevents the sync
482482
// algorithms from requesting blocks from them (at least for a set period of
483483
// time, multiple failures would then lead to a ban).
484-
PeerAction::Fatal
484+
485+
match direction {
486+
// If the blocks request was initiated by us, then we have no use of this
487+
// peer and so we ban it.
488+
ConnectionDirection::Outgoing => PeerAction::Fatal,
489+
// If the blocks request was initiated by the peer, then we let the peer decide if
490+
// it wants to continue talking to us, we do not ban the peer.
491+
ConnectionDirection::Incoming => return,
492+
}
485493
}
486494
RPCResponseErrorCode::ServerError => PeerAction::MidToleranceError,
487495
RPCResponseErrorCode::InvalidRequest => PeerAction::LowToleranceError,

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

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ impl<T: BeaconChainTypes> Worker<T> {
135135
executor.spawn(
136136
async move {
137137
let mut send_block_count = 0;
138+
let mut send_response = true;
138139
for root in request.block_roots.iter() {
139140
match self
140141
.chain
@@ -157,6 +158,23 @@ impl<T: BeaconChainTypes> Worker<T> {
157158
"request_root" => ?root
158159
);
159160
}
161+
Err(BeaconChainError::BlockHashMissingFromExecutionLayer(_)) => {
162+
debug!(
163+
self.log,
164+
"Failed to fetch execution payload for blocks by root request";
165+
"block_root" => ?root,
166+
"reason" => "execution layer not synced",
167+
);
168+
// send the stream terminator
169+
self.send_error_response(
170+
peer_id,
171+
RPCResponseErrorCode::ResourceUnavailable,
172+
"Execution layer not synced".into(),
173+
request_id,
174+
);
175+
send_response = false;
176+
break;
177+
}
160178
Err(e) => {
161179
debug!(
162180
self.log,
@@ -173,11 +191,13 @@ impl<T: BeaconChainTypes> Worker<T> {
173191
"Received BlocksByRoot Request";
174192
"peer" => %peer_id,
175193
"requested" => request.block_roots.len(),
176-
"returned" => send_block_count
194+
"returned" => %send_block_count
177195
);
178196

179197
// send stream termination
180-
self.send_response(peer_id, Response::BlocksByRoot(None), request_id);
198+
if send_response {
199+
self.send_response(peer_id, Response::BlocksByRoot(None), request_id);
200+
}
181201
drop(send_on_drop);
182202
},
183203
"load_blocks_by_root_blocks",
@@ -255,6 +275,7 @@ impl<T: BeaconChainTypes> Worker<T> {
255275
executor.spawn(
256276
async move {
257277
let mut blocks_sent = 0;
278+
let mut send_response = true;
258279

259280
for root in block_roots {
260281
match self.chain.get_block(&root).await {
@@ -280,6 +301,23 @@ impl<T: BeaconChainTypes> Worker<T> {
280301
);
281302
break;
282303
}
304+
Err(BeaconChainError::BlockHashMissingFromExecutionLayer(_)) => {
305+
debug!(
306+
self.log,
307+
"Failed to fetch execution payload for blocks by range request";
308+
"block_root" => ?root,
309+
"reason" => "execution layer not synced",
310+
);
311+
// send the stream terminator
312+
self.send_error_response(
313+
peer_id,
314+
RPCResponseErrorCode::ResourceUnavailable,
315+
"Execution layer not synced".into(),
316+
request_id,
317+
);
318+
send_response = false;
319+
break;
320+
}
283321
Err(e) => {
284322
error!(
285323
self.log,
@@ -320,12 +358,15 @@ impl<T: BeaconChainTypes> Worker<T> {
320358
);
321359
}
322360

323-
// send the stream terminator
324-
self.send_network_message(NetworkMessage::SendResponse {
325-
peer_id,
326-
response: Response::BlocksByRange(None),
327-
id: request_id,
328-
});
361+
if send_response {
362+
// send the stream terminator
363+
self.send_network_message(NetworkMessage::SendResponse {
364+
peer_id,
365+
response: Response::BlocksByRange(None),
366+
id: request_id,
367+
});
368+
}
369+
329370
drop(send_on_drop);
330371
},
331372
"load_blocks_by_range_blocks",

0 commit comments

Comments
 (0)