# codex-dht - Codex DHT # Copyright (c) 2020-2022 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. # ## Discovery v5 packet encoding as specified at ## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-wire.md#packet-encoding import std/net, chronicles, libp2p/routing_record, libp2p/signed_envelope, "."/[messages, spr, node], ../../../../dht/providers_encoding from stew/objects import checkedEnumAssign type DecodeResult*[T] = Result[T, cstring] Distances = seq[uint16] EncodedMessage = seq[byte] IPv4 = array[0..3, uint8] IPv6 = array[0..15, uint8] Port = uint16 proc getField*(pb: ProtoBuffer, field: int, reqId: var RequestId): ProtoResult[bool] {.inline.} = ## Read ``RequestId`` from ProtoBuf's message and validate it var buffer: seq[byte] let res = ? pb.getField(field, buffer) if not(res): ok(false) elif buffer.len > 8: ok(false) # RequestId must not be more than 8 bytes else: reqId = RequestId(id: buffer) ok(true) proc write*(pb: var ProtoBuffer, field: int, reqId: RequestId) = ## Write RequestId value ``reqId`` to object ``pb`` using ProtoBuf's encoding. let encoded = reqId.id write(pb, field, encoded) proc decode*( T: typedesc[PingMessage], buffer: openArray[byte]): Result[PingMessage, ProtoError] = let pb = initProtoBuffer(buffer) var msg = PingMessage() ? pb.getRequiredField(1, msg.sprSeq) ok(msg) proc encode*(msg: PingMessage): seq[byte] = var pb = initProtoBuffer() pb.write(1, msg.sprSeq) pb.finish() pb.buffer proc getField*(pb: ProtoBuffer, field: int, ipv4: var IPv4): ProtoResult[bool] {.inline.} = ## Read ``IPv4`` from ProtoBuf's message and validate it var buffer: seq[byte] let res = ? pb.getField(field, buffer) if not(res): ok(false) else: for i in 0..