Skip to main content
  1. Posts/

Introducing Bitcoin nodes' boostrap process and its protocol

·532 words

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 Size Description Data type Comments
4 magic uint32_t for REGTEST: 0xDAB5BFFA
12 command char[12] NULL padded
4 length uint32_t Length of payload bytes
4 checksum uint32_t First 4 bytes of sha256(sha256(payload))
? payload uchar[] 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 Size Description Data type Comments
4 version uint32_t the protocol version
1+ hash count var_int number of block locator hash entries
32+ block locator hashes char[32] block locator object
32 hash_stop char[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