Use results.Opt instead of option in discv5, utp and nat (#705)

+ some other minor cleanups
This commit is contained in:
Kim De Mey 2024-06-18 18:09:27 +02:00 committed by GitHub
parent f169068df6
commit 26212c881b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 265 additions and 258 deletions

View File

@ -1,6 +1,6 @@
#
# Ethereum KeyFile
# (c) Copyright 2018
# (c) Copyright 2018-2024
# Status Research & Development GmbH
#
# Licensed under either of
@ -18,7 +18,7 @@
{.push raises: [].}
import stew/[byteutils, endians2, results]
import stew/[byteutils, endians2], results
from nimcrypto/utils import stripSpaces

View File

@ -1,4 +1,4 @@
# Copyright (c) 2019-2023 Status Research & Development GmbH
# Copyright (c) 2019-2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
@ -9,11 +9,13 @@
{.push raises: [].}
import
std/[options, os, strutils, times],
std/[os, strutils, times],
results, nat_traversal/[miniupnpc, natpmp],
chronicles, json_serialization/std/net, chronos,
../common/utils, ./utils as netutils
export results
type
NatStrategy* = enum
NatAny
@ -47,7 +49,7 @@ logScope:
## Also does threadvar initialisation.
## Must be called before redirectPorts() in each thread.
proc getExternalIP*(natStrategy: NatStrategy, quiet = false): Option[IpAddress] =
proc getExternalIP*(natStrategy: NatStrategy, quiet = false): Opt[IpAddress] =
var externalIP: IpAddress
if natStrategy == NatAny or natStrategy == NatUpnp:
@ -83,7 +85,7 @@ proc getExternalIP*(natStrategy: NatStrategy, quiet = false): Option[IpAddress]
try:
externalIP = parseIpAddress(ires.value)
strategy = NatUpnp
return some(externalIP)
return Opt.some(externalIP)
except ValueError as e:
error "parseIpAddress() exception", err = e.msg
return
@ -102,7 +104,7 @@ proc getExternalIP*(natStrategy: NatStrategy, quiet = false): Option[IpAddress]
try:
externalIP = parseIpAddress($(nires.value))
strategy = NatPmp
return some(externalIP)
return Opt.some(externalIP)
except ValueError as e:
error "parseIpAddress() exception", err = e.msg
return
@ -113,7 +115,7 @@ proc getExternalIP*(natStrategy: NatStrategy, quiet = false): Option[IpAddress]
# Further more, we check if the bind address (user provided, or a "0.0.0.0"
# default) is a public IP. That's a long shot, because code paths involving a
# user-provided bind address are not supposed to get here.
proc getRoutePrefSrc(bindIp: IpAddress): (Option[IpAddress], PrefSrcStatus) =
proc getRoutePrefSrc(bindIp: IpAddress): (Opt[IpAddress], PrefSrcStatus) =
let bindAddress = initTAddress(bindIp, Port(0))
if bindAddress.isAnyLocal():
@ -122,20 +124,20 @@ proc getRoutePrefSrc(bindIp: IpAddress): (Option[IpAddress], PrefSrcStatus) =
# No route was found, log error and continue without IP.
error "No routable IP address found, check your network connection",
error = ip.error
return (none(IpAddress), NoRoutingInfo)
return (Opt.none(IpAddress), NoRoutingInfo)
elif ip.get().isGlobalUnicast():
return (some(ip.get()), PrefSrcIsPublic)
return (Opt.some(ip.get()), PrefSrcIsPublic)
else:
return (none(IpAddress), PrefSrcIsPrivate)
return (Opt.none(IpAddress), PrefSrcIsPrivate)
elif bindAddress.isGlobalUnicast():
return (some(bindIp), BindAddressIsPublic)
return (Opt.some(bindIp), BindAddressIsPublic)
else:
return (none(IpAddress), BindAddressIsPrivate)
return (Opt.none(IpAddress), BindAddressIsPrivate)
# Try to detect a public IP assigned to this host, before trying NAT traversal.
proc getPublicRoutePrefSrcOrExternalIP*(
natStrategy: NatStrategy, bindIp: IpAddress, quiet = true):
Option[IpAddress] =
Opt[IpAddress] =
let (prefSrcIp, prefSrcStatus) = getRoutePrefSrc(bindIp)
case prefSrcStatus:
@ -144,9 +146,9 @@ proc getPublicRoutePrefSrcOrExternalIP*(
of PrefSrcIsPrivate, BindAddressIsPrivate:
let extIp = getExternalIP(natStrategy, quiet)
if extIp.isSome:
return some(extIp.get)
return Opt.some(extIp.get)
proc doPortMapping(tcpPort, udpPort: Port, description: string): Option[(Port, Port)] {.gcsafe.} =
proc doPortMapping(tcpPort, udpPort: Port, description: string): Opt[(Port, Port)] {.gcsafe.} =
var
extTcpPort: Port
extUdpPort: Port
@ -196,7 +198,7 @@ proc doPortMapping(tcpPort, udpPort: Port, description: string): Option[(Port, P
extTcpPort = extPort
of NatPmpProtocol.UDP:
extUdpPort = extPort
return some((extTcpPort, extUdpPort))
return Opt.some((extTcpPort, extUdpPort))
type PortMappingArgs = tuple[tcpPort, udpPort: Port, description: string]
var
@ -274,7 +276,7 @@ proc stopNatThread() {.noconv.} =
else:
debug "NAT-PMP: deleted port mapping", externalPort = eport, internalPort = iport, protocol = protocol
proc redirectPorts*(tcpPort, udpPort: Port, description: string): Option[(Port, Port)] =
proc redirectPorts*(tcpPort, udpPort: Port, description: string): Opt[(Port, Port)] =
result = doPortMapping(tcpPort, udpPort, description)
if result.isSome:
(externalTcpPort, externalUdpPort) = result.get()
@ -294,7 +296,7 @@ proc redirectPorts*(tcpPort, udpPort: Port, description: string): Option[(Port,
proc setupNat*(natStrategy: NatStrategy, tcpPort, udpPort: Port,
clientId: string):
tuple[ip: Option[IpAddress], tcpPort, udpPort: Option[Port]] =
tuple[ip: Opt[IpAddress], tcpPort, udpPort: Opt[Port]] =
## Setup NAT port mapping and get external IP address.
## If any of this fails, we don't return any IP address but do return the
## original ports as best effort.
@ -308,13 +310,13 @@ proc setupNat*(natStrategy: NatStrategy, tcpPort, udpPort: Port,
description = clientId))
if extPorts.isSome:
let (extTcpPort, extUdpPort) = extPorts.get()
(ip: some(ip), tcpPort: some(extTcpPort), udpPort: some(extUdpPort))
(ip: Opt.some(ip), tcpPort: Opt.some(extTcpPort), udpPort: Opt.some(extUdpPort))
else:
warn "UPnP/NAT-PMP available but port forwarding failed"
(ip: none(IpAddress), tcpPort: some(tcpPort), udpPort: some(udpPort))
(ip: Opt.none(IpAddress), tcpPort: Opt.some(tcpPort), udpPort: Opt.some(udpPort))
else:
warn "UPnP/NAT-PMP not available"
(ip: none(IpAddress), tcpPort: some(tcpPort), udpPort: some(udpPort))
(ip: Opt.none(IpAddress), tcpPort: Opt.some(tcpPort), udpPort: Opt.some(udpPort))
type
NatConfig* = object
@ -349,7 +351,7 @@ func completeCmdArg*(T: type NatConfig, val: string): seq[string] =
proc setupAddress*(natConfig: NatConfig, bindIp: IpAddress,
tcpPort, udpPort: Port, clientId: string):
tuple[ip: Option[IpAddress], tcpPort, udpPort: Option[Port]]
tuple[ip: Opt[IpAddress], tcpPort, udpPort: Opt[Port]]
{.gcsafe.} =
## Set-up of the external address via any of the ways as configured in
## `NatConfig`. In case all fails an error is logged and the bind ports are
@ -359,7 +361,7 @@ proc setupAddress*(natConfig: NatConfig, bindIp: IpAddress,
if natConfig.hasExtIp:
# any required port redirection must be done by hand
return (some(natConfig.extIp), some(tcpPort), some(udpPort))
return (Opt.some(natConfig.extIp), Opt.some(tcpPort), Opt.some(udpPort))
case natConfig.nat:
of NatAny:
@ -367,7 +369,7 @@ proc setupAddress*(natConfig: NatConfig, bindIp: IpAddress,
case prefSrcStatus:
of NoRoutingInfo, PrefSrcIsPublic, BindAddressIsPublic:
return (prefSrcIp, some(tcpPort), some(udpPort))
return (prefSrcIp, Opt.some(tcpPort), Opt.some(udpPort))
of PrefSrcIsPrivate, BindAddressIsPrivate:
return setupNat(natConfig.nat, tcpPort, udpPort, clientId)
of NatNone:
@ -375,12 +377,12 @@ proc setupAddress*(natConfig: NatConfig, bindIp: IpAddress,
case prefSrcStatus:
of NoRoutingInfo, PrefSrcIsPublic, BindAddressIsPublic:
return (prefSrcIp, some(tcpPort), some(udpPort))
return (prefSrcIp, Opt.some(tcpPort), Opt.some(udpPort))
of PrefSrcIsPrivate:
error "No public IP address found. Should not use --nat:none option"
return (none(IpAddress), some(tcpPort), some(udpPort))
return (Opt.none(IpAddress), Opt.some(tcpPort), Opt.some(udpPort))
of BindAddressIsPrivate:
error "Bind IP is not a public IP address. Should not use --nat:none option"
return (none(IpAddress), some(tcpPort), some(udpPort))
return (Opt.none(IpAddress), Opt.some(tcpPort), Opt.some(udpPort))
of NatUpnp, NatPmp:
return setupNat(natConfig.nat, tcpPort, udpPort, clientId)

View File

@ -1,6 +1,6 @@
#
# Ethereum P2P
# (c) Copyright 2018-2023
# (c) Copyright 2018-2024
# Status Research & Development GmbH
#
# Licensed under either of
@ -14,7 +14,8 @@
import
nimcrypto/[rijndael, keccak, utils],
stew/[arrayops, byteutils, endians2, objects, results],
stew/[arrayops, byteutils, endians2, objects],
results,
".."/[keys, rlp],
./ecies

View File

@ -1,5 +1,5 @@
# nim-eth
# Copyright (c) 2018-2023 Status Research & Development GmbH
# Copyright (c) 2018-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -10,7 +10,7 @@
import
std/[times, net],
chronos, stint, nimcrypto/keccak, chronicles,
stew/[objects, results],
stew/objects, results,
".."/[keys, rlp],
"."/[kademlia, enode]

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5
# Copyright (c) 2020-2023 Status Research & Development GmbH
# Copyright (c) 2020-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -14,7 +14,7 @@
{.push raises: [].}
import
std/[tables, options, hashes, net],
std/[tables, hashes, net],
nimcrypto/[bcmode, rijndael, sha2], stint, chronicles,
stew/[byteutils, endians2], metrics,
results,
@ -23,7 +23,7 @@ import
from stew/objects import checkedEnumAssign
export keys
export keys, results
declareCounter discovery_session_lru_cache_hits, "Session LRU cache hits"
declareCounter discovery_session_lru_cache_misses, "Session LRU cache misses"
@ -68,7 +68,7 @@ type
Challenge* = object
whoareyouData*: WhoareyouData
pubkey*: Option[PublicKey]
pubkey*: Opt[PublicKey]
StaticHeader* = object
flag: Flag
@ -87,7 +87,7 @@ type
Packet* = object
case flag*: Flag
of OrdinaryMessage:
messageOpt*: Option[Message]
messageOpt*: Opt[Message]
requestNonce*: AESGCMNonce
srcId*: NodeId
of Whoareyou:
@ -163,10 +163,10 @@ proc encryptGCM*(key: AesKey, nonce, pt, authData: openArray[byte]): seq[byte] =
ectx.clear()
proc decryptGCM*(key: AesKey, nonce, ct, authData: openArray[byte]):
Option[seq[byte]] =
Opt[seq[byte]] =
if ct.len <= gcmTagSize:
debug "cipher is missing tag", len = ct.len
return
return Opt.none(seq[byte])
var dctx: GCM[aes128]
dctx.init(key, nonce, authData)
@ -177,9 +177,9 @@ proc decryptGCM*(key: AesKey, nonce, ct, authData: openArray[byte]):
dctx.clear()
if tag != ct.toOpenArray(ct.len - gcmTagSize, ct.high):
return
return Opt.none(seq[byte])
return some(res)
Opt.some(res)
proc encryptHeader*(id: NodeId, iv, header: openArray[byte]): seq[byte] =
var ectx: CTR[aes128]
@ -247,7 +247,7 @@ proc encodeMessagePacket*(rng: var HmacDrbgContext, c: var Codec,
proc encodeWhoareyouPacket*(rng: var HmacDrbgContext, c: var Codec,
toId: NodeId, toAddr: Address, requestNonce: AESGCMNonce, recordSeq: uint64,
pubkey: Option[PublicKey]): seq[byte] =
pubkey: Opt[PublicKey]): seq[byte] =
let
idNonce = rng.generate(IdNonce)
@ -414,7 +414,7 @@ proc decodeMessagePacket(c: var Codec, fromAddr: Address, nonce: AESGCMNonce,
let message = ? decodeMessage(pt.get())
return ok(Packet(flag: Flag.OrdinaryMessage,
messageOpt: some(message), requestNonce: nonce, srcId: srcId))
messageOpt: Opt.some(message), requestNonce: nonce, srcId: srcId))
proc decodeWhoareyouPacket(c: var Codec, nonce: AESGCMNonce,
iv, header, ct: openArray[byte]): DecodeResult[Packet] =
@ -473,13 +473,13 @@ proc decodeHandshakePacket(c: var Codec, fromAddr: Address, nonce: AESGCMNonce,
ephKeyRaw = authdata[ephKeyPos..<ephKeyPos + int(ephKeySize)]
ephKey = ? PublicKey.fromRaw(ephKeyRaw)
var record: Option[enr.Record]
var record: Opt[enr.Record]
let recordPos = ephKeyPos + int(ephKeySize)
if authdata.len() > recordPos:
# There is possibly an ENR still
try:
# Signature check of record happens in decode.
record = some(rlp.decode(authdata.toOpenArray(recordPos, authdata.high),
record = Opt.some(rlp.decode(authdata.toOpenArray(recordPos, authdata.high),
enr.Record))
except RlpError, ValueError:
return err("Invalid encoded ENR")

View File

@ -11,7 +11,7 @@
{.push raises: [].}
import
std/[strutils, macros, algorithm, options, net],
std/[strutils, macros, algorithm, net],
nimcrypto/[keccak, utils],
stew/base64,
results,
@ -38,13 +38,13 @@ type
TypedRecord* = object
id*: string
secp256k1*: Option[array[33, byte]]
ip*: Option[array[4, byte]]
ip6*: Option[array[16, byte]]
tcp*: Option[int]
udp*: Option[int]
tcp6*: Option[int]
udp6*: Option[int]
secp256k1*: Opt[array[33, byte]]
ip*: Opt[array[4, byte]]
ip6*: Opt[array[16, byte]]
tcp*: Opt[int]
udp*: Opt[int]
tcp6*: Opt[int]
udp6*: Opt[int]
FieldKind = enum
kString,
@ -168,8 +168,8 @@ template toFieldPair*(key: string, value: auto): FieldPair =
func addAddress(
fields: var seq[FieldPair],
ip: Option[IpAddress],
tcpPort, udpPort: Option[Port]) =
ip: Opt[IpAddress],
tcpPort, udpPort: Opt[Port]) =
## Add address information in new fields. Incomplete address
## information is allowed (example: Port but not IP) as that information
## might be already in the ENR or added later.
@ -193,8 +193,8 @@ func addAddress(
func init*(
T: type Record,
seqNum: uint64, pk: PrivateKey,
ip: Option[IpAddress],
tcpPort, udpPort: Option[Port],
ip: Opt[IpAddress],
tcpPort, udpPort: Opt[Port],
extraFields: openArray[FieldPair] = []):
EnrResult[T] =
## Initialize a `Record` with given sequence number, private key, optional
@ -260,24 +260,24 @@ func get*(r: Record, key: string, T: type): EnrResult[T] =
else:
err("Key not found in ENR")
func get*(r: Record, T: type PublicKey): Option[T] =
func get*(r: Record, T: type PublicKey): Opt[T] =
## Get the `PublicKey` from provided `Record`. Return `none` when there is
## no `PublicKey` in the record.
var pubkeyField: Field
if r.getField("secp256k1", pubkeyField) and pubkeyField.kind == kBytes:
let pk = PublicKey.fromRaw(pubkeyField.bytes)
if pk.isOk:
return some pk[]
none(T)
return Opt.some(pk[])
Opt.none(T)
func find(r: Record, key: string): Option[int] =
func find(r: Record, key: string): Opt[int] =
## Search for key in record key:value pairs.
##
## Returns some(index of key) if key is found in record. Else return none.
for i, (k, v) in r.pairs:
if k == key:
return some(i)
none(int)
return Opt.some(i)
Opt.none(int)
func update*(
record: var Record, pk: PrivateKey,
@ -324,9 +324,9 @@ func update*(
func update*(
r: var Record,
pk: PrivateKey,
ip: Option[IpAddress],
tcpPort: Option[Port] = none[Port](),
udpPort: Option[Port] = none[Port](),
ip: Opt[IpAddress],
tcpPort: Opt[Port] = Opt.none(Port),
udpPort: Opt[Port] = Opt.none(Port),
extraFields: openArray[FieldPair] = []):
EnrResult[void] =
## Update a `Record` with given ip address, tcp port, udp port and optional
@ -345,15 +345,11 @@ func update*(
fields.add extraFields
r.update(pk, fields)
func tryGet*(r: Record, key: string, T: type): Option[T] =
func tryGet*(r: Record, key: string, T: type): Opt[T] =
## Get the value from the provided key.
## Return `none` if the key does not exist or if the value is invalid
## according to type `T`.
let val = get(r, key, T)
if val.isOk():
some(val.get())
else:
none(T)
get(r, key, T).optValue()
func toTypedRecord*(r: Record): EnrResult[TypedRecord] =
let id = r.tryGet("id", string)

View File

@ -1,5 +1,5 @@
# nim-eth - Node Discovery Protocol v5
# Copyright (c) 2021-2023 Status Research & Development GmbH
# Copyright (c) 2021-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -18,11 +18,12 @@
{.push raises: [].}
import
std/[tables, options],
std/tables,
results,
chronos,
./node
export options
export results
const IpVoteTimeout = 5.minutes ## Duration until a vote expires
@ -45,7 +46,7 @@ proc insert*(ipvote: var IpVote, key: NodeId, address: Address) =
## can only hold 1 vote.
ipvote.votes[key] = (address, now(chronos.Moment) + IpVoteTimeout)
proc majority*(ipvote: var IpVote): Option[Address] =
proc majority*(ipvote: var IpVote): Opt[Address] =
## Get the majority of votes on an address. Pruning of votes older than
## `IpVoteTime` will be done before the majority count.
## Note: When there is a draw the selected "majority" will depend on whichever
@ -66,11 +67,11 @@ proc majority*(ipvote: var IpVote): Option[Address] =
ipvote.votes.del(id)
if ipCount.len <= 0:
return none(Address)
return Opt.none(Address)
let (address, count) = ipCount.largest()
if uint(count) >= ipvote.threshold:
some(address)
Opt.some(address)
else:
none(Address)
Opt.none(Address)

View File

@ -1,5 +1,5 @@
# nim-eth
# Copyright (c) 2020-2023 Status Research & Development GmbH
# Copyright (c) 2020-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -8,7 +8,9 @@
{.push raises: [].}
import std/[tables, lists, options]
import std/[tables, lists], results
export results
type
LRUCache*[K, V] = object of RootObj
@ -19,14 +21,14 @@ type
func init*[K, V](T: type LRUCache[K, V], capacity: int): LRUCache[K, V] =
LRUCache[K, V](capacity: capacity) # Table and list init is done default
func get*[K, V](lru: var LRUCache[K, V], key: K): Option[V] =
func get*[K, V](lru: var LRUCache[K, V], key: K): Opt[V] =
let node = lru.table.getOrDefault(key, nil)
if node.isNil:
return none(V)
return Opt.none(V)
lru.list.remove(node)
lru.list.prepend(node)
return some(node.value[1])
return Opt.some(node.value[1])
func put*[K, V](lru: var LRUCache[K, V], key: K, value: V) =
let node = lru.table.getOrDefault(key, nil)

View File

@ -9,11 +9,11 @@
import
std/[hashes, net],
nimcrypto/keccak, stint, chronos, chronicles,
nimcrypto/keccak, stint, chronos, chronicles, results,
../../keys, ../../net/utils,
./enr
export stint
export stint, results
type
NodeId* = UInt256
@ -25,7 +25,7 @@ type
Node* = ref object
id*: NodeId
pubkey*: PublicKey
address*: Option[Address]
address*: Opt[Address]
record*: Record
seen*: bool ## Indicates if there was at least one successful
## request-response with this node.
@ -52,29 +52,29 @@ func newNode*(r: Record): Result[Node, cstring] =
if tr.ip.isSome() and tr.udp.isSome():
let a = Address(ip: ipv4(tr.ip.get()), port: Port(tr.udp.get()))
ok(Node(id: pk.get().toNodeId(), pubkey: pk.get() , record: r,
address: some(a)))
ok(Node(id: pk.get().toNodeId(), pubkey: pk.get(), record: r,
address: Opt.some(a)))
else:
ok(Node(id: pk.get().toNodeId(), pubkey: pk.get(), record: r,
address: none(Address)))
address: Opt.none(Address)))
func update*(n: Node, pk: PrivateKey, ip: Option[IpAddress],
tcpPort: Option[Port] = none[Port](),
udpPort: Option[Port] = none[Port](),
func update*(n: Node, pk: PrivateKey, ip: Opt[IpAddress],
tcpPort: Opt[Port] = Opt.none(Port),
udpPort: Opt[Port] = Opt.none(Port),
extraFields: openArray[FieldPair] = []): Result[void, cstring] =
? n.record.update(pk, ip, tcpPort, udpPort, extraFields)
if ip.isSome():
if udpPort.isSome():
let a = Address(ip: ip.get(), port: udpPort.get())
n.address = some(a)
n.address = Opt.some(a)
elif n.address.isSome():
let a = Address(ip: ip.get(), port: n.address.get().port)
n.address = some(a)
n.address = Opt.some(a)
else:
n.address = none(Address)
n.address = Opt.none(Address)
else:
n.address = none(Address)
n.address = Opt.none(Address)
ok()

View File

@ -9,7 +9,7 @@
{.push raises: [].}
import
std/[sets, options, net],
std/[sets, net],
results, chronicles, chronos,
../../net/utils,
"."/[node, enr, routing_table]
@ -32,7 +32,7 @@ func validIp(sender, address: IpAddress): bool =
proc verifyNodesRecords(
enrs: openArray[Record], src: Node, nodesLimit: int,
distances: Option[seq[uint16]]): seq[Node] =
distances: Opt[seq[uint16]]): seq[Node] =
## Verify and convert ENRs to a sequence of nodes. Only ENRs that pass
## verification will be added. ENRs are verified for duplicates, invalid
## addresses and invalid distances if those are specified.
@ -86,9 +86,9 @@ proc verifyNodesRecords(
proc verifyNodesRecords*(
enrs: openArray[Record], src: Node, nodesLimit: int): seq[Node] =
verifyNodesRecords(enrs, src, nodesLimit, none[seq[uint16]]())
verifyNodesRecords(enrs, src, nodesLimit, Opt.none(seq[uint16]))
proc verifyNodesRecords*(
enrs: openArray[Record], src: Node, nodesLimit: int,
distances: seq[uint16]): seq[Node] =
verifyNodesRecords(enrs, src, nodesLimit, some[seq[uint16]](distances))
verifyNodesRecords(enrs, src, nodesLimit, Opt.some(distances))

View File

@ -81,7 +81,7 @@
{.push raises: [].}
import
std/[tables, sets, options, math, sequtils, algorithm],
std/[tables, sets, math, sequtils, algorithm],
json_serialization/std/net,
results, chronicles, chronos, stint, metrics,
".."/../[rlp, keys],
@ -89,7 +89,7 @@ import
ip_vote, nodes_verification]
export
options, results, node, enr, encoding.maxDiscv5PacketSize
results, node, enr, encoding.maxDiscv5PacketSize
declareCounter discovery_message_requests_outgoing,
"Discovery protocol outgoing message requests", labels = ["response"]
@ -141,7 +141,7 @@ type
pendingRequests: Table[AESGCMNonce, PendingRequest]
routingTable*: RoutingTable
codec*: Codec
awaitedMessages: Table[(NodeId, RequestId), Future[Option[Message]]]
awaitedMessages: Table[(NodeId, RequestId), Future[Opt[Message]]]
refreshLoop: Future[void]
revalidateLoop: Future[void]
ipMajorityLoop: Future[void]
@ -178,8 +178,8 @@ const
responseTimeout: defaultResponseTimeout
)
chronicles.formatIt(Option[Port]): $it
chronicles.formatIt(Option[IpAddress]): $it
chronicles.formatIt(Opt[Port]): $it
chronicles.formatIt(Opt[IpAddress]): $it
proc addNode*(d: Protocol, node: Node): bool =
## Add `Node` to discovery routing table.
@ -383,9 +383,9 @@ proc handleMessage(
trace "Received unimplemented message kind", kind = message.kind,
origin = fromAddr
else:
var waiter: Future[Option[Message]]
var waiter: Future[Opt[Message]]
if d.awaitedMessages.take((srcId, message.reqId), waiter):
waiter.complete(some(message))
waiter.complete(Opt.some(message))
else:
discovery_unsolicited_messages.inc()
trace "Timed out or unrequested message", kind = message.kind,
@ -404,10 +404,12 @@ proc sendWhoareyou(d: Protocol, toId: NodeId, a: Address,
let key = HandshakeKey(nodeId: toId, address: a)
if not d.codec.hasHandshake(key):
let
recordSeq = if node.isSome(): node.get().record.seqNum
else: 0
pubkey = if node.isSome(): some(node.get().pubkey)
else: none(PublicKey)
recordSeq =
if node.isSome():
node.get().record.seqNum
else:
0
pubkey = node.map(proc(node: Node): PublicKey = node.pubkey)
let data = encodeWhoareyouPacket(d.rng[], d.codec, toId, a, requestNonce,
recordSeq, pubkey)
@ -504,13 +506,13 @@ proc registerRequest(d: Protocol, n: Node, message: seq[byte],
d.pendingRequests.del(nonce)
proc waitMessage(d: Protocol, fromNode: Node, reqId: RequestId):
Future[Option[Message]] {.async: (raw: true, raises: [CancelledError]).} =
let retFuture = Future[Option[Message]].Raising([CancelledError]).init("discv5.waitMessage")
Future[Opt[Message]] {.async: (raw: true, raises: [CancelledError]).} =
let retFuture = Future[Opt[Message]].Raising([CancelledError]).init("discv5.waitMessage")
let key = (fromNode.id, reqId)
sleepAsync(d.responseTimeout).addCallback() do(data: pointer):
d.awaitedMessages.del(key)
if not retFuture.finished:
retFuture.complete(none(Message))
retFuture.complete(Opt.none(Message))
d.awaitedMessages[key] = retFuture
retFuture
@ -881,7 +883,7 @@ proc updateExternalIp*(d: Protocol, extIp: IpAddress, udpPort: Port): bool =
let
previous = d.localNode.address
res = d.localNode.update(d.privateKey,
ip = some(extIp), udpPort = some(udpPort))
ip = Opt.some(extIp), udpPort = Opt.some(udpPort))
if res.isErr:
warn "Failed updating ENR with newly discovered external address",
@ -967,11 +969,11 @@ func init*(
proc newProtocol*(
privKey: PrivateKey,
enrIp: Option[IpAddress],
enrTcpPort, enrUdpPort: Option[Port],
enrIp: Opt[IpAddress],
enrTcpPort, enrUdpPort: Opt[Port],
localEnrFields: openArray[(string, seq[byte])] = [],
bootstrapRecords: openArray[Record] = [],
previousRecord = none[enr.Record](),
previousRecord = Opt.none(enr.Record),
bindPort: Port,
bindIp = IPv4_any(),
enrAutoUpdate = false,
@ -1028,11 +1030,11 @@ proc newProtocol*(
proc newProtocol*(
privKey: PrivateKey,
enrIp: Option[IpAddress],
enrTcpPort, enrUdpPort: Option[Port],
enrIp: Opt[IpAddress],
enrTcpPort, enrUdpPort: Opt[Port],
localEnrFields: openArray[(string, seq[byte])] = [],
bootstrapRecords: openArray[Record] = [],
previousRecord = none[enr.Record](),
previousRecord = Opt.none(enr.Record),
bindPort: Port,
bindIp: Opt[IpAddress],
enrAutoUpdate = false,

View File

@ -12,7 +12,7 @@
{.push raises: [].}
import
std/[options, net],
std/net,
stint, stew/endians2,
node, lru

View File

@ -1,6 +1,6 @@
#
# Ethereum P2P
# (c) Copyright 2018-2023
# (c) Copyright 2018-2024
# Status Research & Development GmbH
#
# Licensed under either of
@ -13,7 +13,7 @@
{.push raises: [].}
import
stew/[results, endians2],
stew/endians2, results,
nimcrypto/[rijndael, bcmode, hash, hmac, sha2, utils],
../keys

View File

@ -51,7 +51,7 @@ type
Packet* = object
header*: PacketHeaderV1
eack*: Option[SelectiveAckExtension]
eack*: Opt[SelectiveAckExtension]
payload*: seq[uint8]
TimeStampInfo* = object
@ -169,7 +169,7 @@ func decodePacket*(bytes: openArray[byte]): Result[Packet, string] =
return ok(Packet(
header: header,
eack: none[SelectiveAckExtension](),
eack: Opt.none(SelectiveAckExtension),
payload: payload))
else:
# packet with the selective ack extension
@ -200,7 +200,7 @@ func decodePacket*(bytes: openArray[byte]): Result[Packet, string] =
else:
bytes[minimalHeaderSizeWithSelectiveAck..^1]
return ok(Packet(header: header, eack: some(extension), payload: payload))
return ok(Packet(header: header, eack: Opt.some(extension), payload: payload))
proc modifyTimeStampAndAckNr*(
packetBytes: var seq[byte], newTimestamp: uint32, newAckNr: uint16) =
@ -229,7 +229,7 @@ proc synPacket*(
ackNr: 0'u16 # At start, no acks have been received
)
Packet(header: h, eack: none[SelectiveAckExtension](), payload: @[])
Packet(header: h, eack: Opt.none(SelectiveAckExtension), payload: @[])
proc ackPacket*(
seqNr: uint16,
@ -237,14 +237,14 @@ proc ackPacket*(
ackNr: uint16,
bufferSize: uint32,
timestampDiff: uint32,
acksBitmask: Option[array[4, byte]] = none[array[4, byte]]()
acksBitmask: Opt[array[4, byte]] = Opt.none(array[4, byte])
): Packet =
let (extensionByte, extensionData) =
if acksBitmask.isSome():
(1'u8, some(SelectiveAckExtension(acks: acksBitmask.unsafeGet())))
(1'u8, Opt.some(SelectiveAckExtension(acks: acksBitmask.unsafeGet())))
else:
(0'u8, none[SelectiveAckExtension]())
(0'u8, Opt.none(SelectiveAckExtension))
let h = PacketHeaderV1(
pType: ST_STATE,
@ -280,7 +280,7 @@ proc dataPacket*(
ackNr: ackNr
)
Packet(header: h, eack: none[SelectiveAckExtension](), payload: payload)
Packet(header: h, eack: Opt.none(SelectiveAckExtension), payload: payload)
proc resetPacket*(
seqNr: uint16, sndConnectionId: uint16, ackNr: uint16): Packet =
@ -298,7 +298,7 @@ proc resetPacket*(
ackNr: ackNr
)
Packet(header: h, eack: none[SelectiveAckExtension](), payload: @[])
Packet(header: h, eack: Opt.none(SelectiveAckExtension), payload: @[])
proc finPacket*(
seqNr: uint16,
@ -319,4 +319,4 @@ proc finPacket*(
ackNr: ackNr
)
Packet(header: h, eack: none[SelectiveAckExtension](), payload: @[])
Packet(header: h, eack: Opt.none(SelectiveAckExtension), payload: @[])

View File

@ -9,11 +9,12 @@
import
std/[hashes, sugar],
chronos, chronicles,
results,
../p2p/discoveryv5/[protocol, messages_encoding, encoding],
./utp_router,
../keys
export utp_router, protocol
export utp_router, protocol, results
logScope:
topics = "eth utp utp_discv5_protocol"
@ -30,7 +31,7 @@ type
proc init*(T: type NodeAddress, nodeId: NodeId, address: Address): NodeAddress =
NodeAddress(nodeId: nodeId, address: address)
proc init*(T: type NodeAddress, node: Node): Option[NodeAddress] =
proc init*(T: type NodeAddress, node: Node): Opt[NodeAddress] =
node.address.map((address: Address) =>
NodeAddress(nodeId: node.id, address: address))

View File

@ -96,7 +96,7 @@ proc new*(
socketConfig: SocketConfig = SocketConfig.init(),
allowConnectionCb: AllowConnectionCallback[TransportAddress] = nil,
sendCallbackBuilder: SendCallbackBuilder = nil,
rng = newRng()): UtpProtocol {.raises: [CatchableError].} =
rng = newRng()): UtpProtocol {.raises: [TransportOsError].} =
doAssert(not(isNil(acceptConnectionCb)))
@ -125,7 +125,7 @@ proc new*(
socketConfig: SocketConfig = SocketConfig.init(),
allowConnectionCb: AllowConnectionCallback[TransportAddress] = nil,
sendCallbackBuilder: SendCallbackBuilder = nil,
rng = newRng()): UtpProtocol {.raises: [CatchableError].} =
rng = newRng()): UtpProtocol {.raises: [TransportOsError].} =
GC_ref(udata)
UtpProtocol.new(
acceptConnectionCb,

View File

@ -7,8 +7,9 @@
{.push raises: [].}
import
std/[tables, options, sugar],
std/tables,
chronos, chronicles, metrics,
results,
../keys,
./utp_socket,
./packets
@ -67,18 +68,18 @@ const
# This should probably be in standard lib, it allows lazy composition of options
# i.e one can write: O1 orElse O2 orElse O3, and chain will be evaluated to
# first option which isSome()
template orElse[A](a: Option[A], b: Option[A]): Option[A] =
template orElse[A](a: Opt[A], b: Opt[A]): Opt[A] =
if (a.isSome()):
a
else:
b
proc getUtpSocket[A](s: UtpRouter[A], k: UtpSocketKey[A]): Option[UtpSocket[A]] =
proc getUtpSocket[A](s: UtpRouter[A], k: UtpSocketKey[A]): Opt[UtpSocket[A]] =
let s = s.sockets.getOrDefault(k)
if s == nil:
none[UtpSocket[A]]()
Opt.none(UtpSocket[A])
else:
some(s)
Opt.some(s)
proc deRegisterUtpSocket[A](s: UtpRouter[A], socket: UtpSocket[A]) =
s.sockets.del(socket.socketKey)
@ -164,7 +165,7 @@ proc getUserData*[A, T](router: UtpRouter[A]): T =
# There are different possibilities on how the connection got established, need
# to check every case.
proc getSocketOnReset[A](
r: UtpRouter[A], sender: A, id: uint16): Option[UtpSocket[A]] =
r: UtpRouter[A], sender: A, id: uint16): Opt[UtpSocket[A]] =
# id is our recv id
let recvKey = UtpSocketKey[A].init(sender, id)
@ -176,8 +177,8 @@ proc getSocketOnReset[A](
let sendNoInitKey = UtpSocketKey[A].init(sender, id + 1)
r.getUtpSocket(recvKey)
.orElse(r.getUtpSocket(sendInitKey).filter(s => s.connectionIdSnd == id))
.orElse(r.getUtpSocket(sendNoInitKey).filter(s => s.connectionIdSnd == id))
.orElse(r.getUtpSocket(sendInitKey).filter(proc(s: UtpSocket[A]): bool = s.connectionIdSnd == id))
.orElse(r.getUtpSocket(sendNoInitKey).filter(proc(s: UtpSocket[A]): bool = s.connectionIdSnd == id))
proc shouldAllowConnection[A](
r: UtpRouter[A], remoteAddress: A, connectionId: uint16): bool =

View File

@ -78,6 +78,8 @@ type
# to move the socket in `Connected` state.
# If set to none, the incoming socket will immediately be set to `Connected`
# state and will be able to transfer data.
# TODO: Move to Opt but need to figure out current compile error:
# cannot instantiate: 'Opt[T]'; Maybe generic arguments are missing
incomingSocketReceiveTimeout*: Option[Duration]
# Timeout after which the send window will be reset to its minimal value
@ -260,7 +262,7 @@ type
eventLoop: Future[void]
# timer which is started when peer max window drops below current packet size
zeroWindowTimer: Option[Moment]
zeroWindowTimer: Opt[Moment]
# last measured delay between current local timestamp and remote sent
# timestamp, in microseconds.
@ -552,7 +554,7 @@ proc checkTimeouts(socket: UtpSocket) =
let remoteWindow = 2 * socket.socketConfig.payloadSize
socket.maxRemoteWindow = remoteWindow
debug "Reset remote window to minimal value", remoteWindow
socket.zeroWindowTimer = none[Moment]()
socket.zeroWindowTimer = Opt.none(Moment)
if (currentTime > socket.rtoTimeout):
debug "CheckTimeouts rto timeout",
@ -1086,9 +1088,9 @@ proc generateSelectiveAckBitMask*(socket: UtpSocket): array[4, byte] =
proc generateAckPacket*(socket: UtpSocket): Packet =
let bitmask =
if (socket.reorderCount != 0 and (not socket.reachedFin)):
some(socket.generateSelectiveAckBitMask())
Opt.some(socket.generateSelectiveAckBitMask())
else:
none[array[4, byte]]()
Opt.none(array[4, byte])
let bufferSize = socket.getRcvWindowSize()
@ -1319,7 +1321,7 @@ proc processPacketInternal(socket: UtpSocket, p: Packet) =
# when zeroWindowTimer is hit and maxRemoteWindow still is equal
# to 0 then it will be reset to the minimal value
socket.zeroWindowTimer =
some(timestampInfo.moment + socket.socketConfig.remoteWindowResetTimeout)
Opt.some(timestampInfo.moment + socket.socketConfig.remoteWindowResetTimeout)
debug "Remote window size dropped below packet size",
currentTime = timestampInfo.moment,
@ -1988,7 +1990,7 @@ proc new[A](
closeCallbacks: newSeq[Future[void]](),
pendingWrites: initDeque[WriteRequest](),
eventQueue: newAsyncQueue[SocketEvent](),
zeroWindowTimer: none[Moment](),
zeroWindowTimer: Opt.none(Moment),
socketKey: UtpSocketKey.init(to, rcvId),
slowStart: true,
fastTimeout: false,

View File

@ -13,13 +13,13 @@ init:
privKeyB = PrivateKey.fromHex(nodeBKey)[] # receive -> decode
enrRecA = enr.Record.init(1, privKeyA,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
nodeA = newNode(enrRecA).expect("Properly initialized record")
enrRecB = enr.Record.init(1, privKeyB,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
nodeB = newNode(enrRecB).expect("Properly initialized record")
var codecB = Codec(localNode: nodeB, privKey: privKeyB,

View File

@ -10,8 +10,8 @@ proc generate() =
let
rng = newRng()
privKey = PrivateKey.random(rng[])
ip = some(parseIpAddress("127.0.0.1"))
port = some(Port(20301))
ip = Opt.some(parseIpAddress("127.0.0.1"))
port = Opt.some(Port(20301))
block:
let record = enr.Record.init(1, privKey, ip, port, port)[]

View File

@ -23,15 +23,15 @@ proc initDiscoveryNode*(
address: Address,
bootstrapRecords: openArray[Record] = [],
localEnrFields: openArray[(string, seq[byte])] = [],
previousRecord = none[enr.Record]()):
previousRecord = Opt.none(enr.Record)):
discv5_protocol.Protocol =
# set bucketIpLimit to allow bucket split
let config = DiscoveryConfig.init(1000, 24, 5)
let protocol = newProtocol(
privKey,
some(address.ip),
some(address.port), some(address.port),
Opt.some(address.ip),
Opt.some(address.port), Opt.some(address.port),
bindPort = address.port,
bootstrapRecords = bootstrapRecords,
localEnrFields = localEnrFields,
@ -51,8 +51,8 @@ func generateNode*(privKey: PrivateKey, port: int = 20302,
ip: IpAddress = parseIpAddress("127.0.0.1"),
localEnrFields: openArray[FieldPair] = []): Node =
let port = Port(port)
let enr = enr.Record.init(1, privKey, some(ip),
some(port), some(port), localEnrFields).expect("Properly initialized private key")
let enr = enr.Record.init(1, privKey, Opt.some(ip),
Opt.some(port), Opt.some(port), localEnrFields).expect("Properly initialized private key")
result = newNode(enr).expect("Properly initialized node")
proc generateNRandomNodes*(rng: var HmacDrbgContext, n: int): seq[Node] =

View File

@ -423,18 +423,18 @@ suite "Discovery v5 Tests":
test "New protocol with enr":
let
privKey = PrivateKey.random(rng[])
ip = some(parseIpAddress("127.0.0.1"))
ip = Opt.some(parseIpAddress("127.0.0.1"))
port = Port(20301)
node = newProtocol(privKey, ip, some(port), some(port), bindPort = port,
node = newProtocol(privKey, ip, Opt.some(port), Opt.some(port), bindPort = port,
rng = rng)
noUpdatesNode = newProtocol(privKey, ip, some(port), some(port),
bindPort = port, rng = rng, previousRecord = some(node.getRecord()))
updatesNode = newProtocol(privKey, ip, some(port), some(Port(20302)),
noUpdatesNode = newProtocol(privKey, ip, Opt.some(port), Opt.some(port),
bindPort = port, rng = rng, previousRecord = Opt.some(node.getRecord()))
updatesNode = newProtocol(privKey, ip, Opt.some(port), Opt.some(Port(20302)),
bindPort = port, rng = rng,
previousRecord = some(noUpdatesNode.getRecord()))
moreUpdatesNode = newProtocol(privKey, ip, some(port), some(port),
previousRecord = Opt.some(noUpdatesNode.getRecord()))
moreUpdatesNode = newProtocol(privKey, ip, Opt.some(port), Opt.some(port),
bindPort = port, rng = rng, localEnrFields = {"addfield": @[byte 0]},
previousRecord = some(updatesNode.getRecord()))
previousRecord = Opt.some(updatesNode.getRecord()))
check:
node.getRecord().seqNum == 1
noUpdatesNode.getRecord().seqNum == 1
@ -444,8 +444,8 @@ suite "Discovery v5 Tests":
# Defect (for now?) on incorrect key use
expect ResultDefect:
let incorrectKeyUpdates = newProtocol(PrivateKey.random(rng[]),
ip, some(port), some(port), bindPort = port, rng = rng,
previousRecord = some(updatesNode.getRecord()))
ip, Opt.some(port), Opt.some(port), bindPort = port, rng = rng,
previousRecord = Opt.some(updatesNode.getRecord()))
asyncTest "Update node record with revalidate":
let
@ -518,8 +518,8 @@ suite "Discovery v5 Tests":
let
port = Port(9000)
srcRecord = enr.Record.init(1, PrivateKey.random(rng[]),
some(parseIpAddress("11.12.13.14")),
some(port), some(port))[]
Opt.some(parseIpAddress("11.12.13.14")),
Opt.some(port), Opt.some(port))[]
srcNode = newNode(srcRecord)[]
pk = PrivateKey.random(rng[])
targetDistance = @[logDistance(srcNode.id, pk.toPublicKey().toNodeId())]
@ -528,8 +528,8 @@ suite "Discovery v5 Tests":
block: # Duplicates
let
record = enr.Record.init(
1, pk, some(parseIpAddress("12.13.14.15")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("12.13.14.15")),
Opt.some(port), Opt.some(port))[]
# Exact duplicates
var records = @[record, record]
@ -538,8 +538,8 @@ suite "Discovery v5 Tests":
# Node id duplicates
let recordSameId = enr.Record.init(
1, pk, some(parseIpAddress("212.13.14.15")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("212.13.14.15")),
Opt.some(port), Opt.some(port))[]
records.add(recordSameId)
nodes = verifyNodesRecords(records, srcNode, limit, targetDistance)
check nodes.len == 1
@ -547,7 +547,7 @@ suite "Discovery v5 Tests":
block: # No address
let
recordNoAddress = enr.Record.init(
1, pk, none(IpAddress), some(port), some(port))[]
1, pk, Opt.none(IpAddress), Opt.some(port), Opt.some(port))[]
records = [recordNoAddress]
test = verifyNodesRecords(records, srcNode, limit, targetDistance)
check test.len == 0
@ -555,8 +555,8 @@ suite "Discovery v5 Tests":
block: # Invalid address - any local
let
recordInvalidAddress = enr.Record.init(
1, pk, some(parseIpAddress("0.0.0.0")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("0.0.0.0")),
Opt.some(port), Opt.some(port))[]
records = [recordInvalidAddress]
test = verifyNodesRecords(records, srcNode, limit, targetDistance)
check test.len == 0
@ -564,8 +564,8 @@ suite "Discovery v5 Tests":
block: # Invalid address - site local
let
recordInvalidAddress = enr.Record.init(
1, pk, some(parseIpAddress("10.1.2.3")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("10.1.2.3")),
Opt.some(port), Opt.some(port))[]
records = [recordInvalidAddress]
test = verifyNodesRecords(records, srcNode, limit, targetDistance)
check test.len == 0
@ -573,8 +573,8 @@ suite "Discovery v5 Tests":
block: # Invalid address - loopback
let
recordInvalidAddress = enr.Record.init(
1, pk, some(parseIpAddress("127.0.0.1")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("127.0.0.1")),
Opt.some(port), Opt.some(port))[]
records = [recordInvalidAddress]
test = verifyNodesRecords(records, srcNode, limit, targetDistance)
check test.len == 0
@ -582,8 +582,8 @@ suite "Discovery v5 Tests":
block: # Invalid distance
let
recordInvalidDistance = enr.Record.init(
1, pk, some(parseIpAddress("12.13.14.15")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("12.13.14.15")),
Opt.some(port), Opt.some(port))[]
records = [recordInvalidDistance]
test = verifyNodesRecords(records, srcNode, limit, @[0'u16])
check test.len == 0
@ -591,8 +591,8 @@ suite "Discovery v5 Tests":
block: # Invalid distance but distance validation is disabled
let
recordInvalidDistance = enr.Record.init(
1, pk, some(parseIpAddress("12.13.14.15")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("12.13.14.15")),
Opt.some(port), Opt.some(port))[]
records = [recordInvalidDistance]
test = verifyNodesRecords(records, srcNode, limit)
check test.len == 1
@ -601,8 +601,8 @@ suite "Discovery v5 Tests":
let
port = Port(9000)
srcRecord = enr.Record.init(1, PrivateKey.random(rng[]),
some(parseIpAddress("127.0.0.0")),
some(port), some(port))[]
Opt.some(parseIpAddress("127.0.0.0")),
Opt.some(port), Opt.some(port))[]
srcNode = newNode(srcRecord)[]
pk = PrivateKey.random(rng[])
targetDistance = @[logDistance(srcNode.id, pk.toPublicKey().toNodeId())]
@ -611,16 +611,16 @@ suite "Discovery v5 Tests":
block: # valid address - lo with lo src
let
record = enr.Record.init(
1, pk, some(parseIpAddress("127.0.0.1")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("127.0.0.1")),
Opt.some(port), Opt.some(port))[]
test = verifyNodesRecords([record], srcNode, limit, targetDistance)
check test.len == 1
block: # valid address - global with lo src
let
record = enr.Record.init(
1, pk, some(parseIpAddress("1.2.3.4")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("1.2.3.4")),
Opt.some(port), Opt.some(port))[]
test = verifyNodesRecords([record], srcNode, limit, targetDistance)
check test.len == 1
@ -628,8 +628,8 @@ suite "Discovery v5 Tests":
let
port = Port(9000)
srcRecord = enr.Record.init(1, PrivateKey.random(rng[]),
some(parseIpAddress("192.168.1.1")),
some(port), some(port))[]
Opt.some(parseIpAddress("192.168.1.1")),
Opt.some(port), Opt.some(port))[]
srcNode = newNode(srcRecord)[]
pk = PrivateKey.random(rng[])
targetDistance = @[logDistance(srcNode.id, pk.toPublicKey().toNodeId())]
@ -638,16 +638,16 @@ suite "Discovery v5 Tests":
block: # valid address - site local with site local src
let
record = enr.Record.init(
1, pk, some(parseIpAddress("192.168.1.2")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("192.168.1.2")),
Opt.some(port), Opt.some(port))[]
test = verifyNodesRecords([record], srcNode, limit, targetDistance)
check test.len == 1
block: # valid address - global with site local src
let
record = enr.Record.init(
1, pk, some(parseIpAddress("1.2.3.4")),
some(port), some(port))[]
1, pk, Opt.some(parseIpAddress("1.2.3.4")),
Opt.some(port), Opt.some(port))[]
test = verifyNodesRecords([record], srcNode, limit, targetDistance)
check test.len == 1
@ -691,8 +691,8 @@ suite "Discovery v5 Tests":
let
privKey = PrivateKey.random(rng[])
enrRec = enr.Record.init(1, privKey,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
sendNode = newNode(enrRec).expect("Properly initialized record")
var codec = Codec(localNode: sendNode, privKey: privKey, sessions: Sessions.init(5))
@ -720,8 +720,8 @@ suite "Discovery v5 Tests":
let
privKey = PrivateKey.random(rng[])
enrRec = enr.Record.init(1, privKey,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized 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:
@ -751,8 +751,8 @@ suite "Discovery v5 Tests":
a = localAddress(20303)
privKey = PrivateKey.random(rng[])
enrRec = enr.Record.init(1, privKey,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
sendNode = newNode(enrRec).expect("Properly initialized record")
var codec = Codec(localNode: sendNode, privKey: privKey, sessions: Sessions.init(5))

View File

@ -265,13 +265,13 @@ suite "Discovery v5.1 Packet Encodings Test Vectors":
privKeyB = PrivateKey.fromHex(nodeBKey)[] # receive -> decode
enrRecA = enr.Record.init(1, privKeyA,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
nodeA = newNode(enrRecA).expect("Properly initialized record")
enrRecB = enr.Record.init(1, privKeyB,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
nodeB = newNode(enrRecB).expect("Properly initialized record")
var
@ -358,7 +358,7 @@ suite "Discovery v5.1 Packet Encodings Test Vectors":
idNonce: hexToByteArray[idNonceSize](whoareyouIdNonce),
recordSeq: whoareyouEnrSeq,
challengeData: hexToSeqByte(whoareyouChallengeData))
pubkey = some(privKeyA.toPublicKey())
pubkey = Opt.some(privKeyA.toPublicKey())
challenge = Challenge(whoareyouData: whoareyouData, pubkey: pubkey)
key = HandshakeKey(nodeId: nodeA.id, address: nodeA.address.get())
@ -408,7 +408,7 @@ suite "Discovery v5.1 Packet Encodings Test Vectors":
idNonce: hexToByteArray[idNonceSize](whoareyouIdNonce),
recordSeq: whoareyouEnrSeq,
challengeData: hexToSeqByte(whoareyouChallengeData))
pubkey = none(PublicKey)
pubkey = Opt.none(PublicKey)
challenge = Challenge(whoareyouData: whoareyouData, pubkey: pubkey)
key = HandshakeKey(nodeId: nodeA.id, address: nodeA.address.get())
@ -486,13 +486,13 @@ suite "Discovery v5.1 Additional Encode/Decode":
privKeyB = PrivateKey.random(rng[]) # receiver -> decode
enrRecA = enr.Record.init(1, privKeyA,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
nodeA = newNode(enrRecA).expect("Properly initialized record")
enrRecB = enr.Record.init(1, privKeyB,
some(parseIpAddress("127.0.0.1")), some(Port(9000)),
some(Port(9000))).expect("Properly initialized private key")
Opt.some(parseIpAddress("127.0.0.1")), Opt.some(Port(9000)),
Opt.some(Port(9000))).expect("Properly initialized private key")
nodeB = newNode(enrRecB).expect("Properly initialized record")
var
@ -520,7 +520,7 @@ suite "Discovery v5.1 Additional Encode/Decode":
let recordSeq = 0'u64
let data = encodeWhoareyouPacket(rng[], codecA, nodeB.id,
nodeB.address.get(), requestNonce, recordSeq, none(PublicKey))
nodeB.address.get(), requestNonce, recordSeq, Opt.none(PublicKey))
let decoded = codecB.decodePacket(nodeA.address.get(), data)
@ -542,7 +542,7 @@ suite "Discovery v5.1 Additional Encode/Decode":
m = PingMessage(enrSeq: 0)
reqId = RequestId.init(rng[])
message = encodeMessage(m, reqId)
pubkey = some(privKeyA.toPublicKey())
pubkey = Opt.some(privKeyA.toPublicKey())
# Encode/decode whoareyou packet to get the handshake stored and the
# whoareyou data returned. It's either that or construct the header for the
@ -572,7 +572,7 @@ suite "Discovery v5.1 Additional Encode/Decode":
m = PingMessage(enrSeq: 0)
reqId = RequestId.init(rng[])
message = encodeMessage(m, reqId)
pubkey = none(PublicKey)
pubkey = Opt.none(PublicKey)
# Encode/decode whoareyou packet to get the handshake stored and the
# whoareyou data returned. It's either that or construct the header for the

View File

@ -7,7 +7,7 @@
{.used.}
import
std/[options, sequtils, net],
std/[sequtils, net],
unittest2,
../../eth/p2p/discoveryv5/enr, ../../eth/[keys, rlp]
@ -68,9 +68,9 @@ suite "ENR":
let
keypair = KeyPair.random(rng[])
ip = parseIpAddress("10.20.30.40")
port = some(Port(9000))
port = Opt.some(Port(9000))
enr = Record.init(
100, keypair.seckey, some(ip), port, port,@[])[]
100, keypair.seckey, Opt.some(ip), port, port,@[])[]
typedEnr = get enr.toTypedRecord()
check:
@ -89,9 +89,9 @@ suite "ENR":
test "ENR without address":
let
keypair = KeyPair.random(rng[])
port = none(Port)
port = Opt.none(Port)
enr = Record.init(
100, keypair.seckey, none(IpAddress), port, port)[]
100, keypair.seckey, Opt.none(IpAddress), port, port)[]
typedEnr = get enr.toTypedRecord()
check:
@ -122,7 +122,7 @@ suite "ENR":
pk = PrivateKey.fromHex(
"5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")[]
newField = toFieldPair("test", 123'u)
var r = Record.init(1, pk, none(IpAddress), none(Port), none(Port))[]
var r = Record.init(1, pk, Opt.none(IpAddress), Opt.none(Port), Opt.none(Port))[]
block: # Insert new k:v pair, update of seqNum should occur.
let updated = r.update(pk, [newField])
@ -189,12 +189,12 @@ suite "ENR":
let
pk = PrivateKey.fromHex(
"5d2908f3f09ea1ff2e327c3f623159639b00af406e9009de5fd4b910fc34049d")[]
var r = Record.init(1, pk, none(IpAddress),
some(Port(9000)), some(Port(9000)))[]
var r = Record.init(1, pk, Opt.none(IpAddress),
Opt.some(Port(9000)), Opt.some(Port(9000)))[]
block:
let updated = r.update(pk, none(IpAddress),
some(Port(9000)), some(Port(9000)))
let updated = r.update(pk, Opt.none(IpAddress),
Opt.some(Port(9000)), Opt.some(Port(9000)))
check updated.isOk()
check:
r.tryGet("ip", uint).isNone()
@ -203,8 +203,8 @@ suite "ENR":
r.seqNum == 1
block:
let updated = r.update(pk, none(IpAddress),
some(Port(9001)), some(Port(9002)))
let updated = r.update(pk, Opt.none(IpAddress),
Opt.some(Port(9001)), Opt.some(Port(9002)))
check updated.isOk()
check:
r.tryGet("ip", uint).isNone()
@ -213,8 +213,8 @@ suite "ENR":
r.seqNum == 2
block:
let updated = r.update(pk, some(parseIpAddress("10.20.30.40")),
some(Port(9000)), some(Port(9000)))
let updated = r.update(pk, Opt.some(parseIpAddress("10.20.30.40")),
Opt.some(Port(9000)), Opt.some(Port(9000)))
check updated.isOk()
let typedEnr = r.toTypedRecord().get()
@ -232,8 +232,8 @@ suite "ENR":
r.seqNum == 3
block:
let updated = r.update(pk, some(parseIpAddress("10.20.30.40")),
some(Port(9001)), some(Port(9001)))
let updated = r.update(pk, Opt.some(parseIpAddress("10.20.30.40")),
Opt.some(Port(9001)), Opt.some(Port(9001)))
check updated.isOk()
let typedEnr = r.toTypedRecord().get()

View File

@ -31,7 +31,7 @@ suite "IP vote":
votes.insert(NodeId.random(rng[]), addr3);
votes.insert(NodeId.random(rng[]), addr3);
check votes.majority() == some(addr2)
check votes.majority() == Opt.some(addr2)
test "Votes below threshold":
const threshold = 10
@ -67,7 +67,7 @@ suite "IP vote":
for i in 0..<(threshold):
votes.insert(NodeId.random(rng[]), addr3);
check votes.majority() == some(addr3)
check votes.majority() == Opt.some(addr3)
test "Double votes with same address":
const threshold = 2
@ -85,7 +85,7 @@ suite "IP vote":
votes.insert(NodeId.random(rng[]), addr2);
votes.insert(NodeId.random(rng[]), addr2);
check votes.majority() == some(addr2)
check votes.majority() == Opt.some(addr2)
test "Double votes with different address":
const threshold = 2
@ -105,4 +105,4 @@ suite "IP vote":
votes.insert(NodeId.random(rng[]), addr2);
votes.insert(NodeId.random(rng[]), addr3);
check votes.majority() == some(addr3)
check votes.majority() == Opt.some(addr3)

View File

@ -460,8 +460,8 @@ suite "Routing Table Tests":
let updatedNode1 = generateNode(pk)
# Need to do an update to get seqNum increased
let updated = updatedNode1.update(pk,
some(parseIpAddress("192.168.0.1")),
some(Port(9000)), some(Port(9000)))
Opt.some(parseIpAddress("192.168.0.1")),
Opt.some(Port(9000)), Opt.some(Port(9000)))
check updated.isOk()
check table.addNode(updatedNode1) == Existing
@ -509,8 +509,8 @@ suite "Routing Table Tests":
for i in 0..<DefaultTableIpLimits.bucketIpLimit + 1:
# Need to do an update to get seqNum increased
let updated = updatedNode1.update(pk,
some(parseIpAddress("192.168.0.1")),
some(Port(9000+i)), some(Port(9000+i)))
Opt.some(parseIpAddress("192.168.0.1")),
Opt.some(Port(9000+i)), Opt.some(Port(9000+i)))
check updated.isOk()
check table.addNode(updatedNode1) == Existing

View File

@ -1,4 +1,4 @@
# Copyright (c) 2020-2023 Status Research & Development GmbH
# Copyright (c) 2020-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -72,7 +72,7 @@ suite "uTP packet encoding":
test "Encode/decode ACK packet: with extensions":
let
bitMask: array[4, byte] = [1'u8, 2, 3, 4]
ackPacket = ackPacket(5, 10, 20, 30, 40, some(bitMask))
ackPacket = ackPacket(5, 10, 20, 30, 40, Opt.some(bitMask))
encoded = encodePacket(ackPacket)
decoded = decodePacket(encoded)
@ -88,7 +88,7 @@ suite "uTP packet encoding":
test "Fail to decode packet with malformed extensions":
let bitMask: array[4, byte] = [1'u8, 2, 3, 4]
let ackPacket = ackPacket(5, 10, 20, 30, 40, some(bitMask))
let ackPacket = ackPacket(5, 10, 20, 30, 40, Opt.some(bitMask))
block: # nextExtension to non zero
var encoded = encodePacket(ackPacket)

View File

@ -1,4 +1,4 @@
# Copyright (c) 2020-2021 Status Research & Development GmbH
# Copyright (c) 2020-2024 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@ -7,7 +7,6 @@
{.used.}
import
std/options,
stew/byteutils,
unittest2,
../../eth/utp/packets,
@ -27,7 +26,7 @@ suite "uTP packets test vectors":
seqNr: 11884,
ackNr: 0
),
eack: none[SelectiveAckExtension](),
eack: Opt.none(SelectiveAckExtension),
payload: @[]
)
@ -51,7 +50,7 @@ suite "uTP packets test vectors":
seqNr: 16807,
ackNr: 11885
),
eack: none[SelectiveAckExtension](),
eack: Opt.none(SelectiveAckExtension),
payload: @[]
)
@ -78,7 +77,7 @@ suite "uTP packets test vectors":
seqNr: 16807,
ackNr: 11885
),
eack: some(SelectiveAckExtension(
eack: Opt.some(SelectiveAckExtension(
acks: bitMask
)),
payload: @[]
@ -104,7 +103,7 @@ suite "uTP packets test vectors":
seqNr: 8334,
ackNr: 16806
),
eack: none[SelectiveAckExtension](),
eack: Opt.none(SelectiveAckExtension),
payload: @[0'u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]
)
@ -128,7 +127,7 @@ suite "uTP packets test vectors":
seqNr: 41050,
ackNr: 16806
),
eack: none[SelectiveAckExtension](),
eack: Opt.none(SelectiveAckExtension),
payload: @[]
)
@ -152,7 +151,7 @@ suite "uTP packets test vectors":
seqNr: 55413,
ackNr: 16807
),
eack: none[SelectiveAckExtension](),
eack: Opt.none(SelectiveAckExtension),
payload: @[]
)

View File

@ -211,7 +211,7 @@ proc run(config: DiscoveryConf) {.raises: [CatchableError].} =
config.listenAddress, udpPort, udpPort, "dcli")
let d = newProtocol(config.nodeKey,
extIp, none(Port), extUdpPort,
extIp, Opt.none(Port), extUdpPort,
bootstrapRecords = config.bootnodes,
bindIp = bindIp, bindPort = udpPort,
enrAutoUpdate = config.enrAutoUpdate)