js-waku/packages/discovery/src/dns/fetch_nodes.ts
fryorcraken 0dfe35281c
fix: do not limit DNS Peer Discovery on capability
Nodes returned by DNS Discovery are not guaranteed to be reachable.
Hence, setting an upfront limit based on sought capability does not provide
any guarantees that such capability should be reached.

The discovery's mechanism role is to find Waku 2 nodes. As many as possible.

It is then the role of the peer manager to decide:
- whether to attempt connecting to the node based on advertised capabilities
- retain connection to the node based on actual mounted protocols.

We still want to prevent infinite loops, hence the `maxGet` parameter.
Also, there was a dichotomy between code tested, and code actually used by libp2p peer discovery, now resolved.

# Conflicts:
#	packages/discovery/src/dns/constants.ts
2025-07-29 19:29:13 +10:00

45 lines
1.1 KiB
TypeScript

import type { IEnr } from "@waku/interfaces";
import { Logger } from "@waku/utils";
const log = new Logger("discovery:fetch_nodes");
/**
* Fetch nodes using passed [[getNode]] until it has been called [[maxGet]]
* times, or it has returned empty or duplicate results more than [[maxErrors]]
* times.
*/
export async function* fetchNodes(
getNode: () => Promise<IEnr | null>,
maxGet: number = 10,
maxErrors: number = 3
): AsyncGenerator<IEnr> {
const peerNodeIds = new Set();
let totalSearches = 0;
let erroneousSearches = 0;
while (
totalSearches < maxGet &&
erroneousSearches < maxErrors // Allows a couple of empty results before calling it quit
) {
totalSearches++;
const peer = await getNode();
if (!peer || !peer.nodeId) {
erroneousSearches++;
continue;
}
if (!peerNodeIds.has(peer.nodeId)) {
peerNodeIds.add(peer.nodeId);
// ENRs without a waku2 key are ignored.
if (peer.waku2) {
yield peer;
}
log.info(
`got new peer candidate from DNS address=${peer.nodeId}@${peer.ip}`
);
}
}
}