2020-02-17 17:44:56 +01:00
|
|
|
import
|
2020-03-05 01:25:21 +01:00
|
|
|
std/[net, hashes], nimcrypto, stint, chronicles,
|
2020-02-17 17:44:56 +01:00
|
|
|
types, enr, eth/keys, ../enode
|
2019-12-16 21:38:45 +02:00
|
|
|
|
2020-04-30 00:11:03 +02:00
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
2019-12-16 21:38:45 +02:00
|
|
|
type
|
|
|
|
Node* = ref object
|
|
|
|
node*: ENode
|
|
|
|
id*: NodeId
|
|
|
|
record*: Record
|
|
|
|
|
|
|
|
proc toNodeId*(pk: PublicKey): NodeId =
|
2020-04-04 18:44:01 +02:00
|
|
|
readUintBE[256](keccak256.digest(pk.toRaw()).data)
|
2019-12-16 21:38:45 +02:00
|
|
|
|
2020-04-30 00:11:03 +02:00
|
|
|
# TODO: Lets not allow to create a node where enode info is not in sync with the
|
|
|
|
# record
|
2020-02-22 01:55:37 +02:00
|
|
|
proc newNode*(enode: ENode, r: Record): Node =
|
|
|
|
Node(node: enode,
|
|
|
|
id: enode.pubkey.toNodeId(),
|
|
|
|
record: r)
|
2019-12-16 21:38:45 +02:00
|
|
|
|
|
|
|
proc newNode*(r: Record): Node =
|
|
|
|
# TODO: Handle IPv6
|
2020-03-20 16:38:46 +01:00
|
|
|
var a: Address
|
|
|
|
try:
|
|
|
|
let
|
|
|
|
ipBytes = r.get("ip", array[4, byte])
|
|
|
|
udpPort = r.get("udp", uint16)
|
|
|
|
|
|
|
|
a = Address(ip: IpAddress(family: IpAddressFamily.IPv4,
|
|
|
|
address_v4: ipBytes),
|
|
|
|
udpPort: Port udpPort)
|
2020-04-30 00:11:03 +02:00
|
|
|
except KeyError, ValueError:
|
2020-03-27 14:37:31 +01:00
|
|
|
# TODO: This will result in a 0.0.0.0 address. Might introduce more bugs.
|
2020-03-30 13:21:32 +02:00
|
|
|
# Maybe we shouldn't allow the creation of Node from Record without IP.
|
|
|
|
# Will need some refactor though.
|
2020-03-20 16:38:46 +01:00
|
|
|
discard
|
2019-12-16 21:38:45 +02:00
|
|
|
|
2020-04-30 00:11:03 +02:00
|
|
|
let pk = r.get(PublicKey)
|
|
|
|
if pk.isNone():
|
|
|
|
warn "Could not recover public key from ENR"
|
2020-02-12 15:36:39 +02:00
|
|
|
return
|
|
|
|
|
2020-04-30 00:11:03 +02:00
|
|
|
let enode = ENode(pubkey: pk.get(), address: a)
|
|
|
|
result = Node(node: enode,
|
|
|
|
id: enode.pubkey.toNodeId(),
|
|
|
|
record: r)
|
2019-12-16 21:38:45 +02:00
|
|
|
|
2020-04-04 18:44:01 +02:00
|
|
|
proc hash*(n: Node): hashes.Hash = hash(n.node.pubkey.toRaw)
|
2020-05-01 22:34:26 +02:00
|
|
|
proc `==`*(a, b: Node): bool =
|
2020-04-30 00:11:03 +02:00
|
|
|
(a.isNil and b.isNil) or
|
|
|
|
(not a.isNil and not b.isNil and a.node.pubkey == b.node.pubkey)
|
2019-12-16 21:38:45 +02:00
|
|
|
|
2020-05-01 22:34:26 +02:00
|
|
|
proc address*(n: Node): Address {.inline.} = n.node.address
|
2019-12-18 12:36:11 +02:00
|
|
|
|
2020-05-01 22:34:26 +02:00
|
|
|
proc updateEndpoint*(n: Node, a: Address) {.inline.} =
|
2020-04-30 00:11:03 +02:00
|
|
|
n.node.address = a
|
2020-03-18 15:27:26 +01:00
|
|
|
|
2020-05-01 22:34:26 +02:00
|
|
|
proc `$`*(n: Node): string =
|
2019-12-16 21:38:45 +02:00
|
|
|
if n == nil:
|
|
|
|
"Node[local]"
|
|
|
|
else:
|
|
|
|
"Node[" & $n.node.address.ip & ":" & $n.node.address.udpPort & "]"
|