mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-07-20 19:49:28 +00:00
fix(discovery): prune stale discv5 peers from peer store (#3933)
Peer-exchange responds with ENRs read from the PeerStore ENRBook, which is fed add-only by the discv5 search loop and only pruned on capacity, never on staleness. discv5 revalidates its routing table and evicts unreachable nodes within seconds, but those evictions were not propagated to the peer store, so PX kept advertising ENRs of dead peers (only peers we personally failed to dial -> CannotConnect were skipped; disconnected peers are CanConnect and discovered-but-unconnected peers are NotConnected, both of which were still served). Reconcile the peer store against the live routing table at the end of each discv5 search iteration: drop Discv5-origin, non-connected peers that discv5 no longer knows about. Peers discovered in the same round are preserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
319c0c68fe
commit
e2f9efedd8
@ -12,7 +12,8 @@ import
|
||||
libp2p/multiaddress,
|
||||
eth/keys as eth_keys,
|
||||
eth/p2p/discoveryv5/node,
|
||||
eth/p2p/discoveryv5/protocol
|
||||
eth/p2p/discoveryv5/protocol,
|
||||
eth/p2p/discoveryv5/routing_table
|
||||
import
|
||||
logos_delivery/waku/
|
||||
[net/auto_port, node/peer_manager/peer_manager, waku_core, waku_enr]
|
||||
@ -254,6 +255,40 @@ proc findRandomPeers*(
|
||||
|
||||
return discoveredRecords
|
||||
|
||||
proc reconcilePeerStoreWithRoutingTable(
|
||||
wd: WakuDiscoveryV5, pm: PeerManager, justDiscovered: seq[RemotePeerInfo]
|
||||
) =
|
||||
## discv5 revalidates its routing table and evicts unreachable nodes, but those
|
||||
## evictions were never propagated to the peer store. As a result peer-exchange
|
||||
## kept advertising stale ENRs of dead Discv5-origin peers (see #3933), and
|
||||
## clients (e.g. light clients) repeatedly tried to dial unreachable peers.
|
||||
##
|
||||
## Here we drop Discv5-origin, non-connected peers that discv5 no longer knows
|
||||
## about. Peers discovered this round are preserved (they were just learned and
|
||||
## may not be in a routing-table bucket yet).
|
||||
let peerStore = pm.switch.peerStore
|
||||
|
||||
var liveIds = initHashSet[PeerId]()
|
||||
for peer in justDiscovered:
|
||||
liveIds.incl(peer.peerId)
|
||||
for node in wd.protocol.routingTable.randomNodes(int.high):
|
||||
let info = node.record.toRemotePeerInfo().valueOr:
|
||||
continue
|
||||
liveIds.incl(info.peerId)
|
||||
|
||||
var stalePeers: seq[PeerId]
|
||||
for peer in peerStore.peers():
|
||||
if peer.origin == PeerOrigin.Discv5 and peer.connectedness != Connectedness.Connected and
|
||||
peer.peerId notin liveIds:
|
||||
stalePeers.add(peer.peerId)
|
||||
|
||||
for peerId in stalePeers:
|
||||
peerStore.delete(peerId)
|
||||
|
||||
if stalePeers.len > 0:
|
||||
debug "discv5: pruned stale peers no longer in routing table from peer store",
|
||||
count = stalePeers.len
|
||||
|
||||
proc searchLoop(wd: WakuDiscoveryV5) {.async.} =
|
||||
## Continuously add newly discovered nodes
|
||||
|
||||
@ -291,6 +326,11 @@ proc searchLoop(wd: WakuDiscoveryV5) {.async.} =
|
||||
# Peers added are filtered by the peer manager
|
||||
peerManager.addPeer(peer, PeerOrigin.Discv5)
|
||||
|
||||
# Reconcile the peer store with discv5's revalidated routing table so that
|
||||
# peer-exchange stops advertising ENRs of nodes discv5 has already evicted
|
||||
# (#3933).
|
||||
wd.reconcilePeerStoreWithRoutingTable(peerManager, discoveredPeers)
|
||||
|
||||
# Discovery `queryRandom` can have a synchronous fast path for example
|
||||
# when no peers are in the routing table. Don't run it in continuous loop.
|
||||
#
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user