nim-eth/eth/p2p/discoveryv5/node.nim

65 lines
1.7 KiB
Nim
Raw Normal View History

import
2020-03-05 00:25:21 +00:00
std/[net, hashes], nimcrypto, stint, chronicles,
types, enr, eth/keys, ../enode
2019-12-16 19:38:45 +00:00
{.push raises: [Defect].}
2019-12-16 19:38:45 +00:00
type
Node* = ref object
node*: ENode
id*: NodeId
record*: Record
proc toNodeId*(pk: PublicKey): NodeId =
readUintBE[256](keccak256.digest(pk.toRaw()).data)
2019-12-16 19:38:45 +00:00
# TODO: Lets not allow to create a node where enode info is not in sync with the
# record
proc newNode*(enode: ENode, r: Record): Node =
Node(node: enode,
id: enode.pubkey.toNodeId(),
record: r)
2019-12-16 19:38:45 +00:00
proc newNode*(r: Record): Node =
# TODO: Handle IPv6
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)
except KeyError, ValueError:
# TODO: This will result in a 0.0.0.0 address. Might introduce more bugs.
# Maybe we shouldn't allow the creation of Node from Record without IP.
# Will need some refactor though.
discard
2019-12-16 19:38:45 +00:00
let pk = r.get(PublicKey)
if pk.isNone():
warn "Could not recover public key from ENR"
return
let enode = ENode(pubkey: pk.get(), address: a)
result = Node(node: enode,
id: enode.pubkey.toNodeId(),
record: r)
2019-12-16 19:38:45 +00:00
proc hash*(n: Node): hashes.Hash = hash(n.node.pubkey.toRaw)
2020-05-01 20:34:26 +00:00
proc `==`*(a, b: Node): bool =
(a.isNil and b.isNil) or
(not a.isNil and not b.isNil and a.node.pubkey == b.node.pubkey)
2019-12-16 19:38:45 +00:00
2020-05-01 20:34:26 +00:00
proc address*(n: Node): Address {.inline.} = n.node.address
2020-05-01 20:34:26 +00:00
proc updateEndpoint*(n: Node, a: Address) {.inline.} =
n.node.address = a
2020-05-01 20:34:26 +00:00
proc `$`*(n: Node): string =
2019-12-16 19:38:45 +00:00
if n == nil:
"Node[local]"
else:
"Node[" & $n.node.address.ip & ":" & $n.node.address.udpPort & "]"