mirror of https://github.com/status-im/nim-eth.git
Add update of ENR on newly discovered address
This commit is contained in:
parent
689eef2c11
commit
bfbad64d83
|
@ -14,12 +14,12 @@ type
|
|||
DiscoveryConf* = object
|
||||
logLevel* {.
|
||||
defaultValue: LogLevel.DEBUG
|
||||
desc: "Sets the log level."
|
||||
desc: "Sets the log level"
|
||||
name: "log-level" .}: LogLevel
|
||||
|
||||
udpPort* {.
|
||||
defaultValue: 9009
|
||||
desc: "UDP listening port."
|
||||
desc: "UDP listening port"
|
||||
name: "udp-port" .}: uint16
|
||||
|
||||
listenAddress* {.
|
||||
|
@ -28,32 +28,39 @@ type
|
|||
name: "listen-address" }: ValidIpAddress
|
||||
|
||||
bootnodes* {.
|
||||
desc: "ENR URI of node to bootstrap discovery with. Argument may be repeated."
|
||||
desc: "ENR URI of node to bootstrap discovery with. Argument may be repeated"
|
||||
name: "bootnode" .}: seq[enr.Record]
|
||||
|
||||
nat* {.
|
||||
desc: "Specify method to use for determining public address. " &
|
||||
"Must be one of: any, none, upnp, pmp, extip:<IP>."
|
||||
"Must be one of: any, none, upnp, pmp, extip:<IP>"
|
||||
defaultValue: "any" .}: string
|
||||
|
||||
enrAutoUpdate* {.
|
||||
defaultValue: false
|
||||
desc: "Discovery can automatically update its ENR with the IP address " &
|
||||
"and UDP port as seen by other nodes it communicates with. " &
|
||||
"This option allows to enable/disable this functionality"
|
||||
name: "enr-auto-update" .}: bool
|
||||
|
||||
nodeKey* {.
|
||||
desc: "P2P node private key as hex.",
|
||||
desc: "P2P node private key as hex",
|
||||
defaultValue: PrivateKey.random(keys.newRng()[])
|
||||
name: "nodekey" .}: PrivateKey
|
||||
|
||||
metricsEnabled* {.
|
||||
defaultValue: false
|
||||
desc: "Enable the metrics server."
|
||||
desc: "Enable the metrics server"
|
||||
name: "metrics" .}: bool
|
||||
|
||||
metricsAddress* {.
|
||||
defaultValue: defaultAdminListenAddress(config)
|
||||
desc: "Listening address of the metrics server."
|
||||
desc: "Listening address of the metrics server"
|
||||
name: "metrics-address" .}: ValidIpAddress
|
||||
|
||||
metricsPort* {.
|
||||
defaultValue: 8008
|
||||
desc: "Listening HTTP port of the metrics server."
|
||||
desc: "Listening HTTP port of the metrics server"
|
||||
name: "metrics-port" .}: Port
|
||||
|
||||
case cmd* {.
|
||||
|
@ -163,7 +170,8 @@ proc run(config: DiscoveryConf) =
|
|||
let
|
||||
(ip, tcpPort, udpPort) = setupNat(config)
|
||||
d = newProtocol(config.nodeKey, ip, tcpPort, udpPort,
|
||||
bootstrapRecords = config.bootnodes, bindIp = config.listenAddress)
|
||||
bootstrapRecords = config.bootnodes, bindIp = config.listenAddress,
|
||||
enrAutoUpdate = config.enrAutoUpdate)
|
||||
|
||||
d.open()
|
||||
|
||||
|
|
|
@ -144,7 +144,8 @@ template toFieldPair*(key: string, value: auto): FieldPair =
|
|||
(key, toField(value))
|
||||
|
||||
proc addAddress(fields: var seq[FieldPair], ip: Option[ValidIpAddress],
|
||||
tcpPort, udpPort: Port) =
|
||||
tcpPort, udpPort: Option[Port]) =
|
||||
# It makes sense to add ports only when there is an IP provided
|
||||
if ip.isSome():
|
||||
let
|
||||
ipExt = ip.get()
|
||||
|
@ -152,16 +153,15 @@ proc addAddress(fields: var seq[FieldPair], ip: Option[ValidIpAddress],
|
|||
|
||||
fields.add(if isV6: ("ip6", ipExt.address_v6.toField)
|
||||
else: ("ip", ipExt.address_v4.toField))
|
||||
fields.add(((if isV6: "tcp6" else: "tcp"), tcpPort.uint16.toField))
|
||||
fields.add(((if isV6: "udp6" else: "udp"), udpPort.uint16.toField))
|
||||
else:
|
||||
fields.add(("tcp", tcpPort.uint16.toField))
|
||||
fields.add(("udp", udpPort.uint16.toField))
|
||||
if tcpPort.isSome():
|
||||
fields.add(((if isV6: "tcp6" else: "tcp"), tcpPort.get().uint16.toField))
|
||||
if udpPort.isSome():
|
||||
fields.add(((if isV6: "udp6" else: "udp"), udpPort.get().uint16.toField))
|
||||
|
||||
proc init*(T: type Record, seqNum: uint64,
|
||||
pk: PrivateKey,
|
||||
ip: Option[ValidIpAddress],
|
||||
tcpPort, udpPort: Port,
|
||||
tcpPort, udpPort: Option[Port],
|
||||
extraFields: openarray[FieldPair] = []):
|
||||
EnrResult[T] =
|
||||
## Initialize a `Record` with given sequence number, private key, optional
|
||||
|
@ -281,7 +281,7 @@ proc update*(record: var Record, pk: PrivateKey,
|
|||
|
||||
proc update*(r: var Record, pk: PrivateKey,
|
||||
ip: Option[ValidIpAddress],
|
||||
tcpPort, udpPort: Port,
|
||||
tcpPort, udpPort: Option[Port] = none[Port](),
|
||||
extraFields: openarray[FieldPair] = []):
|
||||
EnrResult[void] =
|
||||
## Update a `Record` with given ip address, tcp port, udp port and optional
|
||||
|
|
|
@ -48,14 +48,20 @@ func newNode*(r: Record): Result[Node, cstring] =
|
|||
ok(Node(id: pk.get().toNodeId(), pubkey: pk.get(), record: r,
|
||||
address: none(Address)))
|
||||
|
||||
proc updateNode*(n: Node, pk: PrivateKey, ip: Option[ValidIpAddress],
|
||||
tcpPort, udpPort: Port, extraFields: openarray[FieldPair] = []):
|
||||
Result[void, cstring] =
|
||||
proc update*(n: Node, pk: PrivateKey, ip: Option[ValidIpAddress],
|
||||
tcpPort, udpPort: Option[Port] = none[Port](),
|
||||
extraFields: openarray[FieldPair] = []): Result[void, cstring] =
|
||||
? n.record.update(pk, ip, tcpPort, udpPort, extraFields)
|
||||
|
||||
if ip.isSome():
|
||||
let a = Address(ip: ip.get(), port: udpPort)
|
||||
n.address = some(a)
|
||||
if udpPort.isSome():
|
||||
let a = Address(ip: ip.get(), port: udpPort.get())
|
||||
n.address = some(a)
|
||||
elif n.address.isSome():
|
||||
let a = Address(ip: ip.get(), port: n.address.get().port)
|
||||
n.address = some(a)
|
||||
else:
|
||||
n.address = none(Address)
|
||||
else:
|
||||
n.address = none(Address)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# nim-eth - Node Discovery Protocol v5
|
||||
# Copyright (c) 2020 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-2021 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, (LICENSE-APACHEv2)
|
||||
# * MIT license (LICENSE-MIT)
|
||||
|
@ -106,6 +106,8 @@ const
|
|||
## refresh the routing table.
|
||||
revalidateMax = 10000 ## Revalidation of a peer is done between 0 and this
|
||||
## value in milliseconds
|
||||
ipMajorityInterval = 5.minutes ## Interval for checking the latest IP:Port
|
||||
## majority and updating this when ENR auto update is set.
|
||||
initialLookups = 1 ## Amount of lookups done when populating the routing table
|
||||
handshakeTimeout* = 2.seconds ## timeout for the reply on the
|
||||
## whoareyou message
|
||||
|
@ -124,9 +126,11 @@ type
|
|||
awaitedMessages: Table[(NodeId, RequestId), Future[Option[Message]]]
|
||||
refreshLoop: Future[void]
|
||||
revalidateLoop: Future[void]
|
||||
ipMajorityLoop: Future[void]
|
||||
lastLookup: chronos.Moment
|
||||
bootstrapRecords*: seq[Record]
|
||||
ipVote: IpVote
|
||||
enrAutoUpdate: bool
|
||||
rng*: ref BrHmacDrbgContext
|
||||
|
||||
PendingRequest = object
|
||||
|
@ -890,21 +894,46 @@ proc refreshLoop(d: Protocol) {.async, raises: [Exception, Defect].} =
|
|||
trace "Discovered nodes in random target query", nodes = randomQuery.len
|
||||
debug "Total nodes in discv5 routing table", total = d.routingTable.len()
|
||||
|
||||
let majority = d.ipVote.majority()
|
||||
if majority.isSome():
|
||||
let address = majority.get()
|
||||
debug "Majority on voted address", address
|
||||
|
||||
await sleepAsync(refreshInterval)
|
||||
except CancelledError:
|
||||
trace "refreshLoop canceled"
|
||||
|
||||
proc ipMajorityLoop(d: Protocol) {.async, raises: [Exception, Defect].} =
|
||||
try:
|
||||
while true:
|
||||
let majority = d.ipVote.majority()
|
||||
if majority.isSome():
|
||||
if d.localNode.address != majority:
|
||||
let address = majority.get()
|
||||
let previous = d.localNode.address
|
||||
if d.enrAutoUpdate:
|
||||
let res = d.localNode.update(d.privateKey,
|
||||
ip = some(address.ip), udpPort = some(address.port))
|
||||
if res.isErr:
|
||||
warn "Failed updating ENR with newly discovered external address",
|
||||
majority, previous, error = res.error
|
||||
else:
|
||||
info "Updated ENR with newly discovered external address",
|
||||
majority, previous, uri = toURI(d.localNode.record)
|
||||
else:
|
||||
warn "Discovered new external address but ENR auto update is off",
|
||||
majority, previous
|
||||
else:
|
||||
debug "Discovered external address matches current address", majority,
|
||||
current = d.localNode.address
|
||||
|
||||
await sleepAsync(ipMajorityInterval)
|
||||
except CancelledError:
|
||||
trace "ipMajorityLoop canceled"
|
||||
|
||||
proc newProtocol*(privKey: PrivateKey,
|
||||
externalIp: Option[ValidIpAddress], tcpPort, udpPort: Port,
|
||||
externalIp: Option[ValidIpAddress],
|
||||
tcpPort, udpPort: Port,
|
||||
localEnrFields: openarray[(string, seq[byte])] = [],
|
||||
bootstrapRecords: openarray[Record] = [],
|
||||
previousRecord = none[enr.Record](),
|
||||
bindIp = IPv4_any(),
|
||||
enrAutoUpdate = false,
|
||||
tableIpLimits = DefaultTableIpLimits,
|
||||
rng = newRng()):
|
||||
Protocol {.raises: [Defect].} =
|
||||
|
@ -920,11 +949,11 @@ proc newProtocol*(privKey: PrivateKey,
|
|||
var record: Record
|
||||
if previousRecord.isSome():
|
||||
record = previousRecord.get()
|
||||
record.update(privKey, externalIp, tcpPort, udpPort,
|
||||
record.update(privKey, externalIp, some(tcpPort), some(udpPort),
|
||||
extraFields).expect("Record within size limits and correct key")
|
||||
else:
|
||||
record = enr.Record.init(1, privKey, externalIp, tcpPort, udpPort,
|
||||
extraFields).expect("Record within size limits")
|
||||
record = enr.Record.init(1, privKey, externalIp, some(tcpPort),
|
||||
some(udpPort), extraFields).expect("Record within size limits")
|
||||
let node = newNode(record).expect("Properly initialized record")
|
||||
|
||||
# TODO Consider whether this should be a Defect
|
||||
|
@ -938,6 +967,7 @@ proc newProtocol*(privKey: PrivateKey,
|
|||
sessions: Sessions.init(256)),
|
||||
bootstrapRecords: @bootstrapRecords,
|
||||
ipVote: IpVote.init(),
|
||||
enrAutoUpdate: enrAutoUpdate,
|
||||
rng: rng)
|
||||
|
||||
result.routingTable.init(node, DefaultBitsPerHop, tableIpLimits, rng)
|
||||
|
@ -959,6 +989,7 @@ proc open*(d: Protocol) {.raises: [Exception, Defect].} =
|
|||
proc start*(d: Protocol) {.raises: [Exception, Defect].} =
|
||||
d.refreshLoop = refreshLoop(d)
|
||||
d.revalidateLoop = revalidateLoop(d)
|
||||
d.ipMajorityLoop = ipMajorityLoop(d)
|
||||
|
||||
proc close*(d: Protocol) {.raises: [Exception, Defect].} =
|
||||
doAssert(not d.transp.closed)
|
||||
|
@ -968,6 +999,8 @@ proc close*(d: Protocol) {.raises: [Exception, Defect].} =
|
|||
d.revalidateLoop.cancel()
|
||||
if not d.refreshLoop.isNil:
|
||||
d.refreshLoop.cancel()
|
||||
if not d.ipMajorityLoop.isNil:
|
||||
d.ipMajorityLoop.cancel()
|
||||
|
||||
d.transp.close()
|
||||
|
||||
|
@ -979,5 +1012,7 @@ proc closeWait*(d: Protocol) {.async, raises: [Exception, Defect].} =
|
|||
await d.revalidateLoop.cancelAndWait()
|
||||
if not d.refreshLoop.isNil:
|
||||
await d.refreshLoop.cancelAndWait()
|
||||
if not d.ipMajorityLoop.isNil:
|
||||
await d.ipMajorityLoop.cancelAndWait()
|
||||
|
||||
await d.transp.closeWait()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import
|
||||
testutils/fuzzing, stew/shims/net, stew/byteutils,
|
||||
eth/p2p/discoveryv5/[encodingv1, enr, sessions, node]
|
||||
eth/p2p/discoveryv5/[encoding, enr, sessions, node]
|
||||
|
||||
init:
|
||||
const
|
||||
|
@ -12,13 +12,13 @@ init:
|
|||
privKeyB = PrivateKey.fromHex(nodeBKey)[] # receive -> decode
|
||||
|
||||
enrRecA = enr.Record.init(1, privKeyA,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
nodeA = newNode(enrRecA).expect("Properly initialized record")
|
||||
|
||||
enrRecB = enr.Record.init(1, privKeyB,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
nodeB = newNode(enrRecB).expect("Properly initialized record")
|
||||
|
||||
var codecB = Codec(localNode: nodeB, privKey: privKeyB,
|
||||
|
|
|
@ -38,7 +38,7 @@ proc generateNode*(privKey: PrivateKey, port: int = 20302,
|
|||
localEnrFields: openarray[FieldPair] = []): Node =
|
||||
let port = Port(port)
|
||||
let enr = enr.Record.init(1, privKey, some(ip),
|
||||
port, port, localEnrFields).expect("Properly intialized private key")
|
||||
some(port), some(port), localEnrFields).expect("Properly intialized private key")
|
||||
result = newNode(enr).expect("Properly initialized node")
|
||||
|
||||
proc nodeAndPrivKeyAtDistance*(n: Node, rng: var BrHmacDrbgContext, d: uint32,
|
||||
|
|
|
@ -463,7 +463,7 @@ procSuite "Discovery v5 Tests":
|
|||
port = Port(9000)
|
||||
fromNoderecord = enr.Record.init(1, PrivateKey.random(rng[]),
|
||||
some(ValidIpAddress.init("11.12.13.14")),
|
||||
port, port)[]
|
||||
some(port), some(port))[]
|
||||
fromNode = newNode(fromNoderecord)[]
|
||||
pk = PrivateKey.random(rng[])
|
||||
targetDistance = logDist(fromNode.id, pk.toPublicKey().toNodeId())
|
||||
|
@ -471,7 +471,8 @@ procSuite "Discovery v5 Tests":
|
|||
block: # Duplicates
|
||||
let
|
||||
record = enr.Record.init(
|
||||
1, pk, some(ValidIpAddress.init("12.13.14.15")), port, port)[]
|
||||
1, pk, some(ValidIpAddress.init("12.13.14.15")),
|
||||
some(port), some(port))[]
|
||||
|
||||
# Exact duplicates
|
||||
var records = @[record, record]
|
||||
|
@ -480,7 +481,8 @@ procSuite "Discovery v5 Tests":
|
|||
|
||||
# Node id duplicates
|
||||
let recordSameId = enr.Record.init(
|
||||
1, pk, some(ValidIpAddress.init("212.13.14.15")), port, port)[]
|
||||
1, pk, some(ValidIpAddress.init("212.13.14.15")),
|
||||
some(port), some(port))[]
|
||||
records.add(recordSameId)
|
||||
nodes = verifyNodesRecords(records, fromNode, targetDistance)
|
||||
check nodes.len == 1
|
||||
|
@ -488,7 +490,7 @@ procSuite "Discovery v5 Tests":
|
|||
block: # No address
|
||||
let
|
||||
recordNoAddress = enr.Record.init(
|
||||
1, pk, none(ValidIpAddress), port, port)[]
|
||||
1, pk, none(ValidIpAddress), some(port), some(port))[]
|
||||
records = [recordNoAddress]
|
||||
test = verifyNodesRecords(records, fromNode, targetDistance)
|
||||
check test.len == 0
|
||||
|
@ -497,7 +499,7 @@ procSuite "Discovery v5 Tests":
|
|||
let
|
||||
recordInvalidAddress = enr.Record.init(
|
||||
1, pk, some(ValidIpAddress.init("10.1.2.3")),
|
||||
port, port)[]
|
||||
some(port), some(port))[]
|
||||
records = [recordInvalidAddress]
|
||||
test = verifyNodesRecords(records, fromNode, targetDistance)
|
||||
check test.len == 0
|
||||
|
@ -505,7 +507,8 @@ procSuite "Discovery v5 Tests":
|
|||
block: # Invalid address - loopback
|
||||
let
|
||||
recordInvalidAddress = enr.Record.init(
|
||||
1, pk, some(ValidIpAddress.init("127.0.0.1")), port, port)[]
|
||||
1, pk, some(ValidIpAddress.init("127.0.0.1")),
|
||||
some(port), some(port))[]
|
||||
records = [recordInvalidAddress]
|
||||
test = verifyNodesRecords(records, fromNode, targetDistance)
|
||||
check test.len == 0
|
||||
|
@ -513,7 +516,8 @@ procSuite "Discovery v5 Tests":
|
|||
block: # Invalid distance
|
||||
let
|
||||
recordInvalidDistance = enr.Record.init(
|
||||
1, pk, some(ValidIpAddress.init("12.13.14.15")), port, port)[]
|
||||
1, pk, some(ValidIpAddress.init("12.13.14.15")),
|
||||
some(port), some(port))[]
|
||||
records = [recordInvalidDistance]
|
||||
test = verifyNodesRecords(records, fromNode, 0'u32)
|
||||
check test.len == 0
|
||||
|
@ -530,8 +534,8 @@ procSuite "Discovery v5 Tests":
|
|||
let
|
||||
privKey = PrivateKey.random(rng[])
|
||||
enrRec = enr.Record.init(1, privKey,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
sendNode = newNode(enrRec).expect("Properly initialized record")
|
||||
var codec = Codec(localNode: sendNode, privKey: privKey, sessions: Sessions.init(5))
|
||||
|
||||
|
@ -559,8 +563,8 @@ procSuite "Discovery v5 Tests":
|
|||
let
|
||||
privKey = PrivateKey.random(rng[])
|
||||
enrRec = enr.Record.init(1, privKey,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
sendNode = newNode(enrRec).expect("Properly initialized record")
|
||||
var codec = Codec(localNode: sendNode, privKey: privKey, sessions: Sessions.init(5))
|
||||
for i in 0 ..< 5:
|
||||
|
@ -590,8 +594,8 @@ procSuite "Discovery v5 Tests":
|
|||
a = localAddress(20303)
|
||||
privKey = PrivateKey.random(rng[])
|
||||
enrRec = enr.Record.init(1, privKey,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
sendNode = newNode(enrRec).expect("Properly initialized record")
|
||||
var codec = Codec(localNode: sendNode, privKey: privKey, sessions: Sessions.init(5))
|
||||
|
||||
|
|
|
@ -219,13 +219,13 @@ suite "Discovery v5.1 Packet Encodings Test Vectors":
|
|||
privKeyB = PrivateKey.fromHex(nodeBKey)[] # receive -> decode
|
||||
|
||||
enrRecA = enr.Record.init(1, privKeyA,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
nodeA = newNode(enrRecA).expect("Properly initialized record")
|
||||
|
||||
enrRecB = enr.Record.init(1, privKeyB,
|
||||
some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
nodeB = newNode(enrRecB).expect("Properly initialized record")
|
||||
|
||||
var
|
||||
|
@ -432,12 +432,14 @@ suite "Discovery v5.1 Additional Encode/Decode":
|
|||
privKeyA = PrivateKey.random(rng[]) # sender -> encode
|
||||
privKeyB = PrivateKey.random(rng[]) # receiver -> decode
|
||||
|
||||
enrRecA = enr.Record.init(1, privKeyA, some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
enrRecA = enr.Record.init(1, privKeyA,
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
nodeA = newNode(enrRecA).expect("Properly initialized record")
|
||||
|
||||
enrRecB = enr.Record.init(1, privKeyB, some(ValidIpAddress.init("127.0.0.1")), Port(9000),
|
||||
Port(9000)).expect("Properly intialized private key")
|
||||
enrRecB = enr.Record.init(1, privKeyB,
|
||||
some(ValidIpAddress.init("127.0.0.1")), some(Port(9000)),
|
||||
some(Port(9000))).expect("Properly intialized private key")
|
||||
nodeB = newNode(enrRecB).expect("Properly initialized record")
|
||||
|
||||
var
|
||||
|
|
|
@ -60,8 +60,9 @@ suite "ENR":
|
|||
let
|
||||
keypair = KeyPair.random(rng[])
|
||||
ip = ValidIpAddress.init("10.20.30.40")
|
||||
port = some(Port(9000))
|
||||
enr = Record.init(
|
||||
100, keypair.seckey, some(ip), Port(9000), Port(9000),@[])[]
|
||||
100, keypair.seckey, some(ip), port, port,@[])[]
|
||||
typedEnr = get enr.toTypedRecord()
|
||||
|
||||
check:
|
||||
|
@ -80,8 +81,9 @@ suite "ENR":
|
|||
test "ENR without address":
|
||||
let
|
||||
keypair = KeyPair.random(rng[])
|
||||
port = some(Port(9000))
|
||||
enr = Record.init(
|
||||
100, keypair.seckey, none(ValidIpAddress), Port(9000), Port(9000))[]
|
||||
100, keypair.seckey, none(ValidIpAddress), port, port)[]
|
||||
typedEnr = get enr.toTypedRecord()
|
||||
|
||||
check:
|
||||
|
@ -89,11 +91,8 @@ suite "ENR":
|
|||
typedEnr.secp256k1.get() == keypair.pubkey.toRawCompressed()
|
||||
|
||||
typedEnr.ip.isNone()
|
||||
typedEnr.tcp.isSome()
|
||||
typedEnr.tcp.get() == 9000
|
||||
|
||||
typedEnr.udp.isSome()
|
||||
typedEnr.udp.get() == 9000
|
||||
typedEnr.tcp.isNone()
|
||||
typedEnr.udp.isNone()
|
||||
|
||||
typedEnr.ip6.isNone()
|
||||
typedEnr.tcp6.isNone()
|
||||
|
@ -115,7 +114,7 @@ suite "ENR":
|
|||
pk = PrivateKey.fromHex(
|
||||
"5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")[]
|
||||
newField = toFieldPair("test", 123'u)
|
||||
var r = Record.init(1, pk, none(ValidIpAddress), Port(9000), Port(9000))[]
|
||||
var r = Record.init(1, pk, none(ValidIpAddress), none(Port), none(Port))[]
|
||||
|
||||
block: # Insert new k:v pair, update of seqNum should occur.
|
||||
let updated = r.update(pk, [newField])
|
||||
|
@ -182,20 +181,63 @@ suite "ENR":
|
|||
let
|
||||
pk = PrivateKey.fromHex(
|
||||
"5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")[]
|
||||
var r = Record.init(1, pk, none(ValidIpAddress), Port(9000), Port(9000))[]
|
||||
var r = Record.init(1, pk, none(ValidIpAddress),
|
||||
some(Port(9000)), some(Port(9000)))[]
|
||||
|
||||
block:
|
||||
let updated = r.update(pk, none(ValidIpAddress), Port(9000), Port(9000))
|
||||
let updated = r.update(pk, none(ValidIpAddress),
|
||||
some(Port(9000)), some(Port(9000)))
|
||||
check updated.isOk()
|
||||
check:
|
||||
r.get("tcp", uint) == 9000
|
||||
r.get("udp", uint) == 9000
|
||||
r.tryGet("ip", uint).isNone()
|
||||
r.tryGet("tcp", uint).isNone()
|
||||
r.tryGet("udp", uint).isNone()
|
||||
r.seqNum == 1
|
||||
|
||||
block:
|
||||
let updated = r.update(pk, none(ValidIpAddress), Port(9001), Port(9002))
|
||||
let updated = r.update(pk, none(ValidIpAddress),
|
||||
some(Port(9001)), some(Port(9002)))
|
||||
check updated.isOk()
|
||||
check:
|
||||
r.get("tcp", uint) == 9001
|
||||
r.get("udp", uint) == 9002
|
||||
r.tryGet("ip", uint).isNone()
|
||||
r.tryGet("tcp", uint).isNone()
|
||||
r.tryGet("udp", uint).isNone()
|
||||
r.seqNum == 1
|
||||
|
||||
block:
|
||||
let updated = r.update(pk, some(ValidIpAddress.init("10.20.30.40")),
|
||||
some(Port(9000)), some(Port(9000)))
|
||||
check updated.isOk()
|
||||
|
||||
let typedEnr = r.toTypedRecord().get()
|
||||
|
||||
check:
|
||||
typedEnr.ip.isSome()
|
||||
typedEnr.ip.get() == [byte 10, 20, 30, 40]
|
||||
|
||||
typedEnr.tcp.isSome()
|
||||
typedEnr.tcp.get() == 9000
|
||||
|
||||
typedEnr.udp.isSome()
|
||||
typedEnr.udp.get() == 9000
|
||||
|
||||
r.seqNum == 2
|
||||
|
||||
block:
|
||||
let updated = r.update(pk, some(ValidIpAddress.init("10.20.30.40")),
|
||||
some(Port(9001)), some(Port(9001)))
|
||||
check updated.isOk()
|
||||
|
||||
let typedEnr = r.toTypedRecord().get()
|
||||
|
||||
check:
|
||||
typedEnr.ip.isSome()
|
||||
typedEnr.ip.get() == [byte 10, 20, 30, 40]
|
||||
|
||||
typedEnr.tcp.isSome()
|
||||
typedEnr.tcp.get() == 9001
|
||||
|
||||
typedEnr.udp.isSome()
|
||||
typedEnr.udp.get() == 9001
|
||||
|
||||
r.seqNum == 3
|
||||
|
|
|
@ -472,8 +472,9 @@ suite "Routing Table Tests":
|
|||
|
||||
let updatedNode1 = generateNode(pk)
|
||||
# Need to do an update to get seqNum increased
|
||||
let updated = updatedNode1.updateNode(pk,
|
||||
some(ValidIpAddress.init("192.168.0.1")), Port(9000), Port(9000))
|
||||
let updated = updatedNode1.update(pk,
|
||||
some(ValidIpAddress.init("192.168.0.1")),
|
||||
some(Port(9000)), some(Port(9000)))
|
||||
check updated.isOk()
|
||||
check table.addNode(updatedNode1) == Existing
|
||||
|
||||
|
@ -524,8 +525,9 @@ suite "Routing Table Tests":
|
|||
|
||||
for i in 0..<DefaultTableIpLimits.bucketIpLimit + 1:
|
||||
# Need to do an update to get seqNum increased
|
||||
let updated = updatedNode1.updateNode(pk,
|
||||
some(ValidIpAddress.init("192.168.0.1")), Port(9000+i), Port(9000+i))
|
||||
let updated = updatedNode1.update(pk,
|
||||
some(ValidIpAddress.init("192.168.0.1")),
|
||||
some(Port(9000+i)), some(Port(9000+i)))
|
||||
check updated.isOk()
|
||||
check table.addNode(updatedNode1) == Existing
|
||||
|
||||
|
|
Loading…
Reference in New Issue