nim-eth/eth/p2p/discoveryv5/discovery_db.nim
Kim De Mey a110f091af
Discv5 eh2 (#240)
* Discv5: More error handling improvements

- More results usage and raises pragma annotations
- Remove ENode related code and adjust Node object
- Misc.

* Add sendMessage and catch RlpError when decoding WhoAreYou

* Make the receive proc exception free

Except for `Exception` hah...

* Address review comments

* And another bunch of results and raises annotations

* Send Nodes Message also on 0 nodes and remove usage of broken require
2020-05-28 10:19:36 +02:00

64 lines
1.8 KiB
Nim

import
std/net, stint, stew/endians2,
eth/trie/db, types, node
{.push raises: [Defect].}
type
DiscoveryDB* = ref object of Database
backend: TrieDatabaseRef
DbKeyKind = enum
kNodeToKeys = 100
proc init*(T: type DiscoveryDB, backend: TrieDatabaseRef): DiscoveryDB =
T(backend: backend)
const keySize = 1 + # unique triedb prefix (kNodeToKeys)
sizeof(NodeId) +
16 + # max size of ip address (ipv6)
2 # Sizeof port
proc makeKey(id: NodeId, address: Address): array[keySize, byte] =
result[0] = byte(kNodeToKeys)
var pos = 1
result[pos ..< pos+sizeof(id)] = toBytes(id)
pos.inc(sizeof(id))
case address.ip.family
of IpAddressFamily.IpV4:
result[pos ..< pos+sizeof(address.ip.address_v4)] = address.ip.address_v4
of IpAddressFamily.IpV6:
result[pos..< pos+sizeof(address.ip.address_v6)] = address.ip.address_v6
pos.inc(sizeof(address.ip.address_v6))
result[pos ..< pos+sizeof(address.port)] = toBytes(address.port.uint16)
method storeKeys*(db: DiscoveryDB, id: NodeId, address: Address, r, w: AesKey):
bool =
try:
var value: array[sizeof(r) + sizeof(w), byte]
value[0 .. 15] = r
value[16 .. ^1] = w
db.backend.put(makeKey(id, address), value)
return true
except CatchableError:
return false
method loadKeys*(db: DiscoveryDB, id: NodeId, address: Address,
r, w: var AesKey): bool =
try:
let res = db.backend.get(makeKey(id, address))
if res.len != sizeof(r) + sizeof(w):
return false
copyMem(addr r[0], unsafeAddr res[0], sizeof(r))
copyMem(addr w[0], unsafeAddr res[sizeof(r)], sizeof(w))
return true
except CatchableError:
return false
method deleteKeys*(db: DiscoveryDB, id: NodeId, address: Address): bool =
try:
db.backend.del(makeKey(id, address))
return true
except CatchableError:
return false