mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-11 18:04:18 +00:00
Report RPC Errors to the application on peer disconnections (#5680)
* Report RPC Errors to the application on peer disconnections Co-authored-by: Age Manning <Age@AgeManning.com> * Expect RPCError::Disconnect to fail ongoing requests * Drop lookups after peer disconnect and not awaiting events * Allow RPCError disconnect through network service * Update beacon_node/lighthouse_network/src/service/mod.rs Co-authored-by: Age Manning <Age@AgeManning.com> * Merge branch 'unstable' into rpc-error-on-disconnect
This commit is contained in:
@@ -352,6 +352,31 @@ where
|
||||
!matches!(self.state, HandlerState::Deactivated)
|
||||
}
|
||||
|
||||
// NOTE: This function gets polled to completion upon a connection close.
|
||||
fn poll_close(&mut self, _: &mut Context<'_>) -> Poll<Option<Self::ToBehaviour>> {
|
||||
// Inform the network behaviour of any failed requests
|
||||
|
||||
while let Some(substream_id) = self.outbound_substreams.keys().next().cloned() {
|
||||
let outbound_info = self
|
||||
.outbound_substreams
|
||||
.remove(&substream_id)
|
||||
.expect("The value must exist for a key");
|
||||
// If the state of the connection is closing, we do not need to report this case to
|
||||
// the behaviour, as the connection has just closed non-gracefully
|
||||
if matches!(outbound_info.state, OutboundSubstreamState::Closing(_)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Register this request as an RPC Error
|
||||
return Poll::Ready(Some(HandlerEvent::Err(HandlerErr::Outbound {
|
||||
error: RPCError::Disconnected,
|
||||
proto: outbound_info.proto,
|
||||
id: outbound_info.req_id,
|
||||
})));
|
||||
}
|
||||
Poll::Ready(None)
|
||||
}
|
||||
|
||||
fn poll(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
|
||||
@@ -972,6 +972,12 @@ impl<AppReqId: ReqId, E: EthSpec> Network<AppReqId, E> {
|
||||
.goodbye_peer(peer_id, reason, source);
|
||||
}
|
||||
|
||||
/// Hard (ungraceful) disconnect for testing purposes only
|
||||
/// Use goodbye_peer for disconnections, do not use this function.
|
||||
pub fn __hard_disconnect_testing_only(&mut self, peer_id: PeerId) {
|
||||
let _ = self.swarm.disconnect_peer_id(peer_id);
|
||||
}
|
||||
|
||||
/// Returns an iterator over all enr entries in the DHT.
|
||||
pub fn enr_entries(&self) -> Vec<Enr> {
|
||||
self.discovery().table_entries_enr()
|
||||
@@ -1373,12 +1379,18 @@ impl<AppReqId: ReqId, E: EthSpec> Network<AppReqId, E> {
|
||||
let peer_id = event.peer_id;
|
||||
|
||||
if !self.peer_manager().is_connected(&peer_id) {
|
||||
debug!(
|
||||
self.log,
|
||||
"Ignoring rpc message of disconnecting peer";
|
||||
event
|
||||
);
|
||||
return None;
|
||||
// Sync expects a RPCError::Disconnected to drop associated lookups with this peer.
|
||||
// Silencing this event breaks the API contract with RPC where every request ends with
|
||||
// - A stream termination event, or
|
||||
// - An RPCError event
|
||||
if !matches!(event.event, HandlerEvent::Err(HandlerErr::Outbound { .. })) {
|
||||
debug!(
|
||||
self.log,
|
||||
"Ignoring rpc message of disconnecting peer";
|
||||
event
|
||||
);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
let handler_id = event.conn_id;
|
||||
|
||||
Reference in New Issue
Block a user