Initial Peer Discovery in Bitcoin

·

6 min read

Initial Peer Discovery in Bitcoin

In the Bitcoin Network, Peer- Discovery is an essential process that ensures nodes can effectively connect and exchange information. This plays a critical role in securing the network by ensuring blocks are propagated and transactions can be validated, forming the core basis of how the network operates.

If you are in the Bitcoin ecosystem, you've probably heard this statement "Run your own node, it's great for the network".(Check out this guideon why that is). But have you ever wondered how a first-time node would initially get connected to other nodes and become part of the network? In this article, we will explore the most convenient way a new node would get connected.

BitcoinCore has a list of DNS seeds that a new node can use to connect to other peers.

Before diving deep let's first cover the basics.

What is a Domain Name Service(DNS)?

Currently, if you want to Google something you'd have to type google.com into your browser. Imagine if, instead, you had to use an IPv4 address like '8.8.8.8' or an IPv6 address like '2001:4860:4860::8888'. That would be hard, right? This is where DNS comes in, after you type the domain name into your browser, DNS is responsible for translating that domain name into an IP address.

What is a Transmission Control Protocol(TCP) connection?

For information to be successfully passed down through a network, the data is first broken down into smaller chunks called packets. TCP is a messaging standard that orders and checks the validity of the packets of data being transported and establishes the transmission of that data. This connection is established through a three-way handshake process.

Identifying DNS Seeds

First, a new node would need to identify a set of DNS seeds that are relevant to its network.

In Bitcoin Core, there's a list of 7 hardcoded DNS seeds that have domain names pointing to public DNS servers. The reference to this list can be found in this file: https://github.com/bitcoin/bitcoin/blob/master/src/kernel/chainparams.cpp#L134

Each DNS seed supports different node services. For example, seed.bitcoin.sipa.be supports x1, x5, x9, and xd. These codes represent service flags that indicate a node's capabilities.

X1 corresponds to the NODE_NETWORK service (full node) with a value of 0x01.

X5 indicates support for both NODE_NETWORK (0x01) and NODE_BLOOM (supports bloom filters, 0x04). The bitwise OR of these two values results in 0x05.

X9 signifies a node that supports NODE_NETWORK and NODE_WITNESS (downloads witness data), with values 0x01 and 0x08 respectively. Their bitwise OR results in 0x09.


 vSeeds.emplace_back("seed.bitcoin.sipa.be."); // Pieter Wuille, only supports x1, x5, x9, and xd
 vSeeds.emplace_back("dnsseed.bluematt.me."); // Matt Corallo, only supports x9
 vSeeds.emplace_back("dnsseed.bitcoin.dashjr.org."); // Luke Dashjr
 vSeeds.emplace_back("seed.bitcoinstats.com."); // Christian Decker, supports x1 - xf
 vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch."); // Jonas Schnelli, only supports x1, x5, x9, and xdvSeeds.emplace_back("seed.btc.petertodd.net."); // Peter Todd, only supports x1, x5, x9, and xd
 vSeeds.emplace_back("seed.bitcoin.sprovoost.nl."); // Sjors Provoost
 vSeeds.emplace_back("dnsseed.emzy.de."); // Stephan Oeste
 vSeeds.emplace_back("seed.bitcoin.wiz.biz."); // Jason Maurice

Query DNS Server

An example of how to query the DNS seeds provided and to Perform an "A record lookup" is by using $ dig seed.bitcoin.sipa.be command on a terminal. The output will include a list of IPv4 addresses belonging to the full nodes in Bitcoin main net that are associated with seed.bitcoin.sipa.be DNS server.

; ANSWER SECTION:
seed.bitcoin.sipa.be.    3600    IN    A    165.22.0.113
seed.bitcoin.sipa.be.    3600    IN    A    83.78.112.142
seed.bitcoin.sipa.be.    3600    IN    A    174.7.106.8
seed.bitcoin.sipa.be.    3600    IN    A    205.250.189.74
seed.bitcoin.sipa.be.    3600    IN    A    109.99.63.159
seed.bitcoin.sipa.be.    3600    IN    A    34.71.60.191
seed.bitcoin.sipa.be.    3600    IN    A    85.145.79.26
seed.bitcoin.sipa.be.    3600    IN    A    144.6.88.141

Establish a Connection

After obtaining an IP address the node can now attempt to establish a TCP connection and create an initial handshake. For this process to be successful the two nodes have to be compatible with each other. The new node initiates a compatibility check by sending a version message to the receiver node.

The following information is included in the version message:

Protocol Version: This represents the version of a node and is especially important because different protocol versions might have different changes introduced through each upgrade. To check protocol versions using RPC one can run bitcoin-cli getnetworkinfo sample output for bitcoin core version 26 is:"protocolversion": 70016

Services: A standard list of services that nodes support, for example, if a node supports bloom filters it will have NODE_BLOOM in its service list. By checking the network info one can view the list of services that its node has to offer: "localservicesnames": [ "NETWORK", "WITNESS", "NETWORK_LIMITED", "P2P_V2" ],

Timestamp: Represents the current time of a node in UNIX time. This field is important because nodes will not accept a connection to another node that has blocks with more than two hours in the future[source] example output:1666812142

Receiver Node IP Address: The addr_recv field is the IPV6 or an IPv4-mapped IPv6 address of the receiving node(i.e. the node that the new node is trying to connect to)example.::ffff:127.0.0.1

Transmitting Node IP Address: The addr_trans field of the new node looking to make a connection. It can also be IPV6 or an IPv4-mapped IPv6 address, if the field is not set, a default is usually provided, for example ::ffff:0808:0808.

Nonce: A randomly generated unique value that a node includes in the version message to verify the connection. the receiving node will terminate the connection if it receives a nonce with a non-zero value from the same peer:example 987654321

User Agent: A string Field that identifies the client a node is running on and its version example "/Satoshi:26.99.0/"

Verack Message

After the new node has sent a version message, the receiver node responds with a Verack message. This acts as an acknowledgment of the compatibility between the nodes and is an indicator that both nodes can send each other messages.

Reconnection Process

Once the initial connection is established, adjacent nodes will start sending a request for the IP address of the new node and the gossiping process will continue.

If a node gets disconnected and reconnects it doesn't have to query the DNS seeds again. Instead, it queries its own database to obtain the IP addresses of other nodes.

Peers.dat File
This file stores information about peer nodes after a connection has been established. The sample output below is from a Python script that reads from the file. This information will include the timestamp of each node, the IP addresses of the connected nodes, the ports, as well as a hexadecimal representation of each service that a node has to offer.

Timestamp: Not available
IP Address: 34.0.0.0
Port: 53763
Services: 245203977922563

Timestamp: Not available
IP Address: 0.0.203.1
Port: 0
Services: 11962123564141969408

Timestamp: Not available
IP Address: 9.4.0.0
Port: 0
Services: 0

Timestamp: Not available
IP Address: 0.0.0.0
Port: 0
Services: 72057594759479296

Conclusion

While DNS seeds offer a convenient way to bootstrap connections in Bitcoin core, the reliance on centralized servers introduces security risks, as DNS servers could be hijacked to supply malicious IP addresses to nodes. Node operators that use the hardcoded list do so for convenience and not because it's the only way. There are other ways to connect to peers for the first time; for example, a node could manually connect to a node they believe to be honest.

Additionally, for Bitcoin Core, there are expectations that every DNS Seed Provider must meet to be added to or remain on the list. You can read more about these requirements here.

Want to dive deeper into peer discovery in Bitcoin? Check out these resources!

https://developer.bitcoin.org/reference/p2p_networking.html#protocol-versions
https://raghavsood.com/blog/2018/05/20/demystifying-peers-dat

https://learn.saylor.org/mod/book/view.php?id=36307&chapterid=18899

https://bitcoin.stackexchange.com/questions/103495/how-do-network-nodes-connect-amateur-level