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
- Variables
- func BuildHandshakeHeaderData(localNodeID node.ID, nonce []byte, signature, ephPubkey, enrBytes []byte) ([]byte, []byte, error)
- func BuildOrdinaryHeaderData(localNodeID node.ID, nonce, authdata []byte) ([]byte, []byte, error)
- func BuildWHOAREYOUChallengeData(maskingIV, nonce []byte, challenge *WHOAREYOUChallenge) []byte
- func EncodeHandshakePacket(localNodeID, destNodeID node.ID, maskingIV, nonce []byte, ...) ([]byte, error)
- func EncodeOrdinaryPacket(localNodeID, destNodeID node.ID, maskingIV, nonce []byte, authdata []byte, ...) ([]byte, error)
- func EncodePacket(packet *Packet) ([]byte, error)
- func EncodeRandomPacket(localNodeID, destNodeID node.ID) ([]byte, error)
- func EncodeWHOAREYOUPacket(destNodeID node.ID, nonce []byte, challenge *WHOAREYOUChallenge) ([]byte, []byte, error)
- func NewRequestID() ([]byte, error)
- type FindNode
- type Handler
- func (h *Handler) GetStats() HandlerStats
- func (h *Handler) HandleIncomingPacket(data []byte, from *net.UDPAddr, localAddr *net.UDPAddr) error
- func (h *Handler) Requests() *RequestTracker
- func (h *Handler) SendFindNode(n *node.Node, distances []uint) (<-chan *Response, error)
- func (h *Handler) SendMessage(msg Message, remoteID node.ID, to *net.UDPAddr, remoteNode *node.Node) error
- func (h *Handler) SendMessageFrom(msg Message, remoteID node.ID, to *net.UDPAddr, remoteNode *node.Node, ...) error
- func (h *Handler) SendPing(n *node.Node) (<-chan *Response, error)
- func (h *Handler) SetTransport(transport Transport)
- type HandlerConfig
- type HandlerStats
- type HandshakeData
- type Message
- type Nodes
- type OnFindNodeCallback
- type OnHandshakeCompleteCallback
- type OnNodeSeenCallback
- type OnNodeUpdateCallback
- type OnPongReceivedCallback
- type OnTalkReqCallback
- type Packet
- type PacketHeader
- type PendingChallenge
- type PendingHandshake
- type PendingRequest
- type Ping
- type Pong
- type ProtocolError
- type RegConfirmation
- type RegTopic
- type RequestStats
- type RequestTracker
- func (rt *RequestTracker) AddRequest(requestID []byte, n *node.Node, msg Message) <-chan *Response
- func (rt *RequestTracker) CancelRequest(requestID []byte)
- func (rt *RequestTracker) CancelRequestsForNode(nodeID node.ID) int
- func (rt *RequestTracker) CleanupExpired() int
- func (rt *RequestTracker) GetPendingRequestForNode(nodeID node.ID) *PendingRequest
- func (rt *RequestTracker) GetStats() RequestStats
- func (rt *RequestTracker) MatchResponse(requestID []byte, nodeID node.ID, msg Message) bool
- type Response
- type TalkReq
- type TalkResp
- type Ticket
- type TopicQuery
- type Transport
- type WHOAREYOUChallenge
Constants ¶
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
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)
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 )
const DefaultRequestTimeout = 5 * time.Second
DefaultRequestTimeout is the default timeout for requests (5 seconds).
Variables ¶
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 ¶
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 ¶
EncodePacket encodes a complete packet to bytes.
Format:
- Header (32 bytes)
- Auth data (variable, size specified in header)
- Message data (remaining bytes)
func EncodeRandomPacket ¶
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 ¶
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, ...]]
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 ¶
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 ¶
SendPing sends a PING to a remote node.
Returns a channel that will receive the PONG response.
func (*Handler) SetTransport ¶
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, ...]]
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 ¶
OnHandshakeCompleteCallback is called when a handshake completes successfully.
type OnNodeSeenCallback ¶
OnNodeSeenCallback is called when a node is seen (receives a message). This is useful for tracking last_seen timestamps in the database.
type OnNodeUpdateCallback ¶
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 ¶
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 ¶
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]
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]
type ProtocolError ¶
ProtocolError represents a protocol-level error.
func (*ProtocolError) Error ¶
func (e *ProtocolError) Error() string
type RegConfirmation ¶
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
type RegTopic ¶
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]
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 ¶
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 ¶
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]
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]
type Ticket ¶
Ticket provides a ticket for topic registration (optional extension).
Format: [request-id, ticket, wait-time]
type TopicQuery ¶
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
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