protocol

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 9, 2025 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package protocol implements the discv5 wire protocol message types and codec.

The discv5 protocol defines several message types for node discovery:

  • PING/PONG: Liveness checks
  • FINDNODE/NODES: Peer discovery
  • TALKREQ/TALKRESP: Generic request/response
  • REGTOPIC/TICKET/REGCONFIRMATION: Topic registration
  • TOPICQUERY: Topic-based discovery

All messages are RLP-encoded and encrypted using session keys.

Index

Constants

View Source
const (
	// PingMsg is sent to check if a node is alive
	PingMsg byte = 0x01

	// PongMsg is the response to PING
	PongMsg byte = 0x02

	// FindNodeMsg requests nodes at a given distance
	FindNodeMsg byte = 0x03

	// NodesMsg is the response to FINDNODE, containing discovered nodes
	NodesMsg byte = 0x04

	// TalkReqMsg is a generic application-level request
	TalkReqMsg byte = 0x05

	// TalkRespMsg is the response to TALKREQ
	TalkRespMsg byte = 0x06

	// RegTopicMsg registers interest in a topic (optional extension)
	RegTopicMsg byte = 0x07

	// TicketMsg provides a ticket for topic registration (optional extension)
	TicketMsg byte = 0x08

	// RegConfirmationMsg confirms topic registration (optional extension)
	RegConfirmationMsg byte = 0x09

	// TopicQueryMsg queries for nodes on a topic (optional extension)
	TopicQueryMsg byte = 0x0A
)

Message type constants for discv5 protocol

View Source
const (
	// OrdinaryPacket is an encrypted message with an established session
	OrdinaryPacket byte = 0x00

	// WHOAREYOUPacket is a challenge sent when no session exists
	WHOAREYOUPacket byte = 0x01

	// HandshakePacket is sent in response to WHOAREYOU to establish a session
	HandshakePacket byte = 0x02
)

Packet types for discv5 protocol (matches go-ethereum v5wire flags)

View Source
const (
	// ProtocolID is the protocol identifier for discv5
	// Format: "discv5" as bytes
	ProtocolID = "discv5"

	// MinPacketSize is the minimum size of a valid packet
	MinPacketSize = 63

	// MaxPacketSize is the maximum size of a UDP packet
	// This is 1280 bytes - the minimum IPv6 MTU to ensure packets aren't fragmented
	MaxPacketSize = 1280

	// HeaderSize is the size of the packet header
	HeaderSize = 32
)
View Source
const DefaultRequestTimeout = 5 * time.Second

DefaultRequestTimeout is the default timeout for requests (5 seconds).

Variables

View Source
var (
	ErrTimeout  = &ProtocolError{Code: "timeout", Message: "request timed out"}
	ErrCanceled = &ProtocolError{Code: "canceled", Message: "request canceled"}
)

Common errors

Functions

func BuildHandshakeHeaderData

func BuildHandshakeHeaderData(localNodeID node.ID, nonce []byte, signature, ephPubkey, enrBytes []byte) ([]byte, []byte, error)

BuildHandshakeHeaderData builds unmasked header data for GCM encryption.

Returns IV || unmasked-header || unmasked-authdata This is used as additional authenticated data for AES-GCM.

func BuildOrdinaryHeaderData

func BuildOrdinaryHeaderData(localNodeID node.ID, nonce, authdata []byte) ([]byte, []byte, error)

BuildOrdinaryHeaderData builds unmasked header data for GCM encryption of ordinary packets.

Returns IV || unmasked-header || unmasked-authdata This is used as additional authenticated data for AES-GCM.

func BuildWHOAREYOUChallengeData

func BuildWHOAREYOUChallengeData(maskingIV, nonce []byte, challenge *WHOAREYOUChallenge) []byte

BuildWHOAREYOUChallengeData builds the unmasked challenge data for signature verification. This matches the headerData that the remote node will extract when decoding the WHOAREYOU packet. Format: IV (16) || unmasked-header (23) || unmasked-authdata (24)

func EncodeHandshakePacket

func EncodeHandshakePacket(localNodeID, destNodeID node.ID, maskingIV, nonce []byte, signature, ephPubkey, enrBytes, messageCiphertext []byte) ([]byte, error)

EncodeHandshakePacket encodes a handshake message packet.

Handshake packet format:

packet = masking-iv (16) || masked-header (23) || masked-authdata || message-ciphertext
authdata = src-id (32) || sig-size (1) || eph-key-size (1) || id-signature || eph-pubkey || record

The minimal authdata is 34 bytes (src-id + sig-size + eph-key-size). Plus variable-length signature (~64 bytes), ephemeral pubkey (33 bytes), and optional ENR.

func EncodeOrdinaryPacket

func EncodeOrdinaryPacket(localNodeID, destNodeID node.ID, maskingIV, nonce []byte, authdata []byte, message []byte) ([]byte, error)

EncodeOrdinaryPacket encodes an ordinary packet with an established session.

Packet format (with session):

packet = masking-iv (16) || masked-header (23) || masked-authdata (32) || message-ciphertext
authdata = srcID (32 bytes)

func EncodePacket

func EncodePacket(packet *Packet) ([]byte, error)

EncodePacket encodes a complete packet to bytes.

Format:

  • Header (32 bytes)
  • Auth data (variable, size specified in header)
  • Message data (remaining bytes)

func EncodeRandomPacket

func EncodeRandomPacket(localNodeID, destNodeID node.ID) ([]byte, error)

EncodeRandomPacket encodes a random packet to trigger WHOAREYOU (go-ethereum style).

Random packet format (no session):

packet = masking-iv (16) || masked-header (23) || masked-authdata (32) || random-message (20)
masking-key = dest-node-id[:16]
mask = AES-CTR(masking-key, masking-iv)

The authdata for random packets contains: srcID (32 bytes) The message is 20 bytes of random data

func EncodeWHOAREYOUPacket

func EncodeWHOAREYOUPacket(destNodeID node.ID, nonce []byte, challenge *WHOAREYOUChallenge) ([]byte, []byte, error)

EncodeWHOAREYOUPacket encodes a WHOAREYOU packet and returns both the packet and the masking IV.

WHOAREYOU packet format:

whoareyou-packet = masking-iv (16) || masked-header (23) || masked-authdata (24)
authdata = id-nonce (16) || enr-seq (8)

Returns: (packet bytes, masking IV, error)

func NewRequestID

func NewRequestID() ([]byte, error)

NewRequestID generates a new random request ID.

Request IDs are used to match requests with their responses. They should be unique for each request to prevent confusion.

Returns an 8-byte random request ID.

Types

type FindNode

type FindNode struct {
	// RequestID is a unique identifier for matching request/response pairs
	RequestID []byte

	// Distances is a list of Kademlia distances to query
	// Each distance is a bucket index (0-256)
	// Special case: [256] means return all known nodes
	Distances []uint
}

FindNode requests nodes at a specific distance from the target.

The distance is specified as a list of logarithmic distances (bucket indices). A distance of [256] means "all nodes", while specific distances like [253, 254, 255] request nodes in those buckets.

Format: [request-id, [distance1, distance2, ...]]

func (*FindNode) Encode

func (f *FindNode) Encode() ([]byte, error)

Encode returns the RLP encoding of the FINDNODE message

func (*FindNode) Type

func (f *FindNode) Type() byte

Type returns the message type

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler handles incoming and outgoing protocol messages.

The handler is responsible for:

  • Processing incoming packets (PING, FINDNODE, TALKREQ)
  • Sending responses with appropriate filtering
  • Managing request/response matching
  • Applying response filters (LAN/WAN awareness)

func NewHandler

func NewHandler(ctx context.Context, cfg HandlerConfig) *Handler

NewHandler creates a new protocol handler.

Example:

handler := NewHandler(HandlerConfig{
    LocalNode: myNode,
    Sessions: sessionCache,
    OnFindNode: func(msg *FindNode, sourceNode *node.Node, requester *net.UDPAddr) []*node.Node { ... },
})

func (*Handler) GetStats

func (h *Handler) GetStats() HandlerStats

GetStats returns statistics about the handler.

func (*Handler) HandleIncomingPacket

func (h *Handler) HandleIncomingPacket(data []byte, from *net.UDPAddr, localAddr *net.UDPAddr) error

HandleIncomingPacket processes an incoming UDP packet.

This is called by the UDP transport layer when a packet arrives. The localAddr parameter is the local address that received the packet.

func (*Handler) Requests

func (h *Handler) Requests() *RequestTracker

Requests returns the request tracker.

This allows higher-level services to track pending requests.

func (*Handler) SendFindNode

func (h *Handler) SendFindNode(n *node.Node, distances []uint) (<-chan *Response, error)

SendFindNode sends a FINDNODE request.

Returns a channel that will receive the NODES response.

func (*Handler) SendMessage

func (h *Handler) SendMessage(msg Message, remoteID node.ID, to *net.UDPAddr, remoteNode *node.Node) error

SendMessage sends a message to a remote node.

This is a public method that can be used by higher-level services to send arbitrary messages through the protocol handler. remoteNode is optional - if provided, it will be stored in pending handshakes for WHOAREYOU responses.

func (*Handler) SendMessageFrom added in v0.0.2

func (h *Handler) SendMessageFrom(msg Message, remoteID node.ID, to *net.UDPAddr, remoteNode *node.Node, from *net.UDPAddr) error

SendMessageFrom sends a message to a remote node from a specific local address.

This is similar to SendMessage but allows specifying the local address to send from. This ensures IP address consistency when binding to 0.0.0.0 - the response is sent from the same address that received the request. remoteNode is optional - if provided, it will be stored in pending handshakes for WHOAREYOU responses.

func (*Handler) SendPing

func (h *Handler) SendPing(n *node.Node) (<-chan *Response, error)

SendPing sends a PING to a remote node.

Returns a channel that will receive the PONG response.

func (*Handler) SetTransport

func (h *Handler) SetTransport(transport Transport)

SetTransport sets the transport for sending packets.

type HandlerConfig

type HandlerConfig struct {
	// LocalNode is our node information
	LocalNode *node.Node

	// Sessions is the session cache
	Sessions *session.Cache

	// PrivateKey is the node's private key (for handshake signatures)
	PrivateKey *ecdsa.PrivateKey

	// Callbacks (all optional, can be nil)
	OnHandshakeComplete OnHandshakeCompleteCallback
	OnNodeUpdate        OnNodeUpdateCallback
	OnNodeSeen          OnNodeSeenCallback
	OnFindNode          OnFindNodeCallback
	OnTalkReq           OnTalkReqCallback
	OnPongReceived      OnPongReceivedCallback

	// RequestTimeout is the timeout for requests
	RequestTimeout time.Duration

	// MaxPendingHandshakes is the maximum number of pending outgoing handshakes (0 = 2000)
	MaxPendingHandshakes int

	// MaxPendingChallenges is the maximum number of pending incoming challenges (0 = 500)
	MaxPendingChallenges int

	// MaxPendingPerIP is the maximum number of pending entries per IP address (0 = 10)
	MaxPendingPerIP int

	// Logger for debug messages
	Logger logrus.FieldLogger
}

HandlerConfig contains configuration for the protocol handler.

type HandlerStats

type HandlerStats struct {
	PacketsReceived    int
	PacketsSent        int
	InvalidPackets     int
	FilteredResponses  int
	FindNodeReceived   int
	PendingHandshakes  int
	PendingChallenges  int
	RejectedHandshakes int
	RejectedChallenges int
	EvictedHandshakes  int
	EvictedChallenges  int
	PendingPerIPCount  int
	RequestStats       RequestStats
}

GetStats returns handler statistics.

type HandshakeData

type HandshakeData struct {
	// SourceNodeID is the sender's node ID (32 bytes)
	SourceNodeID []byte

	// Signature proves ownership of the node ID
	Signature []byte

	// EphemeralPubKey is the ephemeral public key for session establishment
	EphemeralPubKey []byte

	// ENR is the sender's ENR record (optional, only if seq changed)
	ENR []byte
}

HandshakeData is sent in response to a WHOAREYOU challenge.

It proves the sender's identity and optionally provides an updated ENR.

Format:

  • SourceNodeID: Sender's node ID (32 bytes)
  • Signature: Signature proving ownership of node ID
  • EphemeralPubKey: Ephemeral public key for ECDH
  • ENR: Optional updated ENR record (if sequence number changed)

type Message

type Message interface {
	// Type returns the message type byte
	Type() byte

	// Encode returns the RLP encoding of the message
	Encode() ([]byte, error)
}

Message is the interface implemented by all discv5 messages.

type Nodes

type Nodes struct {
	// RequestID matches the request ID from the FINDNODE
	RequestID []byte

	// Total is the total number of NODES messages for this response
	Total uint

	// Records contains the ENR records in this message
	Records []*enr.Record
}

Nodes is the response to a FINDNODE request.

It contains a list of ENR records for discovered nodes. If the response is too large for a single packet, it's split across multiple NODES messages with the same request ID.

Format: [request-id, total, [enr1, enr2, ...]]

func (*Nodes) Encode

func (n *Nodes) Encode() ([]byte, error)

Encode returns the RLP encoding of the NODES message

func (*Nodes) Type

func (n *Nodes) Type() byte

Type returns the message type

type OnFindNodeCallback

type OnFindNodeCallback func(msg *FindNode, sourceNode *node.Node, requester *net.UDPAddr) []*node.Node

OnFindNodeCallback is called when a FINDNODE request is received. The sourceNode parameter is the node that sent the request (may be nil if unknown). The requester parameter provides the requesting node's address for context-aware filtering (e.g., LAN-aware filtering).

type OnHandshakeCompleteCallback

type OnHandshakeCompleteCallback func(n *node.Node, incoming bool)

OnHandshakeCompleteCallback is called when a handshake completes successfully.

type OnNodeSeenCallback

type OnNodeSeenCallback func(n *node.Node, timestamp time.Time)

OnNodeSeenCallback is called when a node is seen (receives a message). This is useful for tracking last_seen timestamps in the database.

type OnNodeUpdateCallback

type OnNodeUpdateCallback func(n *node.Node)

OnNodeUpdateCallback is called when a node's ENR is updated.

type OnPongReceivedCallback

type OnPongReceivedCallback func(remoteNodeID node.ID, sourceIP net.IP, reportedIP net.IP, reportedPort uint16)

OnPongReceivedCallback is called when a PONG response is received. Parameters: remoteNodeID, sourceIP (remote peer's IP), reportedIP (our IP as seen by the remote peer), reportedPort (our port as seen by the remote peer)

type OnTalkReqCallback

type OnTalkReqCallback func(msg *TalkReq) []byte

OnTalkReqCallback is called when a TALKREQ request is received.

type Packet

type Packet struct {
	// PacketType is the type of packet (Ordinary, WHOAREYOU, or Handshake)
	PacketType byte

	// Header contains packet metadata (nonce, auth data, etc.)
	Header *PacketHeader

	// HeaderData is the raw packet data from start to end of authdata (IV + masked header + masked authdata)
	// This is used as additional data (AD) for AES-GCM encryption/decryption
	HeaderData []byte

	// SrcID is the source node ID (extracted from authdata for ordinary/random packets)
	SrcID []byte

	// Message is the encrypted message payload (for Ordinary packets)
	Message []byte

	// Challenge is the challenge data (for WHOAREYOU packets)
	Challenge *WHOAREYOUChallenge

	// Handshake is the handshake data (for Handshake packets)
	Handshake *HandshakeData
}

Packet represents a discv5 protocol packet.

All communication in discv5 happens through packets sent over UDP. There are three packet types:

  • Ordinary: Regular encrypted message (most common)
  • WHOAREYOU: Challenge for session establishment
  • Handshake: Response to WHOAREYOU challenge

func DecodePacket

func DecodePacket(data []byte, localNodeID node.ID) (*Packet, error)

DecodePacket decodes a packet from bytes according to go-ethereum discv5 format.

Packet format:

masking-iv (16) || masked-header (23) || masked-authdata || message-data

The header and authdata are masked using AES-CTR with:

masking-key = localNodeID[:16]
stream = AES-CTR(masking-key, masking-iv)

This performs initial unmasking and parsing of the packet structure. The message payload is not decrypted at this stage.

type PacketHeader

type PacketHeader struct {
	// ProtocolID should always be "discv5"
	ProtocolID []byte

	// Version is the protocol version (currently 0x0001)
	Version uint16

	// Flag indicates the packet type
	Flag byte

	// Nonce is used for encryption (12 bytes)
	Nonce []byte

	// AuthDataSize is the size of the authentication data in bytes
	AuthDataSize uint16
}

PacketHeader contains metadata for all packet types.

Format:

  • ProtocolID: 6 bytes - "discv5"
  • Version: 2 bytes - protocol version (currently 0x0001)
  • Flag: 1 byte - packet type (Ordinary, WHOAREYOU, Handshake)
  • Nonce: 12 bytes - random nonce for encryption
  • AuthDataSize: 2 bytes - size of authentication data

func DecodePacketHeader

func DecodePacketHeader(data []byte) (*PacketHeader, error)

DecodePacketHeader decodes a packet header from bytes.

The input must be at least 32 bytes (the header size).

func NewPacketHeader

func NewPacketHeader(packetType byte) (*PacketHeader, error)

NewPacketHeader creates a new packet header with default values.

The header is initialized with:

  • ProtocolID: "discv5"
  • Version: 0x0001
  • Flag: Set to provided packet type
  • Nonce: Random 12-byte nonce
  • AuthDataSize: 0 (set later based on auth data)

func (*PacketHeader) Encode

func (h *PacketHeader) Encode() ([]byte, error)

Encode encodes the packet header to bytes.

Format (total 32 bytes):

  • ProtocolID: 6 bytes
  • Version: 2 bytes (big-endian)
  • Flag: 1 byte
  • Nonce: 12 bytes
  • AuthDataSize: 2 bytes (big-endian)

type PendingChallenge

type PendingChallenge struct {
	ToAddr        *net.UDPAddr
	ToNodeID      node.ID
	ChallengeData []byte
	PacketBytes   []byte // Raw WHOAREYOU packet bytes for resending
	CreatedAt     time.Time
}

PendingChallenge tracks WHOAREYOU challenges we've sent.

type PendingHandshake

type PendingHandshake struct {
	Message    Message
	ToNode     *node.Node
	ToAddr     *net.UDPAddr
	ToNodeID   node.ID
	CreatedAt  time.Time
	LastRetry  time.Time // When we last sent a retry
	RetryCount int       // Number of retries attempted
	MaxRetries int       // Maximum number of retries (default 3)
}

PendingHandshake tracks a message waiting for handshake completion

type PendingRequest

type PendingRequest struct {
	// RequestID is the unique ID for this request
	RequestID []byte

	// NodeID is the target node
	NodeID node.ID

	// Node is the target node reference (for handshakes after session becomes stale)
	Node *node.Node

	// Message is the original message that was sent (for replay after re-handshake)
	Message Message

	// Timeout is when the request expires
	Timeout time.Time

	// ResponseChan receives the response or error
	ResponseChan chan *Response

	// Retries is the number of retry attempts
	Retries int

	// For multi-packet NODES responses
	ExpectedTotal    uint   // Total number of NODES packets expected
	ReceivedCount    uint   // Number of NODES packets received so far
	AccumulatedNodes *Nodes // Accumulated NODES message
}

PendingRequest tracks an outgoing request waiting for a response.

type Ping

type Ping struct {
	// RequestID is a unique identifier for matching request/response pairs
	RequestID []byte

	// ENRSeq is the sender's current ENR sequence number
	ENRSeq uint64
}

Ping is sent to check if a node is alive.

The ping message includes the sender's ENR sequence number, allowing the recipient to request an updated ENR if needed.

Format: [request-id, enr-seq]

func (*Ping) Encode

func (p *Ping) Encode() ([]byte, error)

Encode returns the RLP encoding of the PING message

func (*Ping) Type

func (p *Ping) Type() byte

Type returns the message type

type Pong

type Pong struct {
	// RequestID matches the request ID from the PING
	RequestID []byte

	// ENRSeq is the responder's current ENR sequence number
	ENRSeq uint64

	// IP is the responder's IP address as seen by the recipient
	IP []byte

	// Port is the responder's UDP port
	Port uint16
}

Pong is the response to a PING message.

It echoes back the request ID and includes the responder's ENR sequence number and IP/port information.

Format: [request-id, enr-seq, ip, port]

func (*Pong) Encode

func (p *Pong) Encode() ([]byte, error)

Encode returns the RLP encoding of the PONG message

func (*Pong) Type

func (p *Pong) Type() byte

Type returns the message type

type ProtocolError

type ProtocolError struct {
	Code    string
	Message string
}

ProtocolError represents a protocol-level error.

func (*ProtocolError) Error

func (e *ProtocolError) Error() string

type RegConfirmation

type RegConfirmation struct {
	RequestID []byte
	Topic     []byte
}

RegConfirmation confirms topic registration (optional extension).

Format: [request-id, topic]

func (*RegConfirmation) Encode

func (r *RegConfirmation) Encode() ([]byte, error)

Encode returns the RLP encoding of the REGCONFIRMATION message

func (*RegConfirmation) Type

func (r *RegConfirmation) Type() byte

Type returns the message type

type RegTopic

type RegTopic struct {
	RequestID []byte
	Topic     []byte
	ENR       *enr.Record
	Ticket    []byte
}

RegTopic registers interest in a topic (optional extension).

Topic discovery is an optional extension to the core discv5 protocol. It allows nodes to advertise and discover peers interested in specific topics.

Format: [request-id, topic, enr, ticket]

func (*RegTopic) Encode

func (r *RegTopic) Encode() ([]byte, error)

Encode returns the RLP encoding of the REGTOPIC message

func (*RegTopic) Type

func (r *RegTopic) Type() byte

Type returns the message type

type RequestStats

type RequestStats struct {
	PendingRequests    int
	TotalRequests      int
	TimedOutRequests   int
	SuccessfulRequests int
	SuccessRate        float64
}

GetStats returns statistics about requests.

type RequestTracker

type RequestTracker struct {
	// contains filtered or unexported fields
}

RequestTracker manages pending requests and matches responses.

func NewRequestTracker

func NewRequestTracker(timeout time.Duration) *RequestTracker

NewRequestTracker creates a new request tracker.

func (*RequestTracker) AddRequest

func (rt *RequestTracker) AddRequest(requestID []byte, n *node.Node, msg Message) <-chan *Response

AddRequest registers a pending request.

The message and node parameters are stored for replay if the session becomes stale.

Returns a channel that will receive the response or timeout.

func (*RequestTracker) CancelRequest

func (rt *RequestTracker) CancelRequest(requestID []byte)

CancelRequest cancels a pending request.

func (*RequestTracker) CancelRequestsForNode

func (rt *RequestTracker) CancelRequestsForNode(nodeID node.ID) int

CancelRequestsForNode cancels all pending requests for a specific node.

This is useful when a session becomes invalid and we need to fail fast instead of waiting for timeouts.

Returns the number of requests canceled.

func (*RequestTracker) CleanupExpired

func (rt *RequestTracker) CleanupExpired() int

CleanupExpired removes expired requests.

Returns the number of requests cleaned up.

func (*RequestTracker) GetPendingRequestForNode

func (rt *RequestTracker) GetPendingRequestForNode(nodeID node.ID) *PendingRequest

GetPendingRequestForNode returns the first pending request for a specific node.

This is useful when we need to replay a message after re-establishing a session due to an unexpected WHOAREYOU.

Returns nil if no pending request exists for this node.

func (*RequestTracker) GetStats

func (rt *RequestTracker) GetStats() RequestStats

GetStats returns request statistics.

func (*RequestTracker) MatchResponse

func (rt *RequestTracker) MatchResponse(requestID []byte, nodeID node.ID, msg Message) bool

MatchResponse matches a response to a pending request.

Returns true if the request was matched and notified.

type Response

type Response struct {
	// Message is the decoded response message
	Message Message

	// NodeID is the responding node
	NodeID node.ID

	// Error is set if the request failed
	Error error
}

Response wraps a protocol message response.

type TalkReq

type TalkReq struct {
	// RequestID is a unique identifier for matching request/response pairs
	RequestID []byte

	// Protocol identifies the application protocol (e.g., "eth2")
	Protocol []byte

	// Request is the application-specific request data
	Request []byte
}

TalkReq is a generic application-level request.

This allows protocols to exchange custom messages over the discv5 transport without defining new message types.

Format: [request-id, protocol, request]

func (*TalkReq) Encode

func (t *TalkReq) Encode() ([]byte, error)

Encode returns the RLP encoding of the TALKREQ message

func (*TalkReq) Type

func (t *TalkReq) Type() byte

Type returns the message type

type TalkResp

type TalkResp struct {
	// RequestID matches the request ID from the TALKREQ
	RequestID []byte

	// Response is the application-specific response data
	Response []byte
}

TalkResp is the response to a TALKREQ message.

Format: [request-id, response]

func (*TalkResp) Encode

func (t *TalkResp) Encode() ([]byte, error)

Encode returns the RLP encoding of the TALKRESP message

func (*TalkResp) Type

func (t *TalkResp) Type() byte

Type returns the message type

type Ticket

type Ticket struct {
	RequestID []byte
	Ticket    []byte
	WaitTime  uint64
}

Ticket provides a ticket for topic registration (optional extension).

Format: [request-id, ticket, wait-time]

func (*Ticket) Encode

func (t *Ticket) Encode() ([]byte, error)

Encode returns the RLP encoding of the TICKET message

func (*Ticket) Type

func (t *Ticket) Type() byte

Type returns the message type

type TopicQuery

type TopicQuery struct {
	RequestID []byte
	Topic     []byte
}

TopicQuery queries for nodes on a topic (optional extension).

Format: [request-id, topic]

func (*TopicQuery) Encode

func (t *TopicQuery) Encode() ([]byte, error)

Encode returns the RLP encoding of the TOPICQUERY message

func (*TopicQuery) Type

func (t *TopicQuery) Type() byte

Type returns the message type

type Transport

type Transport interface {
	SendTo(data []byte, to *net.UDPAddr) error
	Send(data []byte, to *net.UDPAddr, from *net.UDPAddr) error
}

Transport interface for sending packets.

type WHOAREYOUChallenge

type WHOAREYOUChallenge struct {
	// IDNonce is a random challenge value (16 bytes)
	IDNonce []byte

	// ENRSeq is the highest ENR sequence number we have
	// The peer should send their ENR if their sequence is higher
	ENRSeq uint64
}

WHOAREYOUChallenge is sent when a node receives a packet from an unknown source.

It challenges the sender to prove their identity before establishing a session.

Format:

  • IDNonce: Random challenge nonce (16 bytes)
  • ENRSeq: Highest ENR sequence number we have for this node

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL