<p>First of all, finding the <strong>longest</strong> chain is not the goal, but the chain with the <strong>most accumulated proof-of-work</strong> [<a href="https://gist.github.com/harding/dabea3d83c695e6b937bf090eddf2bb3#abstract" rel="noreferrer">1</a>]</p>
<p>Now, finding the most-work chain is the entire goal of the full node. The whole meaning of its existence is finding the most-work chain, and so you can pick almost any line out of the networking and validation modules of the code and explain it in those terms.</p>
<p>To be a bit more specific:</p>
<ul>
<li>The full node connects to at least 8 peers. More recent versions connect to 2 extra peers in 'blocks only' mode. Peers are chosen to be as diverse as possible (by IP subnet or AS map). If a new block has not been added within a certain timeout (I think it's 40 minutes) Bitcoin Core adds one more outgoing peer.</li>
<li>The full node sends a <code>getheaders</code> request to each peer and keeps track of the best block each peer knows about.</li>
<li>If a peer has a valid block header with greater accumulated work than our current tip, we ask it for the corresponding blocks. If those blocks are valid, it becomes our new chain tip. A reorganization may or may not be necessary to get to that state.</li>
</ul>
<p>If you understand conceptually how headers-first sync works, the function <a href="https://github.com/bitcoin/bitcoin/blob/197450f80868fe752c6107955e5da80704212b34/src/net_processing.cpp#L675" rel="noreferrer">FindNextBlocksToDownload()</a> is the next step. This is where the node decides if a peer has headers with greater work than its current chain tip, and requests those blocks from that peer.</p>
<p>So all we can do is connect to a lot of peers and assume that at least one of them knows about the most-work chain. This makes peer discovery and choosing which peers to connect to of critical importance.</p>

CC BY-SA 4.0
2020-08-25T20:46:51.613Z
Thanks, this is really helpful. Looking at `FindNextBlocksToDownload`, the part I'm still trying to understand is: if after finishing your header sync, a peer gives you headers you've never seen, and which don't connect to your chain, how are you going to judge whether they have more accumulated work?
cloudhead
CC BY-SA 4.0
2020-08-25T20:55:18.747Z
Since we can not verify "orphan" headers, we do not request those blocks. The `getheaders` message includes something called a locator that the receiving peer uses to determine where their chain connects to your chain, and sends you headers from that point: https://en.bitcoin.it/wiki/Protocol_documentation#getheaders
pinhead
CC BY-SA 4.0
2020-08-25T21:00:37.530Z
I see, so peers will end up sending chains that connect, by using the locators.. makes sense!
cloudhead
CC BY-SA 4.0
2020-08-23T22:09:09.943Z
2020-08-23T22:09:09.943Z
pinhead
<p>In trying to implement a client, I am wondering what is the most efficient approach to figure out if you are on a fork.</p>
<p>Let's say you pick a peer at random and go through IBD using the headers-first approach. After reaching the tip of the chain, what is the most efficient way to check whether this is the longest chain?</p>
<p>I'm guessing you have to ask your peers what their best header is, and based on the response and some heuristic, decide whether you are on the longest chain or not. Is this simply done via <code>getheaders</code>? What is the heuristic? And what do you do if you find out you're on a fork?</p>
<p>Pointers to the relevant code in bitcoin or btcd would also be appreciated.</p>
<p>Thanks</p>
<p>EDIT: In case this isn't obvious, I'm not asking whether it can know with certaintiy that it is on the longest chain (it can't), but rather what is the best effort <em>attempt</em> to remain on the longest chain at all times.</p>

<bitcoin-core><bitcoin-core-development><best-chain>
How does Bitcoin Core know it's on the longest chain?
cloudhead
# How does Bitcoin Core know it's on the longest chain?

(Asked by: username_0 on 2020-08-23)

In trying to implement a client, I am wondering what is the most efficient approach to figure out if you are on a fork.

Let's say you pick a peer at random and go through IBD using the headers-first approach. After reaching the tip of the chain, what is the most efficient way to check whether this is the longest chain?

I'm guessing you have to ask your peers what their best header is, and based on the response and some heuristic, decide whether you are on the longest chain or not. Is this simply done via `getheaders`? What is the heuristic? And what do you do if you find out you're on a fork?

Pointers to the relevant code in bitcoin or btcd would also be appreciated.

Thanks

EDIT: In case this isn't obvious, I'm not asking whether it can know with certaintiy that it is on the longest chain (it can't), but rather what is the best effort *attempt* to remain on the longest chain at all times.

**Tags:** bitcoin-core, bitcoin-core-development, best-chain


---

## 1 answers

### Answer by username_1 on 2020-08-23. Score: 5 | Accepted answer

First of all, finding the **longest** chain is not the goal, but the chain with the **most accumulated proof-of-work** [[1](https://gist.github.com/harding/dabea3d83c695e6b937bf090eddf2bb3#abstract)]

Now, finding the most-work chain is the entire goal of the full node. The whole meaning of its existence is finding the most-work chain, and so you can pick almost any line out of the networking and validation modules of the code and explain it in those terms.

To be a bit more specific:

* The full node connects to at least 8 peers. More recent versions connect to 2 extra peers in 'blocks only' mode. Peers are chosen to be as diverse as possible (by IP subnet or AS map). If a new block has not been added within a certain timeout (I think it's 40 minutes) Bitcoin Core adds one more outgoing peer.
* The full node sends a `getheaders` request to each peer and keeps track of the best block each peer knows about.
* If a peer has a valid block header with greater accumulated work than our current tip, we ask it for the corresponding blocks. If those blocks are valid, it becomes our new chain tip. A reorganization may or may not be necessary to get to that state.

If you understand conceptually how headers-first sync works, the function [FindNextBlocksToDownload()](https://github.com/bitcoin/bitcoin/blob/197450f80868fe752c6107955e5da80704212b34/src/net_processing.cpp#L675) is the next step. This is where the node decides if a peer has headers with greater work than its current chain tip, and requests those blocks from that peer.

So all we can do is connect to a lot of peers and assume that at least one of them knows about the most-work chain. This makes peer discovery and choosing which peers to connect to of critical importance.

> **Comments:**
> **username_0**: Thanks, this is really helpful. Looking at `FindNextBlocksToDownload`, the part I'm still trying to understand is: if after finishing your header sync, a peer gives you headers you've never seen, and which don't connect to your chain, how are you going to judge whether they have more accumulated work?  
> **username_1**: Since we can not verify "orphan" headers, we do not request those blocks. The `getheaders` message includes something called a locator that the receiving peer uses to determine where their chain connects to your chain, and sends you headers from that point: https://en.bitcoin.it/wiki/Protocol_documentation#getheaders  
> **username_0**: I see, so peers will end up sending chains that connect, by using the locators.. makes sense!  

---

