mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-15 19:02:42 +00:00
Remove all batches related to a peer on disconnect (#5969)
* Remove all batches related to a peer on disconnect * Cleanup map entries after disconnect * Allow lookups to continue in case of disconnections * Pretty response types * fmt * Fix lints * Remove lookup if it cannot progress * Fix tests * Remove poll_close on rpc behaviour * Remove redundant test * Fix issue raised by lion * Revert pretty response types * Cleanup * Fix test * Merge remote-tracking branch 'origin/release-v5.2.1' into rpc-error-on-disconnect-revert * Apply suggestions from joao Co-authored-by: João Oliveira <hello@jxs.pt> * Fix log * update request status on no peers found * Do not remove lookup after peer disconnection * Add comments about expected event api * Update single_block_lookup.rs * Update mod.rs * Merge branch 'rpc-error-on-disconnect-revert' into 5969-review * Merge pull request #10 from dapplion/5969-review Add comments about expected event api
This commit is contained in:
@@ -177,6 +177,46 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the ids of all the requests made to the given peer_id.
|
||||
pub fn peer_disconnected(&mut self, peer_id: &PeerId) -> Vec<SyncRequestId> {
|
||||
let failed_range_ids =
|
||||
self.range_blocks_and_blobs_requests
|
||||
.iter()
|
||||
.filter_map(|(id, request)| {
|
||||
if request.1.peer_id == *peer_id {
|
||||
Some(SyncRequestId::RangeBlockAndBlobs { id: *id })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
let failed_block_ids = self
|
||||
.blocks_by_root_requests
|
||||
.iter()
|
||||
.filter_map(|(id, request)| {
|
||||
if request.peer_id == *peer_id {
|
||||
Some(SyncRequestId::SingleBlock { id: *id })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let failed_blob_ids = self
|
||||
.blobs_by_root_requests
|
||||
.iter()
|
||||
.filter_map(|(id, request)| {
|
||||
if request.peer_id == *peer_id {
|
||||
Some(SyncRequestId::SingleBlob { id: *id })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
failed_range_ids
|
||||
.chain(failed_block_ids)
|
||||
.chain(failed_blob_ids)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn network_globals(&self) -> &NetworkGlobals<T::EthSpec> {
|
||||
&self.network_beacon_processor.network_globals
|
||||
}
|
||||
@@ -272,8 +312,13 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
sender_id: RangeRequestId,
|
||||
) -> Result<Id, RpcRequestSendError> {
|
||||
let id = self.blocks_by_range_request(peer_id, batch_type, request)?;
|
||||
self.range_blocks_and_blobs_requests
|
||||
.insert(id, (sender_id, BlocksAndBlobsRequestInfo::new(batch_type)));
|
||||
self.range_blocks_and_blobs_requests.insert(
|
||||
id,
|
||||
(
|
||||
sender_id,
|
||||
BlocksAndBlobsRequestInfo::new(batch_type, peer_id),
|
||||
),
|
||||
);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
@@ -343,7 +388,10 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
// Block is known are currently processing, expect a future event with the result of
|
||||
// processing.
|
||||
BlockProcessStatus::NotValidated { .. } => {
|
||||
return Ok(LookupRequestResult::Pending("block in processing cache"))
|
||||
// Lookup sync event safety: If the block is currently in the processing cache, we
|
||||
// are guaranteed to receive a `SyncMessage::GossipBlockProcessResult` that will
|
||||
// make progress on this lookup
|
||||
return Ok(LookupRequestResult::Pending("block in processing cache"));
|
||||
}
|
||||
// Block is fully validated. If it's not yet imported it's waiting for missing block
|
||||
// components. Consider this request completed and do nothing.
|
||||
@@ -366,6 +414,12 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
|
||||
let request = BlocksByRootSingleRequest(block_root);
|
||||
|
||||
// Lookup sync event safety: If network_send.send() returns Ok(_) we are guaranteed that
|
||||
// eventually at least one this 3 events will be received:
|
||||
// - StreamTermination(request_id): handled by `Self::on_single_block_response`
|
||||
// - RPCError(request_id): handled by `Self::on_single_block_response`
|
||||
// - Disconnect(peer_id) handled by `Self::peer_disconnected``which converts it to a
|
||||
// ` RPCError(request_id)`event handled by the above method
|
||||
self.network_send
|
||||
.send(NetworkMessage::SendRequest {
|
||||
peer_id,
|
||||
@@ -375,7 +429,7 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
.map_err(|_| RpcRequestSendError::NetworkSendError)?;
|
||||
|
||||
self.blocks_by_root_requests
|
||||
.insert(id, ActiveBlocksByRootRequest::new(request));
|
||||
.insert(id, ActiveBlocksByRootRequest::new(request, peer_id));
|
||||
|
||||
Ok(LookupRequestResult::RequestSent(req_id))
|
||||
}
|
||||
@@ -408,6 +462,13 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
// latter handle the case where if the peer sent no blobs, penalize.
|
||||
// - if `downloaded_block_expected_blobs` is Some = block is downloading or processing.
|
||||
// - if `num_expected_blobs` returns Some = block is processed.
|
||||
//
|
||||
// Lookup sync event safety: Reaching this code means that a block is not in any pre-import
|
||||
// cache nor in the request state of this lookup. Therefore, the block must either: (1) not
|
||||
// be downloaded yet or (2) the block is already imported into the fork-choice.
|
||||
// In case (1) the lookup must either successfully download the block or get dropped.
|
||||
// In case (2) the block will be downloaded, processed, reach `BlockIsAlreadyKnown` and
|
||||
// get dropped as completed.
|
||||
return Ok(LookupRequestResult::Pending("waiting for block download"));
|
||||
};
|
||||
|
||||
@@ -444,6 +505,7 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
indices,
|
||||
};
|
||||
|
||||
// Lookup sync event safety: Refer to `Self::block_lookup_request` `network_send.send` call
|
||||
self.network_send
|
||||
.send(NetworkMessage::SendRequest {
|
||||
peer_id,
|
||||
@@ -453,7 +515,7 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
.map_err(|_| RpcRequestSendError::NetworkSendError)?;
|
||||
|
||||
self.blobs_by_root_requests
|
||||
.insert(id, ActiveBlobsByRootRequest::new(request));
|
||||
.insert(id, ActiveBlobsByRootRequest::new(request, peer_id));
|
||||
|
||||
Ok(LookupRequestResult::RequestSent(req_id))
|
||||
}
|
||||
@@ -660,6 +722,8 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
.ok_or(SendErrorProcessor::ProcessorNotAvailable)?;
|
||||
|
||||
debug!(self.log, "Sending block for processing"; "block" => ?block_root, "id" => id);
|
||||
// Lookup sync event safety: If `beacon_processor.send_rpc_beacon_block` returns Ok() sync
|
||||
// must receive a single `SyncMessage::BlockComponentProcessed` with this process type
|
||||
beacon_processor
|
||||
.send_rpc_beacon_block(
|
||||
block_root,
|
||||
@@ -689,6 +753,8 @@ impl<T: BeaconChainTypes> SyncNetworkContext<T> {
|
||||
.ok_or(SendErrorProcessor::ProcessorNotAvailable)?;
|
||||
|
||||
debug!(self.log, "Sending blobs for processing"; "block" => ?block_root, "id" => id);
|
||||
// Lookup sync event safety: If `beacon_processor.send_rpc_blobs` returns Ok() sync
|
||||
// must receive a single `SyncMessage::BlockComponentProcessed` event with this process type
|
||||
beacon_processor
|
||||
.send_rpc_blobs(
|
||||
block_root,
|
||||
|
||||
Reference in New Issue
Block a user