The P2P Protocol & Message Types
There is no bitcoin.com server that hands you the blockchain. When your node starts, it dials a handful of other volunteers’ machines directly, introduces itself, and from then on everything — transactions, blocks, addresses of more peers — arrives as messages gossiped between equals. This page is the grammar of that conversation: how a node joins a flat, permissionless mesh and the handful of message types that make the whole network run.
A flat, permissionless mesh
Section titled “A flat, permissionless mesh”Every node is both client and server. There are no privileged hubs, no logins, no accounts. Anyone can join by speaking the protocol; anyone can leave; no one can stop you. A typical node keeps a modest number of simultaneous connections — a few outbound ones it chose itself plus some inbound ones from peers that dialed it. That small, partly self-chosen set of neighbors is the node’s only window onto the network, which is exactly why who you connect to matters so much for security (see network attacks).
Finding the first peers
Section titled “Finding the first peers”A brand-new node faces a bootstrapping problem: it knows no one. It solves this with a few fallbacks:
- DNS seeds — hard-coded domain names run by community members that resolve to lists of recently active node IPs.
- Hard-coded seed nodes — a small built-in list, used if DNS fails.
addrgossip — once connected to even one peer, the node asks for more and is told about others (see below). From then on it’s self-sustaining.
The handshake: version / verack
Section titled “The handshake: version / verack”Before two peers exchange any data, they perform a short, mandatory handshake so each learns the other’s software version, capabilities (service bits), and block height.
NODE A (dials) NODE B (listens) | | | ── version ───────────────────────────────────►| "Hi, I'm protocol v70016, | | I have 840000 blocks, here's | | what services I offer." | | |◄──────────────────────────────── version ───────| B replies with its own version | | | ── verack ─────────────────────────────────────►| "Got your version, ack." |◄──────────────────────────────── verack ─────────| "Got yours too, ack." | | |======== handshake complete; link is live ========| | | | ── getaddr / inv / getheaders ... ─────────────►| normal gossip beginsIf either side dislikes what it sees (an ancient protocol version, a missing required service), it
simply hangs up. Only after both veracks does real traffic flow.
The core message vocabulary
Section titled “The core message vocabulary”Once connected, peers exchange typed messages. You only need a handful to understand the whole system:
| Message | Direction | Meaning |
|---|---|---|
version / verack | both | The handshake above. |
addr / getaddr | both | ”Here are peers I know about” / “Tell me peers you know.” Spreads connectivity. |
inv (inventory) | announce | ”I have item X” — a tx or block, identified by hash. Lightweight advertisement. |
getdata | request | ”Send me the full item for hash X.” Issued in response to an interesting inv. |
tx | data | The full serialized transaction. |
block | data | A full serialized block. |
getheaders | request | ”Give me headers starting after these block hashes.” Used to sync the chain. |
headers | data | A batch of block headers (no transactions). |
ping / pong | both | Keep-alive and latency check; detects dead connections. |
The decisive design choice is the announce-then-request split: a peer first sends a tiny inv
(“I have this”), and you only spend bandwidth on getdata if you don’t already have it. This avoids
shipping the same megabyte block to a peer who already received it from someone else — the foundation
of efficient transaction and block propagation.
Putting it together: a tiny session
Section titled “Putting it together: a tiny session”A → B: version A → B: getheaders B → A: inv (new block 840001)A → B: verack B → A: headers (2000) A → B: getdata (block 840001)B → A: version A: verify PoW on headers B → A: block (full)B → A: verack A → B: getdata (bodies) A: validate, then inv it onwardNotice there is no coordinator anywhere in this trace. Two strangers shook hands, compared chains, and swapped data — and that same pattern, repeated across the whole mesh, is how a new block reaches the entire planet in seconds.
The thread
Section titled “The thread”How does this help untrusting strangers agree on one ledger? The protocol is deliberately dumb and symmetric: it moves bytes between equals and assumes nothing about who’s honest. Trust isn’t built into the wire format — it’s enforced after delivery, when each node validates what it received against the rules. The P2P layer’s only job is to make sure every honest node can hear about every transaction and block, so that independent verification has something to verify.
Check your understanding
Section titled “Check your understanding”- Why does Bitcoin have no central server, and how does a brand-new node find its first peers?
- Walk through the
version/verackhandshake. What can cause a peer to refuse the connection? - What problem does the
inv→getdatasplit solve, versus blindly pushing every transaction to every peer? - Why does the protocol let you download
headersseparately from fullblockbodies? - The P2P protocol does almost no trust-checking itself. Where, then, does trust-minimization actually happen?