Add client mode in findNode

This commit is contained in:
Arnaud 2026-05-01 11:20:27 +04:00
parent 1af8dcf504
commit 558b2f4939
No known key found for this signature in database
GPG Key ID: A6C7C781817146FA
2 changed files with 42 additions and 5 deletions

View File

@ -180,6 +180,7 @@ type
talkProtocols*: Table[seq[byte], TalkProtocol] # TODO: Table is a bit of
rng*: ref HmacDrbgContext
providers: ProvidersManager
clientMode*: bool
TalkProtocolHandler* = proc(p: TalkProtocol, request: seq[byte], fromId: NodeId, fromUdpAddress: Address): seq[byte]
{.gcsafe, raises: [Defect].}
@ -340,10 +341,13 @@ proc handleFindNode(d: Protocol, fromId: NodeId, fromAddr: Address,
if fn.distances.len == 0:
d.sendNodes(fromId, fromAddr, reqId, [])
elif fn.distances.contains(0):
# A request for our own record.
# It would be a weird request if there are more distances next to 0
# requested, so in this case lets just pass only our own. TODO: OK?
d.sendNodes(fromId, fromAddr, reqId, [d.localNode])
if d.clientMode:
d.sendNodes(fromId, fromAddr, reqId, [])
else:
# A request for our own record.
# It would be a weird request if there are more distances next to 0
# requested, so in this case lets just pass only our own. TODO: OK?
d.sendNodes(fromId, fromAddr, reqId, [d.localNode])
else:
# TODO: Still deduplicate also?
if fn.distances.all(proc (x: uint16): bool = return x <= 256):
@ -731,7 +735,7 @@ proc addProvider*(
var res = await d.lookup(cId)
# TODO: lookup is specified as not returning local, even if that is the closest. Is this OK?
if res.len == 0:
if res.len == 0 and not d.clientMode:
res.add(d.localNode)
for toNode in res:
if toNode != d.localNode:

View File

@ -777,3 +777,36 @@ suite "Discovery v5 Tests":
await node1.closeWait()
await node2.closeWait()
test "Client mode: findNode(distance=0) returns empty":
# In client mode, the node should not advertise itself when asked for its
# own record (distance=0), so it does not appear in other nodes' routing tables.
let
clientNode = initDiscoveryNode(rng, PrivateKey.example(rng), localAddress(20310))
serverNode = initDiscoveryNode(rng, PrivateKey.example(rng), localAddress(20311))
clientNode.clientMode = true
let response = await discv5_protocol.findNode(serverNode, clientNode.localNode, @[0'u16])
check:
response.isOk()
response[].len == 0
await clientNode.closeWait()
await serverNode.closeWait()
test "Server mode: findNode(distance=0) returns own record":
let
node1 = initDiscoveryNode(rng, PrivateKey.example(rng), localAddress(20312))
node2 = initDiscoveryNode(rng, PrivateKey.example(rng), localAddress(20313))
let response = await discv5_protocol.findNode(node1, node2.localNode, @[0'u16])
check:
response.isOk()
response[].len == 1
response[][0].id == node2.localNode.id
await node1.closeWait()
await node2.closeWait()