2020-02-17 15:36:04 +00:00
|
|
|
import
|
2020-02-26 22:15:14 +00:00
|
|
|
random, unittest, chronos, sequtils, chronicles, tables,
|
|
|
|
eth/[keys, rlp], eth/p2p/enode, eth/trie/db,
|
|
|
|
eth/p2p/discoveryv5/[discovery_db, enr, node, types, routing_table, encoding],
|
2020-02-17 15:36:04 +00:00
|
|
|
eth/p2p/discoveryv5/protocol as discv5_protocol,
|
|
|
|
./p2p_test_helper
|
|
|
|
|
2020-02-24 14:45:30 +00:00
|
|
|
proc initDiscoveryNode*(privKey: PrivateKey, address: Address,
|
2020-02-17 23:07:23 +00:00
|
|
|
bootnodes: seq[Record]): discv5_protocol.Protocol =
|
2020-02-17 15:36:04 +00:00
|
|
|
var db = DiscoveryDB.init(newMemoryDB())
|
2020-02-21 23:55:37 +00:00
|
|
|
result = newProtocol(privKey, db,
|
|
|
|
parseIpAddress("127.0.0.1"),
|
|
|
|
address.tcpPort, address.udpPort)
|
2020-02-17 15:36:04 +00:00
|
|
|
|
|
|
|
for node in bootnodes:
|
|
|
|
result.addNode(node)
|
|
|
|
|
|
|
|
result.open()
|
|
|
|
|
|
|
|
proc nodeIdInNodes(id: NodeId, nodes: openarray[Node]): bool =
|
|
|
|
for n in nodes:
|
|
|
|
if id == n.id: return true
|
|
|
|
|
2020-02-27 21:36:42 +00:00
|
|
|
# Creating a random packet with specific nodeid each time
|
|
|
|
proc randomPacket(tag: PacketTag): seq[byte] =
|
|
|
|
var
|
|
|
|
authTag: AuthTag
|
|
|
|
msg: array[44, byte]
|
|
|
|
|
|
|
|
randomBytes(authTag)
|
|
|
|
randomBytes(msg)
|
|
|
|
result.add(tag)
|
|
|
|
result.add(rlp.encode(authTag))
|
|
|
|
result.add(msg)
|
|
|
|
|
2020-02-17 15:36:04 +00:00
|
|
|
suite "Discovery v5 Tests":
|
2020-02-24 14:45:30 +00:00
|
|
|
asyncTest "Random nodes":
|
2020-02-17 15:36:04 +00:00
|
|
|
let
|
|
|
|
bootNodeKey = initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617")
|
2020-02-26 22:15:14 +00:00
|
|
|
bootNode = initDiscoveryNode(bootNodeKey, localAddress(20301), @[])
|
2020-02-17 15:36:04 +00:00
|
|
|
|
|
|
|
let nodeKeys = [
|
|
|
|
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a618"),
|
|
|
|
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a619"),
|
|
|
|
initPrivateKey("a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a620")
|
|
|
|
]
|
|
|
|
var nodeAddrs = newSeqOfCap[Address](nodeKeys.len)
|
|
|
|
for i in 0 ..< nodeKeys.len: nodeAddrs.add(localAddress(20302 + i))
|
|
|
|
|
|
|
|
var nodes = zip(nodeKeys, nodeAddrs).mapIt(
|
2020-03-23 21:09:16 +00:00
|
|
|
initDiscoveryNode(it[0], it[1], @[bootNode.localNode.record]))
|
2020-02-17 15:36:04 +00:00
|
|
|
nodes.add(bootNode)
|
|
|
|
|
|
|
|
for node in nodes:
|
|
|
|
let discovered = await node.lookupRandom()
|
2020-02-19 12:11:19 +00:00
|
|
|
check discovered.len < nodes.len
|
2020-02-24 14:45:30 +00:00
|
|
|
debug "Lookup from random id", node = node.localNode, discovered
|
2020-02-17 15:36:04 +00:00
|
|
|
|
|
|
|
# Check for each node if the other nodes shows up in the routing table
|
|
|
|
for i in nodes:
|
|
|
|
for j in nodes:
|
|
|
|
if j != i:
|
|
|
|
check(nodeIdInNodes(i.localNode.id, j.randomNodes(nodes.len - 1)))
|
2020-02-24 14:45:30 +00:00
|
|
|
|
|
|
|
for node in nodes:
|
|
|
|
await node.closeWait()
|
|
|
|
|
|
|
|
asyncTest "Lookup targets":
|
|
|
|
const
|
2020-02-25 13:49:31 +00:00
|
|
|
nodeCount = 17
|
2020-02-24 14:45:30 +00:00
|
|
|
|
2020-02-26 22:15:14 +00:00
|
|
|
let bootNode = initDiscoveryNode(newPrivateKey(), localAddress(20301), @[])
|
2020-02-24 14:45:30 +00:00
|
|
|
|
|
|
|
var nodes = newSeqOfCap[discv5_protocol.Protocol](nodeCount)
|
|
|
|
nodes.add(bootNode)
|
|
|
|
for i in 1 ..< nodeCount:
|
|
|
|
nodes.add(initDiscoveryNode(newPrivateKey(), localAddress(20301 + i),
|
|
|
|
@[bootNode.localNode.record]))
|
|
|
|
|
|
|
|
for i in 0..<nodeCount-1:
|
|
|
|
let target = nodes[i]
|
|
|
|
let discovered = await nodes[nodeCount-1].lookup(target.localNode.id)
|
|
|
|
debug "Lookup result", target = target.localNode, discovered
|
|
|
|
# if lookUp would return ordered on distance we could check discovered[0]
|
|
|
|
check discovered.contains(target.localNode)
|
|
|
|
|
|
|
|
for node in nodes:
|
|
|
|
await node.closeWait()
|
2020-02-26 22:15:14 +00:00
|
|
|
|
2020-02-27 21:36:42 +00:00
|
|
|
asyncTest "Handshake cleanup":
|
2020-02-26 22:15:14 +00:00
|
|
|
let node = initDiscoveryNode(newPrivateKey(), localAddress(20302), @[])
|
2020-02-27 21:36:42 +00:00
|
|
|
var tag: PacketTag
|
2020-02-26 22:15:14 +00:00
|
|
|
let a = localAddress(20303)
|
2020-02-27 21:36:42 +00:00
|
|
|
|
2020-02-26 22:15:14 +00:00
|
|
|
for i in 0 ..< 5:
|
2020-02-27 21:36:42 +00:00
|
|
|
randomBytes(tag)
|
|
|
|
node.receive(a, randomPacket(tag))
|
2020-02-26 22:15:14 +00:00
|
|
|
|
2020-02-27 21:36:42 +00:00
|
|
|
# Checking different nodeIds but same address
|
2020-02-26 22:15:14 +00:00
|
|
|
check node.codec.handshakes.len == 5
|
2020-02-27 21:36:42 +00:00
|
|
|
# TODO: Could get rid of the sleep by storing the timeout future of the
|
|
|
|
# handshake
|
2020-02-26 22:15:14 +00:00
|
|
|
await sleepAsync(handshakeTimeout)
|
|
|
|
# Checking handshake cleanup
|
|
|
|
check node.codec.handshakes.len == 0
|
|
|
|
|
2020-02-27 21:36:42 +00:00
|
|
|
await node.closeWait()
|
|
|
|
|
|
|
|
asyncTest "Handshake different address":
|
|
|
|
let node = initDiscoveryNode(newPrivateKey(), localAddress(20302), @[])
|
|
|
|
var tag: PacketTag
|
|
|
|
|
2020-02-26 22:15:14 +00:00
|
|
|
for i in 0 ..< 5:
|
2020-02-27 21:36:42 +00:00
|
|
|
let a = localAddress(20303 + i)
|
|
|
|
node.receive(a, randomPacket(tag))
|
|
|
|
|
|
|
|
check node.codec.handshakes.len == 5
|
|
|
|
|
|
|
|
await node.closeWait()
|
|
|
|
|
|
|
|
asyncTest "Handshake duplicates":
|
|
|
|
let node = initDiscoveryNode(newPrivateKey(), localAddress(20302), @[])
|
|
|
|
var tag: PacketTag
|
|
|
|
let a = localAddress(20303)
|
|
|
|
|
|
|
|
for i in 0 ..< 5:
|
|
|
|
node.receive(a, randomPacket(tag))
|
2020-02-26 22:15:14 +00:00
|
|
|
|
|
|
|
# Checking handshake duplicates
|
|
|
|
check node.codec.handshakes.len == 1
|
|
|
|
|
2020-02-27 21:36:42 +00:00
|
|
|
# TODO: add check that gets the Whoareyou value and checks if its authTag
|
|
|
|
# is that of the first packet.
|
|
|
|
|
2020-02-26 22:15:14 +00:00
|
|
|
await node.closeWait()
|