btcd icon indicating copy to clipboard operation
btcd copied to clipboard

blockchain, netsync: implement a complete headers-first download during ibd

Open kcalvinalvin opened this issue 3 months ago • 4 comments

Change Description

Right now the headers-first download is only based off of the checkpoints and is thus limited to the last checkpoint. The newly implemented headers-first download will always download headers-first and will validate them to see if the headers connect and have proper proof of work.

Then the block download will be based off of the verified headers. This now eliminates any potential downloading of txs or orphan blocks during ibd. It also makes future parallel block download much better as a parallel block download can only happen for blocks we already have headers for.

~~It's not yet put into the code yet but this allows the node to also receive block headers instead of invs during block propagation.~~ I'll do this in a follow up later.

Steps to Test

  • Perform ibd on any of the networks and see that the node syncs up fine.
  • Check that the newly added function tests are correct.

Pull Request Checklist

Testing

  • [x] Your PR passes all CI checks.
  • [x] Tests covering the positive and negative (error paths) are included.
  • [ ] Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

📝 Please see our Contribution Guidelines for further guidance.

kcalvinalvin avatar Sep 22 '25 16:09 kcalvinalvin

Pull Request Test Coverage Report for Build 19373443826

Details

  • 139 of 254 (54.72%) changed or added relevant lines in 6 files are covered.
  • 65 unchanged lines in 6 files lost coverage.
  • Overall coverage increased (+0.5%) to 55.433%

Changes Missing Coverage Covered Lines Changed/Added Lines %
blockchain/chainio.go 1 3 33.33%
blockchain/chain.go 11 22 50.0%
netsync/manager.go 40 142 28.17%
<!-- Total: 139 254
Files with Coverage Reduction New Missed Lines %
mempool/mempool.go 1 66.56%
btcutil/gcs/gcs.go 3 81.25%
database/ffldb/blockio.go 4 88.81%
rpcclient/infrastructure.go 4 47.8%
netsync/manager.go 18 7.05%
blockchain/chainio.go 35 69.75%
<!-- Total: 65
Totals Coverage Status
Change from base Build 19121431262: 0.5%
Covered Lines: 31425
Relevant Lines: 56690

💛 - Coveralls

coveralls avatar Sep 22 '25 16:09 coveralls

cc: @gijswijs for review

saubyk avatar Oct 21 '25 16:10 saubyk

cc: @mohamedawnallah for review

saubyk avatar Oct 21 '25 16:10 saubyk

Addressed all the review comments by roasbeef

kcalvinalvin avatar Nov 14 '25 18:11 kcalvinalvin

Tested in the wild, and does what it says on the tin:

``` 2025-12-17 18:32:10.885 [INF] SYNC: Downloading headers for blocks 136001 to 2401568 from peer PEER_A:18333 2025-12-17 18:32:10.885 [INF] SYNC: Lost peer PEER_B:18333 (outbound) 2025-12-17 18:32:16.309 [INF] SYNC: New valid peer PEER_C:18333 (outbound) (/Satoshi:27.1.0/) 2025-12-17 18:32:40.885 [INF] SYNC: Downloading headers for blocks 136001 to 4807558 from peer PEER_D:18333 2025-12-17 18:32:40.885 [INF] SYNC: Lost peer PEER_A:18333 (outbound) 2025-12-17 18:32:41.044 [INF] SYNC: New valid peer PEER_E:18333 (outbound) (/Satoshi:28.1.0/) 2025-12-17 18:32:41.135 [INF] SYNC: New valid peer PEER_F:18333 (outbound) (/Satoshi:27.0.0/) 2025-12-17 18:32:46.438 [INF] CHAN: Verified checkpoint at height 200000/block 0000000000287bffd321963ef05feab753ebe274e1d78b2fd4e2bfe9ad3aa6f2 2025-12-17 18:32:51.245 [INF] SYNC: New valid peer PEER_G:18333 (outbound) (/Satoshi:28.1.0/) 2025-12-17 18:32:55.171 [INF] CHAN: Verified checkpoint at height 300001/block 0000000000004829474748f3d1bc8fcf893c88be255e6d7f571c548aff57abf4 2025-12-17 18:33:03.103 [INF] CHAN: Verified checkpoint at height 400002/block 0000000005e2c73b8ecb82ae2dbc2e8274614ebad7172b53528aba7501f5a089 2025-12-17 18:33:10.885 [INF] SYNC: Downloading headers for blocks 490001 to 4807558 from peer PEER_G:18333 2025-12-17 18:33:10.885 [INF] SYNC: Lost peer PEER_D:18333 (outbound) 2025-12-17 18:33:13.135 [INF] CHAN: Verified checkpoint at height 500011/block 00000000000929f63977fbac92ff570a9bd9e7715401ee96f2848f7b07750b02 2025-12-17 18:33:25.990 [INF] CHAN: Verified checkpoint at height 600002/block 000000000001f471389afd6ee94dcace5ccc44adc18e8bff402443f034b07240 2025-12-17 18:33:38.331 [INF] CHAN: Verified checkpoint at height 700000/block 000000000000406178b12a4dea3b27e13b3c4fe4510994fd667d7c1e6a3f4dc1 2025-12-17 18:33:40.884 [INF] SYNC: Downloading headers for blocks 718001 to 4807558 from peer PEER_E:18333 2025-12-17 18:33:40.888 [INF] SYNC: Lost peer PEER_G:18333 (outbound) 2025-12-17 18:33:46.254 [INF] SYNC: New valid peer PEER_H:18333 (outbound) (/Satoshi:25.1.0/) 2025-12-17 18:33:50.353 [INF] CHAN: Verified checkpoint at height 800010/block 000000000017ed35296433190b6829db01e657d80631d43f5983fa403bfdb4c1 2025-12-17 18:34:01.433 [INF] CHAN: Verified checkpoint at height 900000/block 0000000000356f8d8924556e765b7a94aaebc6b5c8685dcfa2b1ee8b41acd89b 2025-12-17 18:34:10.884 [INF] SYNC: Downloading headers for blocks 986001 to 4807558 from peer PEER_E:18333 2025-12-17 18:34:10.884 [INF] SYNC: Lost peer PEER_E:18333 (outbound) 2025-12-17 18:34:10.884 [INF] SYNC: Downloading headers for blocks 986001 to 4807558 from peer PEER_H:18333 2025-12-17 18:34:11.269 [INF] SYNC: New valid peer PEER_I:18333 (outbound) (/Satoshi:25.1.0/) 2025-12-17 18:34:11.270 [INF] SYNC: New valid peer PEER_J:18333 (outbound) (/Satoshi:0.20.1/) 2025-12-17 18:34:13.213 [INF] CHAN: Verified checkpoint at height 1000007/block 00000000001ccb893d8a1f25b70ad173ce955e5f50124261bbbc50379a612ddf 2025-12-17 18:34:16.312 [INF] SYNC: New valid peer PEER_K:18333 (outbound) (/Satoshi:27.0.0/) 2025-12-17 18:34:25.081 [INF] CHAN: Verified checkpoint at height 1100007/block 00000000000abc7b2cd18768ab3dee20857326a818d1946ed6796f42d66dd1e8 ```

One thing I noticed though is that the peers may D/C us along the way, so we rotate through a few peers to fetch all the headers. This is testnet3 , there's quite a lot of headers (over 4 million). Are we hitting something like default per-peer upload limit for bitcoind?

IIUC this is a stepping stone for multi-peer header download, so perhaps that'll be sorted out as we'll fetch blocks of headers from many peers in parallel.

Roasbeef avatar Dec 18 '25 02:12 Roasbeef