mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-02 14:03:06 +00:00
151 lines
4.4 KiB
Nim
151 lines
4.4 KiB
Nim
import std/json
|
|
import chronos, chronicles, results, strutils, libp2p/multiaddress
|
|
import
|
|
../../../waku/factory/waku,
|
|
../../../waku/discovery/waku_dnsdisc,
|
|
../../../waku/discovery/waku_discv5,
|
|
../../../waku/waku_core/peers,
|
|
../../../waku/node/waku_node,
|
|
../../alloc
|
|
|
|
type DiscoveryMsgType* = enum
|
|
GET_BOOTSTRAP_NODES
|
|
UPDATE_DISCV5_BOOTSTRAP_NODES
|
|
START_DISCV5
|
|
STOP_DISCV5
|
|
PEER_EXCHANGE
|
|
|
|
type DiscoveryRequest* = object
|
|
operation: DiscoveryMsgType
|
|
|
|
## used in GET_BOOTSTRAP_NODES
|
|
enrTreeUrl: cstring
|
|
nameDnsServer: cstring
|
|
timeoutMs: cint
|
|
|
|
## used in UPDATE_DISCV5_BOOTSTRAP_NODES
|
|
nodes: cstring
|
|
|
|
## used in PEER_EXCHANGE
|
|
numPeers: uint64
|
|
|
|
proc createShared(
|
|
T: type DiscoveryRequest,
|
|
op: DiscoveryMsgType,
|
|
enrTreeUrl: cstring,
|
|
nameDnsServer: cstring,
|
|
timeoutMs: cint,
|
|
nodes: cstring,
|
|
numPeers: uint64,
|
|
): ptr type T =
|
|
var ret = createShared(T)
|
|
ret[].operation = op
|
|
ret[].enrTreeUrl = enrTreeUrl.alloc()
|
|
ret[].nameDnsServer = nameDnsServer.alloc()
|
|
ret[].timeoutMs = timeoutMs
|
|
ret[].nodes = nodes.alloc()
|
|
ret[].numPeers = numPeers
|
|
return ret
|
|
|
|
proc createRetrieveBootstrapNodesRequest*(
|
|
T: type DiscoveryRequest,
|
|
op: DiscoveryMsgType,
|
|
enrTreeUrl: cstring,
|
|
nameDnsServer: cstring,
|
|
timeoutMs: cint,
|
|
): ptr type T =
|
|
return T.createShared(op, enrTreeUrl, nameDnsServer, timeoutMs, "", 0)
|
|
|
|
proc createUpdateBootstrapNodesRequest*(
|
|
T: type DiscoveryRequest, op: DiscoveryMsgType, nodes: cstring
|
|
): ptr type T =
|
|
return T.createShared(op, "", "", 0, nodes, 0)
|
|
|
|
proc createDiscV5StartRequest*(T: type DiscoveryRequest): ptr type T =
|
|
return T.createShared(START_DISCV5, "", "", 0, "", 0)
|
|
|
|
proc createDiscV5StopRequest*(T: type DiscoveryRequest): ptr type T =
|
|
return T.createShared(STOP_DISCV5, "", "", 0, "", 0)
|
|
|
|
proc createPeerExchangeRequest*(
|
|
T: type DiscoveryRequest, numPeers: uint64
|
|
): ptr type T =
|
|
return T.createShared(PEER_EXCHANGE, "", "", 0, "", numPeers)
|
|
|
|
proc destroyShared(self: ptr DiscoveryRequest) =
|
|
deallocShared(self[].enrTreeUrl)
|
|
deallocShared(self[].nameDnsServer)
|
|
deallocShared(self[].nodes)
|
|
deallocShared(self)
|
|
|
|
proc retrieveBootstrapNodes(
|
|
enrTreeUrl: string, ipDnsServer: string
|
|
): Future[Result[seq[string], string]] {.async.} =
|
|
let dnsNameServers = @[parseIpAddress(ipDnsServer)]
|
|
let discoveredPeers: seq[RemotePeerInfo] = (
|
|
await retrieveDynamicBootstrapNodes(enrTreeUrl, dnsNameServers)
|
|
).valueOr:
|
|
return err("failed discovering peers from DNS: " & $error)
|
|
|
|
var multiAddresses = newSeq[string]()
|
|
|
|
for discPeer in discoveredPeers:
|
|
for address in discPeer.addrs:
|
|
multiAddresses.add($address & "/p2p/" & $discPeer)
|
|
|
|
return ok(multiAddresses)
|
|
|
|
proc updateDiscv5BootstrapNodes(nodes: string, waku: ptr Waku): Result[void, string] =
|
|
waku.wakuDiscv5.updateBootstrapRecords(nodes).isOkOr:
|
|
return err("error in updateDiscv5BootstrapNodes: " & $error)
|
|
return ok()
|
|
|
|
proc performPeerExchangeRequestTo(
|
|
numPeers: uint64, waku: ptr Waku
|
|
): Future[Result[int, string]] {.async.} =
|
|
let numPeersRecv = (await waku.node.fetchPeerExchangePeers(numPeers)).valueOr:
|
|
return err($error)
|
|
return ok(numPeersRecv)
|
|
|
|
proc process*(
|
|
self: ptr DiscoveryRequest, waku: ptr Waku
|
|
): Future[Result[string, string]] {.async.} =
|
|
defer:
|
|
destroyShared(self)
|
|
|
|
case self.operation
|
|
of START_DISCV5:
|
|
let res = await waku.wakuDiscv5.start()
|
|
res.isOkOr:
|
|
error "START_DISCV5 failed", error = error
|
|
return err($error)
|
|
|
|
return ok("discv5 started correctly")
|
|
of STOP_DISCV5:
|
|
await waku.wakuDiscv5.stop()
|
|
|
|
return ok("discv5 stopped correctly")
|
|
of GET_BOOTSTRAP_NODES:
|
|
let nodes = (
|
|
await retrieveBootstrapNodes($self[].enrTreeUrl, $self[].nameDnsServer)
|
|
).valueOr:
|
|
error "GET_BOOTSTRAP_NODES failed", error = error
|
|
return err($error)
|
|
|
|
## returns a comma-separated string of bootstrap nodes' multiaddresses
|
|
return ok(nodes.join(","))
|
|
of UPDATE_DISCV5_BOOTSTRAP_NODES:
|
|
updateDiscv5BootstrapNodes($self[].nodes, waku).isOkOr:
|
|
error "UPDATE_DISCV5_BOOTSTRAP_NODES failed", error = error
|
|
return err($error)
|
|
|
|
return ok("discovery request processed correctly")
|
|
of PEER_EXCHANGE:
|
|
let numValidPeers = (await performPeerExchangeRequestTo(self[].numPeers, waku)).valueOr:
|
|
error "PEER_EXCHANGE failed", error = error
|
|
return err($error)
|
|
return ok($numValidPeers)
|
|
|
|
error "discovery request not handled"
|
|
return err("discovery request not handled")
|