discv4

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: 11 Imported by: 0

Documentation

Overview

Package discv4 implements the Ethereum Discovery v4 protocol.

Discovery v4 is a UDP-based protocol for finding peers in the Ethereum network. It uses a Kademlia-style DHT for distributed node discovery with a bond mechanism to prevent amplification attacks.

Key features:

  • PING/PONG for liveness and endpoint verification
  • FINDNODE/NEIGHBORS for peer discovery
  • ENRREQUEST/ENRRESPONSE for ENR record exchange (EIP-868)
  • Bond mechanism (PING/PONG required before FINDNODE)
  • No encryption (packets are signed but not encrypted)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseNodeFromENR

func ParseNodeFromENR(record *enr.Record, addr *net.UDPAddr) (*node.Node, error)

ParseNodeFromENR creates a node from an ENR record.

func ParseNodeFromEnode

func ParseNodeFromEnode(enodeURL string) (*node.Node, error)

ParseNodeFromEnode creates a node from an enode:// URL.

Types

type Config

type Config struct {
	// PrivateKey is the node's private key (required)
	PrivateKey *ecdsa.PrivateKey

	// LocalENR is the node's ENR record (optional)
	// If provided, it will be shared via ENRRESPONSE
	LocalENR *enr.Record

	// BondExpiration is how long bonds last (default: 24 hours)
	// Bonds must be refreshed via PING/PONG before expiration
	BondExpiration time.Duration

	// RequestTimeout is how long to wait for request responses (default: 500ms)
	RequestTimeout time.Duration

	// ExpirationWindow is the acceptable time range for packet expiration (default: 20s)
	// Packets with expiration outside this window are rejected
	ExpirationWindow time.Duration

	// OnPing is called when a PING request is received
	OnPing protocol.OnPingCallback

	// OnFindnode is called when a FINDNODE request is received
	// Should return the list of nodes to include in the NEIGHBORS response
	OnFindnode protocol.OnFindnodeCallback

	// OnENRRequest is called when an ENRREQUEST is received
	OnENRRequest protocol.OnENRRequestCallback

	// OnNodeSeen is called when we receive any valid packet from a node
	// Useful for tracking last_seen timestamps in a database
	OnNodeSeen protocol.OnNodeSeenCallback

	// OnPongReceived is called when a PONG response is received
	// Contains our external IP/port as seen by the remote peer
	OnPongReceived protocol.OnPongReceivedCallback
}

Config contains configuration for the discv4 service.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns a configuration with sensible defaults.

You must set PrivateKey before using.

func (*Config) ApplyDefaults

func (c *Config) ApplyDefaults()

ApplyDefaults applies default values to unset configuration fields.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks if the configuration is valid.

type ConfigBuilder

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

ConfigBuilder provides a fluent interface for building configurations.

func NewConfigBuilder

func NewConfigBuilder() *ConfigBuilder

NewConfigBuilder creates a new configuration builder.

func (*ConfigBuilder) Build

func (b *ConfigBuilder) Build() (*Config, error)

Build returns the built configuration.

func (*ConfigBuilder) MustBuild

func (b *ConfigBuilder) MustBuild() *Config

MustBuild returns the built configuration or panics on error.

func (*ConfigBuilder) WithBondExpiration

func (b *ConfigBuilder) WithBondExpiration(d time.Duration) *ConfigBuilder

WithBondExpiration sets the bond expiration duration.

func (*ConfigBuilder) WithExpirationWindow

func (b *ConfigBuilder) WithExpirationWindow(d time.Duration) *ConfigBuilder

WithExpirationWindow sets the expiration window.

func (*ConfigBuilder) WithLocalENR

func (b *ConfigBuilder) WithLocalENR(record *enr.Record) *ConfigBuilder

WithLocalENR sets the local ENR record.

func (*ConfigBuilder) WithOnENRRequest

func (b *ConfigBuilder) WithOnENRRequest(cb protocol.OnENRRequestCallback) *ConfigBuilder

WithOnENRRequest sets the ENRREQUEST callback.

func (*ConfigBuilder) WithOnFindnode

func (b *ConfigBuilder) WithOnFindnode(cb protocol.OnFindnodeCallback) *ConfigBuilder

WithOnFindnode sets the FINDNODE callback.

func (*ConfigBuilder) WithOnNodeSeen

func (b *ConfigBuilder) WithOnNodeSeen(cb protocol.OnNodeSeenCallback) *ConfigBuilder

WithOnNodeSeen sets the OnNodeSeen callback.

func (*ConfigBuilder) WithOnPing

WithOnPing sets the PING callback.

func (*ConfigBuilder) WithOnPongReceived

func (b *ConfigBuilder) WithOnPongReceived(cb protocol.OnPongReceivedCallback) *ConfigBuilder

WithOnPongReceived sets the OnPongReceived callback.

func (*ConfigBuilder) WithPrivateKey

func (b *ConfigBuilder) WithPrivateKey(key *ecdsa.PrivateKey) *ConfigBuilder

WithPrivateKey sets the private key.

func (*ConfigBuilder) WithRequestTimeout

func (b *ConfigBuilder) WithRequestTimeout(d time.Duration) *ConfigBuilder

WithRequestTimeout sets the request timeout.

type Service

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

Service represents a discv4 service instance.

The service manages:

  • Protocol handler
  • Node database
  • Request routing

func New

func New(config *Config, transport Transport) (*Service, error)

New creates a new discv4 service.

The transport must be created first and passed to New(). The service will register its packet handler with the transport.

Example:

transport, _ := transport.NewUDPTransport(&transport.Config{
    ListenAddr: "0.0.0.0:30303",
})

privKey, _ := crypto.GenerateKey()
config := DefaultConfig()
config.PrivateKey = privKey

service, err := New(config, transport)
if err != nil {
    log.Fatal(err)
}
defer service.Stop()

func (*Service) AddBootstrapNode

func (s *Service) AddBootstrapNode(enodeURL string) error

AddBootstrapNode adds a bootstrap node from an enode URL.

func (*Service) AddNode

func (s *Service) AddNode(n *node.Node)

AddNode adds a node to the known nodes list.

This is useful for adding bootstrap nodes.

func (*Service) AllNodes

func (s *Service) AllNodes() []*node.Node

AllNodes returns all known nodes.

func (*Service) BondedNodes

func (s *Service) BondedNodes() []*node.Node

BondedNodes returns all bonded nodes.

func (*Service) Findnode

func (s *Service) Findnode(n *node.Node, target []byte) ([]*node.Node, error)

Findnode sends a FINDNODE request to discover nodes near a target.

The node must have an active bond (will automatically PING if needed). Returns a list of discovered nodes.

func (*Service) GetNode

func (s *Service) GetNode(id node.ID) *node.Node

GetNode returns a known node by ID.

func (*Service) IsRunning

func (s *Service) IsRunning() bool

IsRunning returns whether the service is currently running.

func (*Service) LocalAddr

func (s *Service) LocalAddr() *net.UDPAddr

LocalAddr returns the local listening address.

func (*Service) LocalENR

func (s *Service) LocalENR() *enr.Record

LocalENR returns the local ENR record (if configured).

func (*Service) LocalEnode

func (s *Service) LocalEnode() string

LocalEnode returns the local enode:// URL.

func (*Service) LocalNodeID

func (s *Service) LocalNodeID() node.ID

LocalNodeID returns the local node ID.

func (*Service) LookupRandom

func (s *Service) LookupRandom() ([]*node.Node, error)

LookupRandom performs a random node lookup.

This is useful for populating the routing table with random nodes.

func (*Service) Ping

func (s *Service) Ping(n *node.Node) (*protocol.Pong, error)

Ping sends a PING request to a node.

This establishes a bond with the node and verifies liveness. Returns the PONG response or an error.

func (*Service) PingAddr

func (s *Service) PingAddr(enodeURL string) (*protocol.Pong, error)

PingAddr sends a PING to a node identified by address.

This is a convenience method that creates a temporary node from an enode URL.

func (*Service) RequestENR

func (s *Service) RequestENR(n *node.Node) (*enr.Record, error)

RequestENR requests a node's ENR record.

Returns the ENR record or an error.

func (*Service) SetLocalENR

func (s *Service) SetLocalENR(record *enr.Record)

SetLocalENR updates the local ENR record.

This should be called when the ENR is updated (e.g., IP change).

func (*Service) Start

func (s *Service) Start() error

Start starts the discv4 service.

Note: The transport is started separately and passed to New(). This method is kept for compatibility and lifecycle management.

func (*Service) Stats

func (s *Service) Stats() map[string]interface{}

Stats returns service statistics.

func (*Service) Stop

func (s *Service) Stop() error

Stop stops the discv4 service.

Note: This does NOT close the transport as it's managed externally. The caller is responsible for closing the transport.

type Transport

type Transport interface {
	protocol.Transport
	LocalAddr() *net.UDPAddr
	AddHandler(handler func(data []byte, from *net.UDPAddr, localAddr *net.UDPAddr) bool)
}

Transport is the interface for sending packets. It must have a LocalAddr() method to get the bind address.

Directories

Path Synopsis
Package node implements the Node representation for discv4.
Package node implements the Node representation for discv4.
Package protocol implements the Discovery v4 wire protocol.
Package protocol implements the Discovery v4 wire protocol.

Jump to

Keyboard shortcuts

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