Discovery protocols are essential for blockchain P2P networks as they enable nodes to find and connect to each other without needing pre-configured addresses. This chapter provides comprehensive coverage of how blockchain nodes discover peers, including Ethereum’s DiscV5, DNS discovery, and bootnode infrastructure.
┌─────────────────────────────────────────────────────────────────────────────┐
├─────────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ DISCV5 (Discovery V5) │ │
│ │ • Current Ethereum discovery protocol │ │
│ │ • Kademlia-based DHT │ │
│ │ • Supports topic advertisement │ │
│ │ • ENR-based node records │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ • Domain name-based node lists │ │
│ │ • Used by many blockchain networks │ │
│ │ • Reliable and easy to maintain │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ • Pre-configured trusted nodes │ │
│ │ • Entry point for new nodes │ │
│ │ • Fallback when DHT fails │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Method Type Complexity Reliability Use Case DiscV5 DHT High High Ethereum mainnet DNS Discovery Static Low Very High All networks Bootnodes Static Low High All networks Static Peers Manual Very Low Medium Private networks
┌─────────────────────────────────────────────────────────────────┐
├─────────────────────────────────────────────────────────────────┤
│ Each node has a unique node ID (256-bit random number) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ KADEMLIA TABLE (k-buckets) │ │
│ │ Bucket 0: Nodes with very similar ID (distance 0-1) │ │
│ │ Bucket 1: Nodes with distance 1-2 │ │
│ │ Bucket 2: Nodes with distance 2-4 │ │
│ │ Bucket 255: Nodes with very different ID │ │
│ │ Each bucket holds up to k=16 nodes │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. Calculate distance between my ID and target ID │ │
│ │ 2. Query closest nodes in relevant buckets │ │
│ │ 3. Repeat with closer nodes until can't find closer │ │
│ │ 4. Return k closest nodes found │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
--discv5.listenaddr " 0.0.0.0:30303 " \
--discv5.discoverylimit 100 \
--discv5.netrestrict " 10.0.0.0/8 "
# Check DiscV5 status via RPC
# eth.nodeInfo returns ENR with discv5 info
# Lighthouse (Ethereum consensus)
┌─────────────────────────────────────────────────────────────────┐
├─────────────────────────────────────────────────────────────────┤
│ ENR is a signed, self-certifying record containing: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ ─────────────────── │ │
│ │ - seq: Sequence number (incremented on each update) │ │
│ │ - id: Protocol identifier (e.g., "v4") │ │
│ │ - secp256k1: Compressed public key │ │
│ │ - ip: IPv4 address │ │
│ │ - tcp: TCP port (optional) │ │
│ │ - udp: UDP port (optional) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ COMMON OPTIONAL FIELDS: │ │
│ │ ──────────────────────── │ │
│ │ - ip6: IPv6 address │ │
│ │ - tcp6: IPv6 TCP port │ │
│ │ - udp6: IPv6 UDP port │ │
│ │ - eth: Ethereum chain data │ │
│ │ - chainId: Chain identifier │ │
│ │ - network: Network ID │ │
│ │ - genesis: Genesis hash │ │
│ │ - forkId: Current fork identifier │ │
│ │ - attnets: Attestation subnet bits │ │
│ └─────────────────────────────────────────────────────────┘ │
│ enr:-KG4QOtcL...@bootnode.mainnet.ethdisco.net:30303 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ DNS DISCOVERY WORKFLOW │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐
│ └────┬─────┘ └────┬─────┘
│ │ 1. Query DNS for ethereum nodes │
│ │─────────────────────────────────────────────────────▶│
│ │ 2. Return list of ENR records │
│ │◀────────────────────────────────────────────────────│
│ │ 3. Connect to discovered nodes │
│ │─────────────────────────────────────────────────────▶│
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ nodes.ethereum.org IN TXT "enr:-I..@1.2.3.4:30303" │ │
│ │ nodes.ethereum.org IN TXT "enr:-I..@5.6.7.8:30303" │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
# Geth with DNS discovery
--discovery.dns " nodes.ethereum.org " \
--dns.anchors " enr:-Iu4... "
# Use multiple DNS servers
--discovery.dns " dns1.example.com,dns2.example.com "
# Custom DNS configuration
--discovery.dns " my-nodes.example.com " \
--discovery.dnsseg " nodes "
# v=1; e=<ENR-base64>; ip=<IPv4>; ip6=<IPv6>; tcp=<port>; udp=<port>
nodes.example.com IN TXT "v=1; e=nP3Z...; ip=1.2.3.4; tcp=30303; udp=30303"
┌─────────────────────────────────────────────────────────────────┐
│ BOOTNODE ARCHITECTURE │
├─────────────────────────────────────────────────────────────────┤
│ Bootnodes serve as entry points to the P2P network: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ └────────────────────────┬────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ (well-known, always online) │ │
│ │ Mainnet Bootnodes: │ │
│ │ ┌────────────────────────────────────────────────┐ │ │
│ │ │ enr:-KG4QO...@bootnode1.ethdisco.net:30303 │ │ │
│ │ │ enr:-L4sU...@bootnode2.ethdisco.net:30303 │ │ │
│ │ │ enr:-LK4UC...@bootnode3.ethdisco.net:30303 │ │ │
│ │ └────────────────────────────────────────────────┘ │ │
│ └────────────────────────┬────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ New node now has peers and can continue discovering │ │
│ │ more peers through the network │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
# Default bootnodes (built into client)
--bootnodes " enr:-KG4QO...@1.2.3.4:30303,enr:-LK4UC...@5.6.7.8:30303 "
# Bootnodes for different networks
geth --goerli --bootnodes " enr:-K64Q... "
geth --sepolia --bootnodes " enr:-MS4L... "
--nodekey /path/to/nodekey \
--writeaddress # Print ENR to use
Network DNS Discovery ENR List Ethereum Mainnet nodes.ethereum.orgethdisco.net Goerli nodes.goerli.ethdevops.io- Sepolia nodes.sepolia.ethdevops.io-
# Check if node is discoverable
geth attach http://localhost:8545
# Check discovery service logs
journalctl -u geth | grep -i discv5
journalctl -u geth | grep -i discovery
nslookup bootnode.mainnet.ethdisco.net
Issue Cause Solution No peers found Discovery disabled Enable --v5disc or --discovery.dns Firewall blocking UDP blocked Allow UDP 30303 Wrong network Using testnet bootnodes on mainnet Use correct bootnode list NAT issue Port not forwarded Configure port forwarding
Question Answer What is DiscV5? Ethereum’s Kademlia-based discovery protocol What is an ENR? Ethereum Node Record - self-certifying node metadata How do bootnodes work? Pre-configured nodes that new nodes connect to initially What is DNS discovery? Using DNS TXT records to find node ENR addresses Why is peer discovery important? Enables decentralized network without central servers
DiscV5 is the primary Ethereum discovery protocol
DNS discovery provides reliable fallback
Bootnodes are essential for network entry
ENR contains all node metadata
Proper configuration ensures good network connectivity
In Chapter 25: Network Ports & Firewall Configuration , we’ll explore port configuration and security.
Last Updated: 2026-02-20