Correct a dial race condition (#2992)
## Issue Addressed On a network with few nodes, it is possible that the same node can be found from a subnet discovery and a normal peer discovery at the same time. The network behaviour loads these peers into events and processes them when it has the chance. It can happen that the same peer can enter the event queue more than once and then attempt to be dialed twice. This PR shifts the registration of nodes in the peerdb as being dialed before they enter the NetworkBehaviour queue, preventing multiple attempts of the same peer being entered into the queue and avoiding the race condition.
This commit is contained in:
parent
48b7c8685b
commit
675c7b7e26
@ -812,7 +812,11 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
for peer_id in peers_to_dial {
|
||||
debug!(self.log, "Dialing cached ENR peer"; "peer_id" => %peer_id);
|
||||
// Remove the ENR from the cache to prevent continual re-dialing on disconnects
|
||||
|
||||
self.discovery.remove_cached_enr(&peer_id);
|
||||
// For any dial event, inform the peer manager
|
||||
let enr = self.discovery_mut().enr_of_peer(&peer_id);
|
||||
self.peer_manager.inject_dialing(&peer_id, enr);
|
||||
self.internal_events
|
||||
.push_back(InternalBehaviourMessage::DialPeer(peer_id));
|
||||
}
|
||||
@ -1096,6 +1100,9 @@ impl<TSpec: EthSpec> NetworkBehaviourEventProcess<DiscoveryEvent> for Behaviour<
|
||||
let to_dial_peers = self.peer_manager.peers_discovered(results);
|
||||
for peer_id in to_dial_peers {
|
||||
debug!(self.log, "Dialing discovered peer"; "peer_id" => %peer_id);
|
||||
// For any dial event, inform the peer manager
|
||||
let enr = self.discovery_mut().enr_of_peer(&peer_id);
|
||||
self.peer_manager.inject_dialing(&peer_id, enr);
|
||||
self.internal_events
|
||||
.push_back(InternalBehaviourMessage::DialPeer(peer_id));
|
||||
}
|
||||
@ -1147,9 +1154,6 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
if let Some(event) = self.internal_events.pop_front() {
|
||||
match event {
|
||||
InternalBehaviourMessage::DialPeer(peer_id) => {
|
||||
// For any dial event, inform the peer manager
|
||||
let enr = self.discovery_mut().enr_of_peer(&peer_id);
|
||||
self.peer_manager.inject_dialing(&peer_id, enr);
|
||||
// Submit the event
|
||||
let handler = self.new_handler();
|
||||
return Poll::Ready(NBAction::Dial {
|
||||
|
Loading…
Reference in New Issue
Block a user