Jaehong Jung

Introducing Bitcoin nodes' boostrap process and its protocol

bitcoinnetwork

Introduction

attachments/bitcoin-handshake.png

Open Image in New Tab

During my undergraduate internship in the KAIST NetS&P lab, I needed to find out how Bitcoin nodes communicate when joining a distributed network for the first time. Specifically, I wanted to understand what information is exchanged between nodes and known hosts or seed nodes during this initial connection. To investigate this, I utilized Wireshark to capture packets and analyze the communication process. And find out that the handshake required for Bitcoin nodes involves a streamlined set of messages, as detailed above.

The commands and protocols exchanged during this process are critical for establishing reliable connections and data sharing. For a more in-depth understanding, I’ve referenced various Bitcoin Protocol and BEP official documentation throughout this exploration.

Bitcoin protocol

Messages

Bitcoin nodes communicate with Bitcoin protocol which follows the protocol documentation like below (which is built on top on TCP)

Messages which are bitcoin protocol have common structures like the table below +) Almost all integers are encoded in little endian. Only IP or port number are encoded big endian. All field sizes are numbers of bytes

Field SizeDescriptionData typeComments
4magicuint32_tfor REGTEST: 0xDAB5BFFA
12commandchar[12]NULL padded
4lengthuint32_tLength of payload bytes
4checksumuint32_tFirst 4 bytes of sha256(sha256(payload))
?payloaduchar[]Actual data

version

Advertise its version

wtxiderelay

BIP339

  • Send prior to verack
  • For only protocol both 70016 or higher
Payload

Empty payload for this command

sendaddrv2

BIP155 Prefer to receive addrv2 than addr

  • Must send as response to version
  • and send prior to verack

verack

sent reply to version

getaddr

asking information about active peers

sendcmpct

BIP152

  • Payload length is 9
  • For only protocol both 70014 or higher

Payload (9bytes) = 1byte (boolean) + 8bytes

Example Payload: 0 2 0 0 0 0 0 0 If first and second bytes are

  • 1 and 1 → new blocks by cmpctblock (BIP130)
  • 0 and * → new blocks by inv and headers (BIP130)
  • * and not 1 → not received any message

ping

confirm TCP/IP connection is valid with random nonce

pong

response to ping with nonce from ping

getheaders

requests the peer for headers message

Example Payload.

  • version: 70016
  • hash_count: 1
  • block_locator_hashes: [GENESIS_BLOCK_HASH] In other words, starting hash
  • hash_stop: 0 In other words, stop_hash. When it is set to zero, get as many blocks as possible (Max. 2000)

So, for getheaders message, it requests the opposite nodes to send block hashes starting from block_locator_hashes until hash_stop.

Payload
Field SizeDescriptionData typeComments
4versionuint32_tthe protocol version
1+hash countvar_intnumber of block locator hash entries
32+block locator hasheschar[32]block locator object
32hash_stopchar[32]hash of the last desired block header

feefilter

Instruct peers not to send invs for transactions with fees below specific value. → due to limited memepool

  • For only protocol both 70013 or higher

headers

returns block header response to getheaders message.

sendheaders

prefer to receive headers message than inv

  • For only protocol both 70012 or higher

Reference

  1. Protocol Wiki
  2. Part1. P2P Protocol
  3. Part2. P2P Protocol
  4. Bitcoin mining
  5. Deep dive into bitcoin header
  6. nBits to target(difficulty)
  7. Creating and verifying Tx
  8. Sighash type in Tx