mirror of
https://github.com/codex-storage/nim-codex-dht.git
synced 2025-02-20 23:58:09 +00:00
This patch adds a findNode message sending the actual target ID as in traditional Kademlia lookup. This in contrast to the actual findNode message that send information about the distance only, leading to more secure but slower lookups. Having both primitives allows us to select which to use per use case. Current naming is findNode for the distance based message and findNodeFast for the message added in this patch.
137 lines
3.6 KiB
Nim
137 lines
3.6 KiB
Nim
# nim-eth - Node Discovery Protocol v5
|
|
# Copyright (c) 2020-2021 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 Protocol Messages as specified at
|
|
## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-wire.md#protocol-messages
|
|
## These messages get RLP encoded.
|
|
##
|
|
|
|
{.push raises: [Defect].}
|
|
|
|
import
|
|
std/[hashes, net],
|
|
eth/[keys],
|
|
./spr,
|
|
./node,
|
|
../../../../dht/providers_messages
|
|
|
|
export providers_messages
|
|
|
|
type
|
|
MessageKind* = enum
|
|
# TODO This is needed only to make Nim 1.2.6 happy
|
|
# Without it, the `MessageKind` type cannot be used as
|
|
# a discriminator in case objects.
|
|
unused = 0x00
|
|
|
|
ping = 0x01
|
|
pong = 0x02
|
|
findNode = 0x03
|
|
nodes = 0x04
|
|
talkReq = 0x05
|
|
talkResp = 0x06
|
|
regTopic = 0x07
|
|
ticket = 0x08
|
|
regConfirmation = 0x09
|
|
topicQuery = 0x0A
|
|
addProvider = 0x0B
|
|
getProviders = 0x0C
|
|
providers = 0x0D
|
|
findNodeFast = 0x83
|
|
|
|
RequestId* = object
|
|
id*: seq[byte]
|
|
|
|
PingMessage* = object
|
|
sprSeq*: uint64
|
|
|
|
PongMessage* = object
|
|
sprSeq*: uint64
|
|
ip*: IpAddress
|
|
port*: uint16
|
|
|
|
FindNodeMessage* = object
|
|
distances*: seq[uint16]
|
|
|
|
FindNodeFastMessage* = object
|
|
target*: NodeId
|
|
|
|
NodesMessage* = object
|
|
total*: uint32
|
|
sprs*: seq[SignedPeerRecord]
|
|
|
|
TalkReqMessage* = object
|
|
protocol*: seq[byte]
|
|
request*: seq[byte]
|
|
|
|
TalkRespMessage* = object
|
|
response*: seq[byte]
|
|
|
|
# Not implemented, specification is not final here.
|
|
RegTopicMessage* = object
|
|
TicketMessage* = object
|
|
RegConfirmationMessage* = object
|
|
TopicQueryMessage* = object
|
|
|
|
SomeMessage* = PingMessage or PongMessage or FindNodeMessage or NodesMessage or
|
|
TalkReqMessage or TalkRespMessage or AddProviderMessage or GetProvidersMessage or
|
|
ProvidersMessage or FindNodeFastMessage
|
|
|
|
Message* = object
|
|
reqId*: RequestId
|
|
case kind*: MessageKind
|
|
of ping:
|
|
ping*: PingMessage
|
|
of pong:
|
|
pong*: PongMessage
|
|
of findNode:
|
|
findNode*: FindNodeMessage
|
|
of findNodeFast:
|
|
findNodeFast*: FindNodeFastMessage
|
|
of nodes:
|
|
nodes*: NodesMessage
|
|
of talkReq:
|
|
talkReq*: TalkReqMessage
|
|
of talkResp:
|
|
talkResp*: TalkRespMessage
|
|
of regTopic:
|
|
regtopic*: RegTopicMessage
|
|
of ticket:
|
|
ticket*: TicketMessage
|
|
of regConfirmation:
|
|
regConfirmation*: RegConfirmationMessage
|
|
of topicQuery:
|
|
topicQuery*: TopicQueryMessage
|
|
of addProvider:
|
|
addProvider*: AddProviderMessage
|
|
of getProviders:
|
|
getProviders*: GetProvidersMessage
|
|
of providers:
|
|
provs*: ProvidersMessage
|
|
else:
|
|
discard
|
|
|
|
template messageKind*(T: typedesc[SomeMessage]): MessageKind =
|
|
when T is PingMessage: ping
|
|
elif T is PongMessage: pong
|
|
elif T is FindNodeMessage: findNode
|
|
elif T is FindNodeFastMessage: findNodeFast
|
|
elif T is NodesMessage: nodes
|
|
elif T is TalkReqMessage: talkReq
|
|
elif T is TalkRespMessage: talkResp
|
|
elif T is AddProviderMessage: addProvider
|
|
elif T is GetProvidersMessage: getProviders
|
|
elif T is ProvidersMessage: providers
|
|
|
|
proc hash*(reqId: RequestId): Hash =
|
|
hash(reqId.id)
|
|
|
|
proc init*(T: type RequestId, rng: var BrHmacDrbgContext): T =
|
|
var reqId = RequestId(id: newSeq[byte](8)) # RequestId must be <= 8 bytes
|
|
brHmacDrbgGenerate(rng, reqId.id)
|
|
reqId
|