Bit of cleanup (#903)

* Rename FindNode to FindNodes as per spec

* Use consistently lower case starting camelCase for consts

Style guide nep1 allows for both CamelCase and camelCase for
consts, but we seem to use more often camelCase. Using this now
consistently.

* Change some procs to func
This commit is contained in:
Kim De Mey 2021-12-08 11:54:22 +01:00 committed by GitHub
parent 2ea35ef82a
commit 10a3946194
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 92 additions and 95 deletions

View File

@ -24,15 +24,15 @@ proc defaultDataDir*(): string =
getHomeDir() / dataDir
const
DefaultListenAddress* = (static ValidIpAddress.init("0.0.0.0"))
DefaultAdminListenAddress* = (static ValidIpAddress.init("127.0.0.1"))
DefaultProxyAddress* = (static "http://127.0.0.1:8546")
DefaultClientConfig* = getHttpClientConfig(DefaultProxyAddress)
defaultListenAddress* = (static ValidIpAddress.init("0.0.0.0"))
defaultAdminListenAddress* = (static ValidIpAddress.init("127.0.0.1"))
defaultProxyAddress* = (static "http://127.0.0.1:8546")
defaultClientConfig* = getHttpClientConfig(defaultProxyAddress)
DefaultListenAddressDesc = $DefaultListenAddress
DefaultAdminListenAddressDesc = $DefaultAdminListenAddress
DefaultDataDirDesc = defaultDataDir()
DefaultClientConfigDesc = $(DefaultClientConfig.httpUri)
defaultListenAddressDesc = $defaultListenAddress
defaultAdminListenAddressDesc = $defaultAdminListenAddress
defaultDataDirDesc = defaultDataDir()
defaultClientConfigDesc = $(defaultClientConfig.httpUri)
type
PortalCmd* = enum
@ -51,8 +51,8 @@ type
name: "udp-port" .}: uint16
listenAddress* {.
defaultValue: DefaultListenAddress
defaultValueDesc: $DefaultListenAddressDesc
defaultValue: defaultListenAddress
defaultValueDesc: $defaultListenAddressDesc
desc: "Listening address for the Discovery v5 traffic"
name: "listen-address" }: ValidIpAddress
@ -88,7 +88,7 @@ type
dataDir* {.
desc: "The directory where fluffy will store the content data"
defaultValue: defaultDataDir()
defaultValueDesc: $DefaultDataDirDesc
defaultValueDesc: $defaultDataDirDesc
name: "data-dir" }: OutDir
# Note: This will add bootstrap nodes for each enabled Portal network.
@ -108,8 +108,8 @@ type
name: "metrics" .}: bool
metricsAddress* {.
defaultValue: DefaultAdminListenAddress
defaultValueDesc: $DefaultAdminListenAddressDesc
defaultValue: defaultAdminListenAddress
defaultValueDesc: $defaultAdminListenAddressDesc
desc: "Listening address of the metrics server"
name: "metrics-address" .}: ValidIpAddress
@ -130,8 +130,8 @@ type
rpcAddress* {.
desc: "Listening address of the RPC server"
defaultValue: DefaultAdminListenAddress
defaultValueDesc: $DefaultAdminListenAddressDesc
defaultValue: defaultAdminListenAddress
defaultValueDesc: $defaultAdminListenAddressDesc
name: "rpc-address" }: ValidIpAddress
bridgeUri* {.
@ -143,8 +143,8 @@ type
# it makes little sense to have default value here in final release, but until then
# it would be troublesome to add some fake uri param every time
proxyUri* {.
defaultValue: DefaultClientConfig
defaultValueDesc: $DefaultClientConfigDesc
defaultValue: defaultClientConfig
defaultValueDesc: $defaultClientConfigDesc
desc: "URI of eth client where to proxy unimplemented rpc methods to"
name: "proxy-uri" .}: ClientConfig

View File

@ -14,7 +14,7 @@ import
./history_content
const
HistoryProtocolId* = [byte 0x50, 0x0B]
historyProtocolId* = [byte 0x50, 0x0B]
# TODO: Extract common parts from the different networks
type HistoryNetwork* = ref object
@ -60,7 +60,7 @@ proc new*(T: type HistoryNetwork, baseProtocol: protocol.Protocol,
contentDB: ContentDB , dataRadius = UInt256.high(),
bootstrapRecords: openarray[Record] = []): T =
let portalProtocol = PortalProtocol.new(
baseProtocol, HistoryProtocolId, getHandler(contentDB), dataRadius,
baseProtocol, historyProtocolId, getHandler(contentDB), dataRadius,
bootstrapRecords)
return HistoryNetwork(portalProtocol: portalProtocol, contentDB: contentDB)

View File

@ -85,7 +85,7 @@ template computeContentId*(digestCtxType: type, body: untyped): ContentId =
let idHash = finish(h)
readUintBE[256](idHash.data)
proc toContentId*(contentKey: ContentKey): ContentId =
func toContentId*(contentKey: ContentKey): ContentId =
case contentKey.contentType:
of accountTrieNode: # sha256(path | node_hash)
let key = contentKey.accountTrieNodeKey
@ -120,7 +120,7 @@ proc toContentId*(contentKey: ContentKey): ContentId =
h.update(key.address)
h.update(key.codeHash.data)
proc toContentId*(contentKey: ByteList): Option[ContentId] =
func toContentId*(contentKey: ByteList): Option[ContentId] =
let key = decode(contentKey)
if key.isSome():
some(key.get().toContentId())

View File

@ -15,7 +15,7 @@ import
./state_distance
const
StateProtocolId* = [byte 0x50, 0x0A]
stateProtocolId* = [byte 0x50, 0x0A]
type StateNetwork* = ref object
portalProtocol*: PortalProtocol
@ -63,7 +63,7 @@ proc new*(T: type StateNetwork, baseProtocol: protocol.Protocol,
contentDB: ContentDB , dataRadius = UInt256.high(),
bootstrapRecords: openarray[Record] = []): T =
let portalProtocol = PortalProtocol.new(
baseProtocol, StateProtocolId, getHandler(contentDB), dataRadius,
baseProtocol, stateProtocolId, getHandler(contentDB), dataRadius,
bootstrapRecords, stateDistanceCalculator)
return StateNetwork(portalProtocol: portalProtocol, contentDB: contentDB)

View File

@ -32,7 +32,7 @@ type
MessageKind* = enum
ping = 0x00
pong = 0x01
findnode = 0x02
findnodes = 0x02
nodes = 0x03
findcontent = 0x04
content = 0x05
@ -52,7 +52,7 @@ type
enrSeq*: uint64
customPayload*: ByteList
FindNodeMessage* = object
FindNodesMessage* = object
distances*: List[uint16, 256]
NodesMessage* = object
@ -85,8 +85,8 @@ type
ping*: PingMessage
of pong:
pong*: PongMessage
of findnode:
findnode*: FindNodeMessage
of findnodes:
findnodes*: FindNodesMessage
of nodes:
nodes*: NodesMessage
of findcontent:
@ -100,14 +100,14 @@ type
SomeMessage* =
PingMessage or PongMessage or
FindNodeMessage or NodesMessage or
FindNodesMessage or NodesMessage or
FindContentMessage or ContentMessage or
OfferMessage or AcceptMessage
template messageKind*(T: typedesc[SomeMessage]): MessageKind =
when T is PingMessage: ping
elif T is PongMessage: pong
elif T is FindNodeMessage: findnode
elif T is FindNodesMessage: findnodes
elif T is NodesMessage: nodes
elif T is FindContentMessage: findcontent
elif T is ContentMessage: content
@ -124,19 +124,19 @@ func fromSszBytes*(T: type UInt256, data: openArray[byte]):
T.fromBytesLE(data)
proc encodeMessage*[T: SomeMessage](m: T): seq[byte] =
func encodeMessage*[T: SomeMessage](m: T): seq[byte] =
# TODO: Could/should be macro'd away,
# or we just use SSZ.encode(Message) directly
when T is PingMessage: SSZ.encode(Message(kind: ping, ping: m))
elif T is PongMessage: SSZ.encode(Message(kind: pong, pong: m))
elif T is FindNodeMessage: SSZ.encode(Message(kind: findnode, findnode: m))
elif T is FindNodesMessage: SSZ.encode(Message(kind: findnodes, findnodes: m))
elif T is NodesMessage: SSZ.encode(Message(kind: nodes, nodes: m))
elif T is FindContentMessage: SSZ.encode(Message(kind: findcontent, findcontent: m))
elif T is ContentMessage: SSZ.encode(Message(kind: content, content: m))
elif T is OfferMessage: SSZ.encode(Message(kind: offer, offer: m))
elif T is AcceptMessage: SSZ.encode(Message(kind: accept, accept: m))
proc decodeMessage*(body: openarray[byte]): Result[Message, cstring] =
func decodeMessage*(body: openarray[byte]): Result[Message, cstring] =
try:
if body.len < 1: # TODO: This check should probably move a layer down
return err("No message data, peer might not support this talk protocol")
@ -153,16 +153,16 @@ template innerMessage[T: SomeMessage](message: Message, expected: MessageKind):
# All our Message variants correspond to enum MessageKind, therefore we are able to
# zoom in on inner structure of message by defining expected type T.
# If expected variant is not active, return None
proc getInnnerMessage*[T: SomeMessage](m: Message): Option[T] =
func getInnnerMessage*[T: SomeMessage](m: Message): Option[T] =
innerMessage[T](m, messageKind(T))
# Simple conversion from Option to Result, looks like something which could live in
# Result library.
proc optToResult*[T, E](opt: Option[T], e: E): Result[T, E] =
func optToResult*[T, E](opt: Option[T], e: E): Result[T, E] =
if (opt.isSome()):
ok(opt.unsafeGet())
else:
err(e)
proc getInnerMessageResult*[T: SomeMessage](m: Message, errMessage: cstring): Result[T, cstring] =
func getInnerMessageResult*[T: SomeMessage](m: Message, errMessage: cstring): Result[T, cstring] =
optToResult(getInnnerMessage[T](m), errMessage)

View File

@ -23,16 +23,14 @@ logScope:
topics = "portal_wire"
const
Alpha = 3 ## Kademlia concurrency factor
LookupRequestLimit = 3 ## Amount of distances requested in a single Findnode
## message for a lookup or query
EnrsResultLimit = 32 ## Maximum amount of ENRs in the total Nodes messages
alpha = 3 ## Kademlia concurrency factor
enrsResultLimit = 32 ## Maximum amount of ENRs in the total Nodes messages
## that will be processed
RefreshInterval = 5.minutes ## Interval of launching a random query to
refreshInterval = 5.minutes ## Interval of launching a random query to
## refresh the routing table.
RevalidateMax = 10000 ## Revalidation of a peer is done between 0 and this
revalidateMax = 10000 ## Revalidation of a peer is done between 0 and this
## value in milliseconds
InitialLookups = 1 ## Amount of lookups done when populating the routing table
initialLookups = 1 ## Amount of lookups done when populating the routing table
type
ContentResultKind* = enum
@ -90,18 +88,17 @@ proc addNode*(p: PortalProtocol, r: Record): bool =
func localNode*(p: PortalProtocol): Node = p.baseProtocol.localNode
proc neighbours*(p: PortalProtocol, id: NodeId, seenOnly = false): seq[Node] =
func neighbours*(p: PortalProtocol, id: NodeId, seenOnly = false): seq[Node] =
p.routingTable.neighbours(id = id, seenOnly = seenOnly)
proc handlePing(p: PortalProtocol, ping: PingMessage):
seq[byte] =
func handlePing(p: PortalProtocol, ping: PingMessage): seq[byte] =
let customPayload = CustomPayload(dataRadius: p.dataRadius)
let p = PongMessage(enrSeq: p.baseProtocol.localNode.record.seqNum,
customPayload: ByteList(SSZ.encode(customPayload)))
encodeMessage(p)
proc handleFindNode(p: PortalProtocol, fn: FindNodeMessage): seq[byte] =
func handleFindNodes(p: PortalProtocol, fn: FindNodesMessage): seq[byte] =
if fn.distances.len == 0:
let enrs = List[ByteList, 32](@[])
encodeMessage(NodesMessage(total: 1, enrs: enrs))
@ -157,7 +154,7 @@ proc handleFindContent(p: PortalProtocol, fc: FindContentMessage): seq[byte] =
encodeMessage(ContentMessage(
contentMessageType: contentType, content: content))
proc handleOffer(p: PortalProtocol, a: OfferMessage): seq[byte] =
func handleOffer(p: PortalProtocol, a: OfferMessage): seq[byte] =
let
# TODO: Not implemented: Based on the content radius and the content that is
# already stored, interest in provided content keys needs to be indicated
@ -205,8 +202,8 @@ proc messageHandler*(protocol: TalkProtocol, request: seq[byte],
case message.kind
of MessageKind.ping:
p.handlePing(message.ping)
of MessageKind.findnode:
p.handleFindNode(message.findNode)
of MessageKind.findnodes:
p.handleFindNodes(message.findNodes)
of MessageKind.findcontent:
p.handleFindContent(message.findcontent)
of MessageKind.offer:
@ -284,13 +281,13 @@ proc ping*(p: PortalProtocol, dst: Node):
trace "Send message request", dstId = dst.id, kind = MessageKind.ping
return await reqResponse[PingMessage, PongMessage](p, dst, ping)
proc findNode*(p: PortalProtocol, dst: Node, distances: List[uint16, 256]):
proc findNodes*(p: PortalProtocol, dst: Node, distances: List[uint16, 256]):
Future[PortalResult[NodesMessage]] {.async.} =
let fn = FindNodeMessage(distances: distances)
let fn = FindNodesMessage(distances: distances)
trace "Send message request", dstId = dst.id, kind = MessageKind.findnode
trace "Send message request", dstId = dst.id, kind = MessageKind.findnodes
# TODO Add nodes validation
return await reqResponse[FindNodeMessage, NodesMessage](p, dst, fn)
return await reqResponse[FindNodesMessage, NodesMessage](p, dst, fn)
proc findContent*(p: PortalProtocol, dst: Node, contentKey: ByteList):
Future[PortalResult[ContentMessage]] {.async.} =
@ -324,16 +321,16 @@ proc recordsFromBytes(rawRecords: List[ByteList, 32]): PortalResult[seq[Record]]
ok(records)
proc findNodeVerified*(
proc findNodesVerified*(
p: PortalProtocol, dst: Node, distances: seq[uint16]):
Future[PortalResult[seq[Node]]] {.async.} =
let nodesMessage = await p.findNode(dst, List[uint16, 256](distances))
let nodesMessage = await p.findNodes(dst, List[uint16, 256](distances))
if nodesMessage.isOk():
let records = recordsFromBytes(nodesMessage.get().enrs)
if records.isOk():
# TODO: distance function is wrong here for state, fix + tests
return ok(verifyNodesRecords(
records.get(), dst, EnrsResultLimit, distances))
records.get(), dst, enrsResultLimit, distances))
else:
return err(records.error)
else:
@ -342,7 +339,7 @@ proc findNodeVerified*(
proc lookupWorker(
p: PortalProtocol, dst: Node, target: NodeId): Future[seq[Node]] {.async.} =
let distances = lookupDistances(target, dst.id)
let nodesMessage = await p.findNodeVerified(dst, distances)
let nodesMessage = await p.findNodesVerified(dst, distances)
if nodesMessage.isOk():
let nodes = nodesMessage.get()
# Attempt to add all nodes discovered
@ -367,13 +364,13 @@ proc lookup*(p: PortalProtocol, target: NodeId): Future[seq[Node]] {.async.} =
for node in closestNodes:
seen.incl(node.id)
var pendingQueries = newSeqOfCap[Future[seq[Node]]](Alpha)
var pendingQueries = newSeqOfCap[Future[seq[Node]]](alpha)
while true:
var i = 0
# Doing `alpha` amount of requests at once as long as closer non queried
# nodes are discovered.
while i < closestNodes.len and pendingQueries.len < Alpha:
while i < closestNodes.len and pendingQueries.len < alpha:
let n = closestNodes[i]
if not asked.containsOrIncl(n.id):
pendingQueries.add(p.lookupWorker(n, target))
@ -423,7 +420,7 @@ proc handleFoundContentMessage(p: PortalProtocol, m: ContentMessage,
let records = recordsFromBytes(m.enrs)
if records.isOk():
let verifiedNodes =
verifyNodesRecords(records.get(), dst, EnrsResultLimit)
verifyNodesRecords(records.get(), dst, enrsResultLimit)
nodes.add(verifiedNodes)
for n in nodes:
@ -464,13 +461,13 @@ proc contentLookup*(p: PortalProtocol, target: ByteList, targetId: UInt256):
for node in closestNodes:
seen.incl(node.id)
var pendingQueries = newSeqOfCap[Future[LookupResult]](Alpha)
var pendingQueries = newSeqOfCap[Future[LookupResult]](alpha)
while true:
var i = 0
# Doing `alpha` amount of requests at once as long as closer non queried
# nodes are discovered.
while i < closestNodes.len and pendingQueries.len < Alpha:
while i < closestNodes.len and pendingQueries.len < alpha:
let n = closestNodes[i]
if not asked.containsOrIncl(n.id):
pendingQueries.add(p.contentLookupWorker(n, target))
@ -532,11 +529,11 @@ proc query*(p: PortalProtocol, target: NodeId, k = BUCKET_SIZE): Future[seq[Node
for node in queryBuffer:
seen.incl(node.id)
var pendingQueries = newSeqOfCap[Future[seq[Node]]](Alpha)
var pendingQueries = newSeqOfCap[Future[seq[Node]]](alpha)
while true:
var i = 0
while i < min(queryBuffer.len, k) and pendingQueries.len < Alpha:
while i < min(queryBuffer.len, k) and pendingQueries.len < alpha:
let n = queryBuffer[i]
if not asked.containsOrIncl(n.id):
pendingQueries.add(p.lookupWorker(n, target))
@ -593,7 +590,7 @@ proc populateTable(p: PortalProtocol) {.async.} =
let selfQuery = await p.query(p.baseProtocol.localNode.id)
trace "Discovered nodes in self target query", nodes = selfQuery.len
for i in 0..<InitialLookups:
for i in 0..<initialLookups:
let randomQuery = await p.queryRandom()
trace "Discovered nodes in random target query", nodes = randomQuery.len
@ -607,7 +604,7 @@ proc revalidateNode*(p: PortalProtocol, n: Node) {.async.} =
let res = pong.get()
if res.enrSeq > n.record.seqNum:
# Request new ENR
let nodesMessage = await p.findNodeVerified(n, @[0'u16])
let nodesMessage = await p.findNodesVerified(n, @[0'u16])
if nodesMessage.isOk():
let nodes = nodesMessage.get()
if nodes.len > 0: # Normally a node should only return 1 record actually
@ -618,7 +615,7 @@ proc revalidateLoop(p: PortalProtocol) {.async.} =
## message.
try:
while true:
await sleepAsync(milliseconds(p.baseProtocol.rng[].rand(RevalidateMax)))
await sleepAsync(milliseconds(p.baseProtocol.rng[].rand(revalidateMax)))
let n = p.routingTable.nodeToRevalidate()
if not n.isNil:
asyncSpawn p.revalidateNode(n)
@ -639,12 +636,12 @@ proc refreshLoop(p: PortalProtocol) {.async.} =
await sleepAsync(5.seconds)
let currentTime = now(chronos.Moment)
if currentTime > (p.lastLookup + RefreshInterval):
if currentTime > (p.lastLookup + refreshInterval):
let randomQuery = await p.queryRandom()
trace "Discovered nodes in random target query", nodes = randomQuery.len
debug "Total nodes in routing table", total = p.routingTable.len()
await sleepAsync(RefreshInterval)
await sleepAsync(refreshInterval)
except CancelledError:
trace "refreshLoop canceled"
@ -670,7 +667,7 @@ proc resolve*(p: PortalProtocol, id: NodeId): Future[Option[Node]] {.async.} =
let node = p.routingTable.getNode(id)
if node.isSome():
let nodesMessage = await p.findNodeVerified(node.get(), @[0'u16])
let nodesMessage = await p.findNodesVerified(node.get(), @[0'u16])
# TODO: Handle failures better. E.g. stop on different failures than timeout
if nodesMessage.isOk() and nodesMessage[].len > 0:
return some(nodesMessage[][0])

View File

@ -52,10 +52,10 @@ suite "Portal Wire Protocol Message Encodings":
message.pong.enrSeq == enrSeq
message.pong.customPayload == customPayload
test "FindNode Request":
test "FindNodes Request":
let
distances = List[uint16, 256](@[0x0100'u16, 0x00ff'u16])
fn = FindNodeMessage(distances: distances)
fn = FindNodesMessage(distances: distances)
let encoded = encodeMessage(fn)
check encoded.toHex == "02040000000001ff00"
@ -65,8 +65,8 @@ suite "Portal Wire Protocol Message Encodings":
let message = decoded.get()
check:
message.kind == findnode
message.findnode.distances == distances
message.kind == findnodes
message.findnodes.distances == distances
test "Nodes Response - empty enr list":
let

View File

@ -68,11 +68,11 @@ procSuite "Portal Wire Protocol Tests":
await test.stopTest()
asyncTest "FindNode/Nodes":
asyncTest "FindNodes/Nodes":
let test = defaultTestCase(rng)
block: # Find itself
let nodes = await test.proto1.findNode(test.proto2.localNode,
let nodes = await test.proto1.findNodes(test.proto2.localNode,
List[uint16, 256](@[0'u16]))
check:
@ -82,7 +82,7 @@ procSuite "Portal Wire Protocol Tests":
block: # Find nothing: this should result in nothing as we haven't started
# the seeding of the portal protocol routing table yet.
let nodes = await test.proto1.findNode(test.proto2.localNode,
let nodes = await test.proto1.findNodes(test.proto2.localNode,
List[uint16, 256](@[]))
check:
@ -102,7 +102,7 @@ procSuite "Portal Wire Protocol Tests":
test.proto2.start()
let distance = logDistance(test.node1.localNode.id, test.node2.localNode.id)
let nodes = await test.proto1.findNode(test.proto2.localNode,
let nodes = await test.proto1.findNodes(test.proto2.localNode,
List[uint16, 256](@[distance]))
check:

View File

@ -92,7 +92,7 @@ procSuite "State Content Network":
asyncTest "Find content in the network via content lookup":
# TODO: Improve this test so it actually need to go through several
# findNode request, to properly test the lookup call.
# findNodes request, to properly test the lookup call.
let
trie = genesisToTrie("fluffy" / "tests" / "custom_genesis" / "chainid7.json")
node1 = initDiscoveryNode(
@ -172,7 +172,7 @@ procSuite "State Content Network":
let distance = proto1.portalProtocol.routingTable.logDistance(
node1.localNode.id, node2.localNode.id)
let nodes = await proto1.portalProtocol.findNode(
let nodes = await proto1.portalProtocol.findNodes(
proto2.portalProtocol.localNode, List[uint16, 256](@[distance]))
check:

View File

@ -17,17 +17,17 @@ import
../network/state/state_content
const
DefaultListenAddress* = (static ValidIpAddress.init("0.0.0.0"))
DefaultAdminListenAddress* = (static ValidIpAddress.init("127.0.0.1"))
defaultListenAddress* = (static ValidIpAddress.init("0.0.0.0"))
defaultAdminListenAddress* = (static ValidIpAddress.init("127.0.0.1"))
DefaultListenAddressDesc = $DefaultListenAddress
DefaultAdminListenAddressDesc = $DefaultAdminListenAddress
defaultListenAddressDesc = $defaultListenAddress
defaultAdminListenAddressDesc = $defaultAdminListenAddress
type
PortalCmd* = enum
noCommand
ping
findnode
findnodes
findcontent
DiscoveryConf* = object
@ -43,8 +43,8 @@ type
name: "udp-port" .}: uint16
listenAddress* {.
defaultValue: DefaultListenAddress
defaultValueDesc: $DefaultListenAddressDesc
defaultValue: defaultListenAddress
defaultValueDesc: $defaultListenAddressDesc
desc: "Listening address for the Discovery v5 traffic"
name: "listen-address" }: ValidIpAddress
@ -82,8 +82,8 @@ type
name: "metrics" .}: bool
metricsAddress* {.
defaultValue: DefaultAdminListenAddress
defaultValueDesc: $DefaultAdminListenAddressDesc
defaultValue: defaultAdminListenAddress
defaultValueDesc: $defaultAdminListenAddressDesc
desc: "Listening address of the metrics server"
name: "metrics-address" .}: ValidIpAddress
@ -102,16 +102,16 @@ type
argument
desc: "ENR URI of the node to a send ping message"
name: "node" .}: Node
of findnode:
of findnodes:
distance* {.
defaultValue: 255
desc: "Distance parameter for the findNode message"
desc: "Distance parameter for the findNodes message"
name: "distance" .}: uint16
# TODO: Order here matters as else the help message does not show all the
# information, see: https://github.com/status-im/nim-confutils/issues/15
findNodeTarget* {.
findNodesTarget* {.
argument
desc: "ENR URI of the node to send a findNode message"
desc: "ENR URI of the node to send a findNodes message"
name: "node" .}: Node
of findcontent:
findContentTarget* {.
@ -210,9 +210,9 @@ proc run(config: DiscoveryConf) =
echo pong.get()
else:
echo pong.error
of findnode:
of findnodes:
let distances = List[uint16, 256](@[config.distance])
let nodes = waitFor portal.findNode(config.findNodeTarget, distances)
let nodes = waitFor portal.findNodes(config.findNodesTarget, distances)
if nodes.isOk():
echo nodes.get()