2024-01-24 08:09:11 +00:00
|
|
|
# nim-eth
|
|
|
|
# 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).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2020-06-17 11:51:30 +00:00
|
|
|
import
|
2024-01-24 08:09:11 +00:00
|
|
|
std/net,
|
|
|
|
chronos,
|
2021-04-06 11:33:24 +00:00
|
|
|
../../eth/keys,
|
|
|
|
../../eth/p2p/discoveryv5/[enr, node, routing_table],
|
|
|
|
../../eth/p2p/discoveryv5/protocol as discv5_protocol
|
2020-06-17 11:51:30 +00:00
|
|
|
|
2020-11-26 17:20:15 +00:00
|
|
|
export net
|
|
|
|
|
2023-11-10 06:28:21 +00:00
|
|
|
func localAddress*(port: int): Address =
|
|
|
|
Address(ip: parseIpAddress("127.0.0.1"), port: Port(port))
|
2020-06-17 11:51:30 +00:00
|
|
|
|
2022-02-02 14:29:45 +00:00
|
|
|
proc initDiscoveryNode*(
|
2022-06-17 20:45:37 +00:00
|
|
|
rng: ref HmacDrbgContext,
|
2022-02-02 14:29:45 +00:00
|
|
|
privKey: PrivateKey,
|
|
|
|
address: Address,
|
|
|
|
bootstrapRecords: openArray[Record] = [],
|
|
|
|
localEnrFields: openArray[(string, seq[byte])] = [],
|
2024-06-18 16:09:27 +00:00
|
|
|
previousRecord = Opt.none(enr.Record)):
|
2022-02-02 14:29:45 +00:00
|
|
|
discv5_protocol.Protocol =
|
2020-11-26 17:20:15 +00:00
|
|
|
# set bucketIpLimit to allow bucket split
|
2022-02-02 14:29:45 +00:00
|
|
|
let config = DiscoveryConfig.init(1000, 24, 5)
|
|
|
|
|
|
|
|
let protocol = newProtocol(
|
|
|
|
privKey,
|
2024-06-18 16:09:27 +00:00
|
|
|
Opt.some(address.ip),
|
|
|
|
Opt.some(address.port), Opt.some(address.port),
|
2022-02-02 14:29:45 +00:00
|
|
|
bindPort = address.port,
|
|
|
|
bootstrapRecords = bootstrapRecords,
|
|
|
|
localEnrFields = localEnrFields,
|
|
|
|
previousRecord = previousRecord,
|
|
|
|
config = config,
|
|
|
|
rng = rng)
|
|
|
|
|
|
|
|
protocol.open()
|
|
|
|
|
|
|
|
protocol
|
2020-06-17 11:51:30 +00:00
|
|
|
|
2023-11-10 06:28:21 +00:00
|
|
|
func nodeIdInNodes*(id: NodeId, nodes: openArray[Node]): bool =
|
2020-06-17 11:51:30 +00:00
|
|
|
for n in nodes:
|
|
|
|
if id == n.id: return true
|
|
|
|
|
2023-11-10 06:28:21 +00:00
|
|
|
func generateNode*(privKey: PrivateKey, port: int = 20302,
|
|
|
|
ip: IpAddress = parseIpAddress("127.0.0.1"),
|
2021-12-20 12:14:50 +00:00
|
|
|
localEnrFields: openArray[FieldPair] = []): Node =
|
2020-06-17 11:51:30 +00:00
|
|
|
let port = Port(port)
|
2024-06-18 16:09:27 +00:00
|
|
|
let enr = enr.Record.init(1, privKey, Opt.some(ip),
|
|
|
|
Opt.some(port), Opt.some(port), localEnrFields).expect("Properly initialized private key")
|
2020-06-17 11:51:30 +00:00
|
|
|
result = newNode(enr).expect("Properly initialized node")
|
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
proc generateNRandomNodes*(rng: var HmacDrbgContext, n: int): seq[Node] =
|
2021-09-02 12:00:36 +00:00
|
|
|
var res = newSeq[Node]()
|
|
|
|
for i in 1..n:
|
2022-06-17 20:45:37 +00:00
|
|
|
let node = generateNode(PrivateKey.random(rng))
|
2021-09-02 12:00:36 +00:00
|
|
|
res.add(node)
|
|
|
|
res
|
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
proc nodeAndPrivKeyAtDistance*(n: Node, rng: var HmacDrbgContext, d: uint32,
|
2023-11-10 06:28:21 +00:00
|
|
|
ip: IpAddress = parseIpAddress("127.0.0.1")): (Node, PrivateKey) =
|
2020-06-17 11:51:30 +00:00
|
|
|
while true:
|
2020-11-26 17:20:15 +00:00
|
|
|
let pk = PrivateKey.random(rng)
|
|
|
|
let node = generateNode(pk, ip = ip)
|
2021-10-07 14:03:12 +00:00
|
|
|
if logDistance(n.id, node.id) == d:
|
2020-11-26 17:20:15 +00:00
|
|
|
return (node, pk)
|
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
proc nodeAtDistance*(n: Node, rng: var HmacDrbgContext, d: uint32,
|
2023-11-10 06:28:21 +00:00
|
|
|
ip: IpAddress = parseIpAddress("127.0.0.1")): Node =
|
2020-11-26 17:20:15 +00:00
|
|
|
let (node, _) = n.nodeAndPrivKeyAtDistance(rng, d, ip)
|
|
|
|
node
|
2020-06-17 11:51:30 +00:00
|
|
|
|
2020-07-07 08:56:26 +00:00
|
|
|
proc nodesAtDistance*(
|
2022-06-17 20:45:37 +00:00
|
|
|
n: Node, rng: var HmacDrbgContext, d: uint32, amount: int,
|
2023-11-10 06:28:21 +00:00
|
|
|
ip: IpAddress = parseIpAddress("127.0.0.1")): seq[Node] =
|
2020-11-26 17:20:15 +00:00
|
|
|
for i in 0..<amount:
|
|
|
|
result.add(nodeAtDistance(n, rng, d, ip))
|
|
|
|
|
|
|
|
proc nodesAtDistanceUniqueIp*(
|
2022-06-17 20:45:37 +00:00
|
|
|
n: Node, rng: var HmacDrbgContext, d: uint32, amount: int,
|
2023-11-10 06:28:21 +00:00
|
|
|
ip: IpAddress = parseIpAddress("127.0.0.1")): seq[Node] =
|
2020-11-26 17:20:15 +00:00
|
|
|
var ta = initTAddress(ip, Port(0))
|
2020-06-17 11:51:30 +00:00
|
|
|
for i in 0..<amount:
|
2020-11-26 17:20:15 +00:00
|
|
|
ta.inc()
|
2023-11-10 06:28:21 +00:00
|
|
|
result.add(nodeAtDistance(n, rng, d, ta.address()))
|
2020-06-30 11:35:15 +00:00
|
|
|
|
|
|
|
proc addSeenNode*(d: discv5_protocol.Protocol, n: Node): bool =
|
|
|
|
# Add it as a seen node, warning: for testing convenience only!
|
|
|
|
n.seen = true
|
|
|
|
d.addNode(n)
|