2024-06-28 16:04:57 +05:30
|
|
|
{.push raises: [].}
|
2021-08-12 10:51:38 +02:00
|
|
|
|
|
|
|
|
## A set of utilities to integrate EIP-1459 DNS-based discovery
|
|
|
|
|
## for Waku v2 nodes.
|
2022-12-07 12:30:32 +01:00
|
|
|
##
|
2021-08-12 10:51:38 +02:00
|
|
|
## EIP-1459 is defined in https://eips.ethereum.org/EIPS/eip-1459
|
|
|
|
|
|
|
|
|
|
import
|
2025-10-08 19:14:54 -03:00
|
|
|
std/[options, net, sequtils, sugar],
|
2021-08-12 10:51:38 +02:00
|
|
|
chronicles,
|
|
|
|
|
chronos,
|
|
|
|
|
metrics,
|
|
|
|
|
eth/keys,
|
2026-01-02 01:02:13 +05:30
|
|
|
eth/enr/enr,
|
2021-08-12 10:51:38 +02:00
|
|
|
libp2p/crypto/crypto,
|
|
|
|
|
libp2p/crypto/secp,
|
|
|
|
|
libp2p/multiaddress,
|
2021-10-06 14:29:08 +02:00
|
|
|
libp2p/peerid,
|
2024-01-15 15:54:02 +01:00
|
|
|
dnsdisc/client
|
2024-05-01 21:13:08 +02:00
|
|
|
import libp2p/nameresolving/dnsresolver
|
2024-04-17 21:48:20 +02:00
|
|
|
import ../waku_core
|
2021-08-12 10:51:38 +02:00
|
|
|
|
|
|
|
|
export client
|
|
|
|
|
|
|
|
|
|
declarePublicGauge waku_dnsdisc_discovered, "number of nodes discovered"
|
2025-08-01 16:11:32 +05:30
|
|
|
declarePublicCounter waku_dnsdisc_errors, "number of waku dnsdisc errors", ["type"]
|
2021-08-12 10:51:38 +02:00
|
|
|
|
|
|
|
|
logScope:
|
2022-11-03 16:36:24 +01:00
|
|
|
topics = "waku dnsdisc"
|
2021-08-12 10:51:38 +02:00
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
type WakuDnsDiscovery* = object
|
|
|
|
|
client*: Client
|
|
|
|
|
resolver*: Resolver
|
2021-08-12 10:51:38 +02:00
|
|
|
|
|
|
|
|
#####################
|
|
|
|
|
# DNS Discovery API #
|
|
|
|
|
#####################
|
|
|
|
|
|
|
|
|
|
proc emptyResolver*(domain: string): Future[string] {.async, gcsafe.} =
|
2025-10-15 10:49:36 +02:00
|
|
|
info "Empty resolver called", domain = domain
|
2021-08-12 10:51:38 +02:00
|
|
|
return ""
|
|
|
|
|
|
2024-12-03 14:39:37 +01:00
|
|
|
proc findPeers*(
|
|
|
|
|
wdd: WakuDnsDiscovery
|
|
|
|
|
): Future[Result[seq[RemotePeerInfo], cstring]] {.async.} =
|
2021-08-12 10:51:38 +02:00
|
|
|
## Find peers to connect to using DNS based discovery
|
2022-12-07 12:30:32 +01:00
|
|
|
|
2021-08-12 10:51:38 +02:00
|
|
|
info "Finding peers using Waku DNS discovery"
|
2022-12-07 12:30:32 +01:00
|
|
|
|
2021-08-12 10:51:38 +02:00
|
|
|
# Synchronise client tree using configured resolver
|
|
|
|
|
var tree: Tree
|
|
|
|
|
try:
|
2024-12-03 14:39:37 +01:00
|
|
|
tree = (await syncTree(wdd.resolver, wdd.client.loc)).tryGet()
|
2021-08-12 10:51:38 +02:00
|
|
|
except Exception:
|
|
|
|
|
error "Failed to synchronise client tree"
|
|
|
|
|
waku_dnsdisc_errors.inc(labelValues = ["tree_sync_failure"])
|
|
|
|
|
return err("Node discovery failed")
|
|
|
|
|
|
2024-12-03 14:39:37 +01:00
|
|
|
let discoveredEnr = tree.getNodes().mapIt(it.record)
|
2021-08-12 10:51:38 +02:00
|
|
|
|
|
|
|
|
if discoveredEnr.len > 0:
|
2024-03-16 00:08:47 +01:00
|
|
|
info "Successfully discovered ENR", count = discoveredEnr.len
|
2021-08-12 10:51:38 +02:00
|
|
|
else:
|
|
|
|
|
trace "No ENR retrieved from client tree"
|
|
|
|
|
|
2021-10-06 14:29:08 +02:00
|
|
|
var discoveredNodes: seq[RemotePeerInfo]
|
2021-08-12 10:51:38 +02:00
|
|
|
|
|
|
|
|
for enr in discoveredEnr:
|
2021-10-06 14:29:08 +02:00
|
|
|
# Convert discovered ENR to RemotePeerInfo and add to discovered nodes
|
2025-10-08 19:14:54 -03:00
|
|
|
let peerInfo = enr.toRemotePeerInfo().valueOr:
|
|
|
|
|
error "Failed to convert ENR to peer info", enr = $enr, error = error
|
2021-08-12 10:51:38 +02:00
|
|
|
waku_dnsdisc_errors.inc(labelValues = ["peer_info_failure"])
|
2025-10-08 19:14:54 -03:00
|
|
|
continue
|
|
|
|
|
discoveredNodes.add(peerInfo)
|
2021-08-12 10:51:38 +02:00
|
|
|
if discoveredNodes.len > 0:
|
2024-03-16 00:08:47 +01:00
|
|
|
info "Successfully discovered nodes", count = discoveredNodes.len
|
2021-08-12 10:51:38 +02:00
|
|
|
waku_dnsdisc_discovered.inc(discoveredNodes.len.int64)
|
|
|
|
|
|
|
|
|
|
return ok(discoveredNodes)
|
|
|
|
|
|
2024-03-16 00:08:47 +01:00
|
|
|
proc init*(
|
|
|
|
|
T: type WakuDnsDiscovery, locationUrl: string, resolver: Resolver
|
|
|
|
|
): Result[T, cstring] =
|
2021-08-12 10:51:38 +02:00
|
|
|
## Initialise Waku peer discovery via DNS
|
2022-12-07 12:30:32 +01:00
|
|
|
|
2025-10-15 10:49:36 +02:00
|
|
|
info "init WakuDnsDiscovery", locationUrl = locationUrl
|
2022-12-07 12:30:32 +01:00
|
|
|
|
2021-08-12 10:51:38 +02:00
|
|
|
let
|
2024-03-16 00:08:47 +01:00
|
|
|
client = ?Client.init(locationUrl)
|
2021-08-17 10:30:17 +02:00
|
|
|
wakuDnsDisc = WakuDnsDiscovery(client: client, resolver: resolver)
|
2021-08-12 10:51:38 +02:00
|
|
|
|
2025-10-15 10:49:36 +02:00
|
|
|
info "init success"
|
2021-08-12 10:51:38 +02:00
|
|
|
|
|
|
|
|
return ok(wakuDnsDisc)
|
2024-05-01 21:13:08 +02:00
|
|
|
|
|
|
|
|
proc retrieveDynamicBootstrapNodes*(
|
2025-07-02 16:37:02 +02:00
|
|
|
dnsDiscoveryUrl: string, dnsAddrsNameServers: seq[IpAddress]
|
2024-12-03 14:39:37 +01:00
|
|
|
): Future[Result[seq[RemotePeerInfo], string]] {.async.} =
|
2024-05-01 21:13:08 +02:00
|
|
|
## Retrieve dynamic bootstrap nodes (DNS discovery)
|
|
|
|
|
|
2025-02-24 22:06:48 +02:00
|
|
|
if dnsDiscoveryUrl != "":
|
2024-05-01 21:13:08 +02:00
|
|
|
# DNS discovery
|
2025-10-15 10:49:36 +02:00
|
|
|
info "Discovering nodes using Waku DNS discovery", url = dnsDiscoveryUrl
|
2024-05-01 21:13:08 +02:00
|
|
|
|
|
|
|
|
var nameServers: seq[TransportAddress]
|
2025-07-02 16:37:02 +02:00
|
|
|
for ip in dnsAddrsNameServers:
|
2024-05-01 21:13:08 +02:00
|
|
|
nameServers.add(initTAddress(ip, Port(53))) # Assume all servers use port 53
|
|
|
|
|
|
|
|
|
|
let dnsResolver = DnsResolver.new(nameServers)
|
|
|
|
|
|
|
|
|
|
proc resolver(domain: string): Future[string] {.async, gcsafe.} =
|
|
|
|
|
trace "resolving", domain = domain
|
|
|
|
|
let resolved = await dnsResolver.resolveTxt(domain)
|
2024-12-03 14:39:37 +01:00
|
|
|
if resolved.len > 0:
|
|
|
|
|
return resolved[0] # Use only first answer
|
2024-05-01 21:13:08 +02:00
|
|
|
|
2025-10-08 19:14:54 -03:00
|
|
|
var wakuDnsDiscovery = WakuDnsDiscovery.init(dnsDiscoveryUrl, resolver).errorOr:
|
|
|
|
|
return (await value.findPeers()).mapErr(e => $e)
|
|
|
|
|
warn "Failed to init Waku DNS discovery"
|
2024-05-01 21:13:08 +02:00
|
|
|
|
2025-10-15 10:49:36 +02:00
|
|
|
info "No method for retrieving dynamic bootstrap nodes specified."
|
2024-05-01 21:13:08 +02:00
|
|
|
ok(newSeq[RemotePeerInfo]()) # Return an empty seq by default
|