2021-11-24 07:45:55 +00:00
|
|
|
# Nimbus
|
2024-01-13 01:41:57 +00:00
|
|
|
# Copyright (c) 2021-2024 Status Research & Development GmbH
|
2021-11-24 07:45:55 +00:00
|
|
|
# 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.
|
|
|
|
|
2023-01-31 12:38:08 +00:00
|
|
|
{.push raises: [].}
|
2021-11-24 07:45:55 +00:00
|
|
|
|
|
|
|
import
|
2024-01-13 01:41:57 +00:00
|
|
|
stint,
|
2021-11-29 09:39:37 +00:00
|
|
|
json_rpc/jsonmarshal,
|
2023-11-27 09:21:19 +00:00
|
|
|
stew/[results, byteutils],
|
2021-11-24 07:45:55 +00:00
|
|
|
eth/p2p/discoveryv5/[routing_table, enr, node]
|
|
|
|
|
2021-12-03 08:51:25 +00:00
|
|
|
export jsonmarshal, routing_table, enr, node
|
2021-11-29 09:39:37 +00:00
|
|
|
|
2021-11-24 07:45:55 +00:00
|
|
|
type
|
|
|
|
NodeInfo* = object
|
2022-12-13 18:22:36 +00:00
|
|
|
enr*: Record
|
2021-12-03 08:51:25 +00:00
|
|
|
nodeId*: NodeId
|
2021-11-24 07:45:55 +00:00
|
|
|
|
|
|
|
RoutingTableInfo* = object
|
2022-12-15 15:24:23 +00:00
|
|
|
localNodeId*: NodeId
|
2021-12-03 08:51:25 +00:00
|
|
|
buckets*: seq[seq[NodeId]]
|
2021-11-24 07:45:55 +00:00
|
|
|
|
2024-01-13 01:41:57 +00:00
|
|
|
PingResult* = tuple[enrSeq: uint64, dataRadius: UInt256]
|
|
|
|
|
|
|
|
NodeInfo.useDefaultSerializationIn JrpcConv
|
|
|
|
RoutingTableInfo.useDefaultSerializationIn JrpcConv
|
|
|
|
(string,string).useDefaultSerializationIn JrpcConv
|
|
|
|
|
2022-12-13 18:22:36 +00:00
|
|
|
func getNodeInfo*(r: RoutingTable): NodeInfo =
|
|
|
|
NodeInfo(enr: r.localNode.record, nodeId: r.localNode.id)
|
2021-11-24 07:45:55 +00:00
|
|
|
|
2022-12-13 18:22:36 +00:00
|
|
|
func getRoutingTableInfo*(r: RoutingTable): RoutingTableInfo =
|
2021-11-24 07:45:55 +00:00
|
|
|
var info: RoutingTableInfo
|
|
|
|
for b in r.buckets:
|
2021-11-29 09:39:37 +00:00
|
|
|
var bucket: seq[NodeId]
|
2021-11-24 07:45:55 +00:00
|
|
|
for n in b.nodes:
|
2021-11-29 09:39:37 +00:00
|
|
|
bucket.add(n.id)
|
2021-11-24 07:45:55 +00:00
|
|
|
|
|
|
|
info.buckets.add(bucket)
|
|
|
|
|
2022-12-15 15:24:23 +00:00
|
|
|
info.localNodeId = r.localNode.id
|
2021-11-24 07:45:55 +00:00
|
|
|
|
|
|
|
info
|
2021-11-29 09:39:37 +00:00
|
|
|
|
2023-01-31 12:38:08 +00:00
|
|
|
func toNodeWithAddress*(enr: Record): Node {.raises: [ValueError].} =
|
2021-11-29 09:39:37 +00:00
|
|
|
let nodeRes = newNode(enr)
|
|
|
|
if nodeRes.isErr():
|
|
|
|
raise newException(ValueError, $nodeRes.error)
|
|
|
|
|
|
|
|
let node = nodeRes.get()
|
|
|
|
if node.address.isNone():
|
|
|
|
raise newException(ValueError, "ENR without address")
|
|
|
|
else:
|
|
|
|
node
|
|
|
|
|
2024-01-13 01:41:57 +00:00
|
|
|
proc writeValue*(w: var JsonWriter[JrpcConv], v: Record)
|
|
|
|
{.gcsafe, raises: [IOError].} =
|
|
|
|
w.writeValue(v.toURI())
|
2021-11-29 09:39:37 +00:00
|
|
|
|
2024-01-13 01:41:57 +00:00
|
|
|
proc readValue*(r: var JsonReader[JrpcConv], val: var Record)
|
|
|
|
{.gcsafe, raises: [IOError, JsonReaderError].} =
|
|
|
|
if not fromURI(val, r.parseString()):
|
|
|
|
r.raiseUnexpectedValue("Invalid ENR")
|
2021-11-29 09:39:37 +00:00
|
|
|
|
2024-01-13 01:41:57 +00:00
|
|
|
proc writeValue*(w: var JsonWriter[JrpcConv], v: NodeId)
|
|
|
|
{.gcsafe, raises: [IOError].} =
|
|
|
|
w.writeValue("0x" & v.toHex())
|
2021-11-29 09:39:37 +00:00
|
|
|
|
2024-01-13 01:41:57 +00:00
|
|
|
proc writeValue*(w: var JsonWriter[JrpcConv], v: Opt[NodeId])
|
|
|
|
{.gcsafe, raises: [IOError].} =
|
|
|
|
if v.isSome():
|
|
|
|
w.writeValue("0x" & v.get().toHex())
|
2023-11-27 09:21:19 +00:00
|
|
|
else:
|
2024-01-13 01:41:57 +00:00
|
|
|
w.writeValue("0x")
|
|
|
|
|
|
|
|
proc readValue*(r: var JsonReader[JrpcConv], val: var NodeId)
|
|
|
|
{.gcsafe, raises: [IOError, JsonReaderError].} =
|
|
|
|
try:
|
|
|
|
val = NodeId.fromHex(r.parseString())
|
|
|
|
except ValueError as exc:
|
|
|
|
r.raiseUnexpectedValue("NodeId parser error: " & exc.msg)
|
|
|
|
|
|
|
|
proc writeValue*(w: var JsonWriter[JrpcConv], v: Opt[seq[byte]])
|
|
|
|
{.gcsafe, raises: [IOError].} =
|
|
|
|
if v.isSome():
|
|
|
|
w.writeValue(v.get().to0xHex())
|
2023-11-27 09:21:19 +00:00
|
|
|
else:
|
2024-01-13 01:41:57 +00:00
|
|
|
w.writeValue("0x")
|
|
|
|
|
|
|
|
proc readValue*(r: var JsonReader[JrpcConv], val: var seq[byte])
|
|
|
|
{.gcsafe, raises: [IOError, JsonReaderError].} =
|
|
|
|
try:
|
|
|
|
val = hexToSeqByte(r.parseString())
|
|
|
|
except ValueError as exc:
|
|
|
|
r.raiseUnexpectedValue("seq[byte] parser error: " & exc.msg)
|
|
|
|
|
|
|
|
proc writeValue*(w: var JsonWriter[JrpcConv], v: PingResult)
|
|
|
|
{.gcsafe, raises: [IOError].} =
|
|
|
|
w.beginRecord()
|
|
|
|
w.writeField("enrSeq", v.enrSeq)
|
|
|
|
w.writeField("dataRadius", "0x" & v.dataRadius.toHex)
|
|
|
|
w.endRecord()
|
|
|
|
|
|
|
|
proc readValue*(r: var JsonReader[JrpcConv], val: var PingResult)
|
|
|
|
{.gcsafe, raises: [IOError, SerializationError].} =
|
|
|
|
try:
|
|
|
|
for field in r.readObjectFields():
|
|
|
|
case field:
|
|
|
|
of "enrSeq": val.enrSeq = r.parseInt(uint64)
|
|
|
|
of "dataRadius": val.dataRadius = UInt256.fromHex(r.parseString())
|
|
|
|
else: discard
|
|
|
|
except ValueError as exc:
|
|
|
|
r.raiseUnexpectedValue("PingResult parser error: " & exc.msg)
|