From 0d039147bde1bb0472465b622e430e597ac9be9b Mon Sep 17 00:00:00 2001 From: Lion - dapplion <35266934+dapplion@users.noreply.github.com> Date: Tue, 6 Aug 2024 04:32:56 +0200 Subject: [PATCH] Skip recursive discovery query if no useful ENRs (#6207) * Skip recursive discovery query if no useful ENRs --- beacon_node/lighthouse_network/src/metrics.rs | 6 ++++++ .../lighthouse_network/src/peer_manager/mod.rs | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/beacon_node/lighthouse_network/src/metrics.rs b/beacon_node/lighthouse_network/src/metrics.rs index 9b11fe5a380..85da8dc2112 100644 --- a/beacon_node/lighthouse_network/src/metrics.rs +++ b/beacon_node/lighthouse_network/src/metrics.rs @@ -77,6 +77,12 @@ pub static DISCOVERY_SESSIONS: LazyLock> = LazyLock::new(|| { "The number of active discovery sessions with peers", ) }); +pub static DISCOVERY_NO_USEFUL_ENRS: LazyLock> = LazyLock::new(|| { + try_create_int_counter( + "discovery_no_useful_enrs_found", + "Total number of counts a query returned no useful ENRs to dial", + ) +}); pub static PEERS_PER_CLIENT: LazyLock> = LazyLock::new(|| { try_create_int_gauge_vec( diff --git a/beacon_node/lighthouse_network/src/peer_manager/mod.rs b/beacon_node/lighthouse_network/src/peer_manager/mod.rs index 4d3da0c8e4b..6423da56fe2 100644 --- a/beacon_node/lighthouse_network/src/peer_manager/mod.rs +++ b/beacon_node/lighthouse_network/src/peer_manager/mod.rs @@ -321,6 +321,7 @@ impl PeerManager { /// This function decides whether or not to dial these peers. pub fn peers_discovered(&mut self, results: HashMap>) { let mut to_dial_peers = 0; + let results_count = results.len(); let connected_or_dialing = self.network_globals.connected_or_dialing_peers(); for (enr, min_ttl) in results { // There are two conditions in deciding whether to dial this peer. @@ -352,8 +353,19 @@ impl PeerManager { } } - // Queue another discovery if we need to - self.maintain_peer_count(to_dial_peers); + // The heartbeat will attempt new discovery queries every N seconds if the node needs more + // peers. As an optimization, this function can recursively trigger new discovery queries + // immediatelly if we don't fulfill our peers needs after completing a query. This + // recursiveness results in an infinite loop in networks where there not enough peers to + // reach out target. To prevent the infinite loop, if a query returns no useful peers, we + // will cancel the recursiveness and wait for the heartbeat to trigger another query latter. + if results_count > 0 && to_dial_peers == 0 { + debug!(self.log, "Skipping recursive discovery query after finding no useful results"; "results" => results_count); + metrics::inc_counter(&metrics::DISCOVERY_NO_USEFUL_ENRS); + } else { + // Queue another discovery if we need to + self.maintain_peer_count(to_dial_peers); + } } /// A STATUS message has been received from a peer. This resets the status timer.