nim-eth/eth/p2p/discoveryv5/messages.nim

114 lines
2.9 KiB
Nim
Raw Normal View History

# 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
##
{.push raises: [Defect].}
import
2021-01-25 16:26:18 +00:00
std/[hashes, net],
./enr
2019-12-16 19:38:45 +00:00
type
MessageKind* = enum
# Note:
# This is needed only to keep the compiler happy. Without it, the
# `MessageKind` type cannot be used as a discriminator in case objects.
# If a message with this value is received however, it will fail at the
# decoding step.
unused = 0x00
# The supported message types
2019-12-16 19:38:45 +00:00
ping = 0x01
pong = 0x02
findNode = 0x03
2019-12-16 19:38:45 +00:00
nodes = 0x04
talkReq = 0x05
talkResp = 0x06
regTopic = 0x07
2020-11-13 11:33:07 +00:00
ticket = 0x08
regConfirmation = 0x09
topicQuery = 0x0A
2019-12-16 19:38:45 +00:00
2020-11-13 11:33:07 +00:00
RequestId* = object
id*: seq[byte]
2019-12-16 19:38:45 +00:00
PingMessage* = object
2019-12-16 19:38:45 +00:00
enrSeq*: uint64
PongMessage* = object
2019-12-16 19:38:45 +00:00
enrSeq*: uint64
2021-01-25 16:26:18 +00:00
ip*: IpAddress
2019-12-16 19:38:45 +00:00
port*: uint16
FindNodeMessage* = object
distances*: seq[uint16]
2019-12-16 19:38:45 +00:00
NodesMessage* = object
2019-12-16 19:38:45 +00:00
total*: uint32
enrs*: seq[Record]
2020-11-13 11:33:07 +00:00
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
2019-12-16 19:38:45 +00:00
Message* = object
2019-12-16 19:38:45 +00:00
reqId*: RequestId
case kind*: MessageKind
2019-12-16 19:38:45 +00:00
of ping:
ping*: PingMessage
2019-12-16 19:38:45 +00:00
of pong:
pong*: PongMessage
of findNode:
findNode*: FindNodeMessage
2019-12-16 19:38:45 +00:00
of nodes:
nodes*: NodesMessage
of talkReq:
talkReq*: TalkReqMessage
of talkResp:
talkResp*: TalkRespMessage
of regTopic:
2020-11-13 11:33:07 +00:00
regtopic*: RegTopicMessage
of ticket:
ticket*: TicketMessage
of regConfirmation:
regConfirmation*: RegConfirmationMessage
of topicQuery:
topicQuery*: TopicQueryMessage
2019-12-16 19:38:45 +00:00
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 NodesMessage: nodes
elif T is TalkReqMessage: talkReq
elif T is TalkRespMessage: talkResp
2020-11-13 11:33:07 +00:00
func init*(T: type RequestId, rng: var HmacDrbgContext): T =
var reqId = RequestId(id: newSeq[byte](8)) # RequestId must be <= 8 bytes
rng.generate(reqId.id)
2020-11-13 11:33:07 +00:00
reqId
func hash*(reqId: RequestId): Hash =
2020-11-13 11:33:07 +00:00
hash(reqId.id)