<p>Yes, this is supported by the P2P protocol. In fact, in the very first release of the Bitcoin software there was no way to ask for headers separately.</p>
<p>The process works roughly like this:</p>
<ul>
<li>A sends <code>getblocks</code> to B (with a &quot;locator&quot;, that roughly informs B about what the last block is that A already has).</li>
<li>B responds with <code>inv</code> message containing (up to) 500 block hashes (just the hashes, not the full headers), starting from the last block A and B have in common.</li>
<li>A then decides which of those block hashes it does not yet know, and sends a <code>getdata</code> request to fetch those.</li>
<li>B then responds by sending <code>block</code> messages for each of the requested blocks.</li>
<li>When A reaches the end of the 500 hashes in the <code>inv</code>, it issues another <code>getblocks</code>, now with an updated locator, so the process can restart with further blocks.</li>
</ul>
<p>The big downside of this approach is that the progress is &quot;in the dark&quot; - A does not know if the blocks it is receiving from B will amount to anything interesting (e.g. they could be from an old fork, or even a low-work attack chain), which A will only notice when it has downloaded and processed them all. The headers-first synchronization gives A the ability to decide whether the chain is interesting before trying to actually download it, with only a marginal bandwidth increase (block hashes are 32 bytes, block headers are 81 bytes each).
With headers-first, the process is instead:</p>
<ul>
<li>A sends a <code>getheaders</code> to B, with a locator corresponds to the best <em>header</em> it has so far.</li>
<li>B responds with a <code>headers</code> message, containing up to 2000 headers starting at the last common header A and B have.</li>
<li>A processes those headers, and sends another <code>getheaders</code> from the newly updated best header it has, repeating the process, gathering all the headers.</li>
<li>At some point, A decides that the headers it has received from B are a sufficiently interesting chain (= its accumulated proof of work is high enough). When this happens, it starts sending <code>getdata</code> messages to B for the blocks along the header chain it lacks.</li>
<li>B responds to those using <code>block</code> messages, which A can process normally.</li>
</ul>

CC BY-SA 4.0
2023-09-04T15:51:08.623Z
Fine. And how a peer identify a "chain" on the network ? Because there's no "chain message", there's no peer who suggests his chain-work.
Loopite
CC BY-SA 4.0
2023-09-04T15:54:11.400Z
@Loopite Using exactly the same mechanism! Nodes are *always* synchronizing. All they have to do is start this synchronization mechanism to learn about whatever chains their peers have (thus, sending `getblocks` or `getheaders`).
Pieter Wuille
CC BY-SA 4.0
2023-09-04T16:06:11.433Z
I already got that part. However, I don't understand to whom peer the client will ask ? If I'm connected to 110 peers ? Who must receive header requests ?
Loopite
CC BY-SA 4.0
2023-09-04T16:16:28.987Z
You ask all your peers for their headers/blocks. If they don't have any you don't have, no problem, the process will be very fast. To avoid duplicate work, Bitcoin Core only starts header sync from one random peer (switching over to another if it's too slow) when it's a lot behind, but eventually will ask all of them.
Pieter Wuille
CC BY-SA 4.0
2023-09-03T20:06:45.823Z
2023-09-03T20:22:24.873Z
2023-09-03T20:22:24.873Z
Pieter Wuille
<p>I would like to know if there's a way to download a blockchain without knowing block headers. This could be achieved by asking NEXT_BLOCK_HASH from the genesis block. But is this even possible ?</p>

<network><full-node><synchronization><nodes><p2p>
Is there a way to download blocks from scratch without downloading block headers first?
Loopite
# Is there a way to download blocks from scratch without downloading block headers first?

(Asked by: username_0 on 2023-09-03)

I would like to know if there's a way to download a blockchain without knowing block headers. This could be achieved by asking NEXT\_BLOCK\_HASH from the genesis block. But is this even possible ?

**Tags:** network, full-node, synchronization, nodes, p2p


---

## 1 answers

### Answer by username_1 on 2023-09-03. Score: 2 | Accepted answer

Yes, this is supported by the P2P protocol. In fact, in the very first release of the Bitcoin software there was no way to ask for headers separately.

The process works roughly like this:

* A sends `getblocks` to B (with a "locator", that roughly informs B about what the last block is that A already has).
* B responds with `inv` message containing (up to) 500 block hashes (just the hashes, not the full headers), starting from the last block A and B have in common.
* A then decides which of those block hashes it does not yet know, and sends a `getdata` request to fetch those.
* B then responds by sending `block` messages for each of the requested blocks.
* When A reaches the end of the 500 hashes in the `inv`, it issues another `getblocks`, now with an updated locator, so the process can restart with further blocks.

The big downside of this approach is that the progress is "in the dark" - A does not know if the blocks it is receiving from B will amount to anything interesting (e.g. they could be from an old fork, or even a low-work attack chain), which A will only notice when it has downloaded and processed them all. The headers-first synchronization gives A the ability to decide whether the chain is interesting before trying to actually download it, with only a marginal bandwidth increase (block hashes are 32 bytes, block headers are 81 bytes each).
With headers-first, the process is instead:

* A sends a `getheaders` to B, with a locator corresponds to the best *header* it has so far.
* B responds with a `headers` message, containing up to 2000 headers starting at the last common header A and B have.
* A processes those headers, and sends another `getheaders` from the newly updated best header it has, repeating the process, gathering all the headers.
* At some point, A decides that the headers it has received from B are a sufficiently interesting chain (= its accumulated proof of work is high enough). When this happens, it starts sending `getdata` messages to B for the blocks along the header chain it lacks.
* B responds to those using `block` messages, which A can process normally.

> **Comments:**
> **username_0**: Fine. And how a peer identify a "chain" on the network ? Because there's no "chain message", there's no peer who suggests his chain-work.  
> **username_1**: @username_0 Using exactly the same mechanism! Nodes are *always* synchronizing. All they have to do is start this synchronization mechanism to learn about whatever chains their peers have (thus, sending `getblocks` or `getheaders`).  
> **username_0**: I already got that part. However, I don't understand to whom peer the client will ask ? If I'm connected to 110 peers ? Who must receive header requests ?  
> **username_1**: You ask all your peers for their headers/blocks. If they don't have any you don't have, no problem, the process will be very fast. To avoid duplicate work, Bitcoin Core only starts header sync from one random peer (switching over to another if it's too slow) when it's a lot behind, but eventually will ask all of them.  

---

