Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network protocol is outdated: headers-first sync, compact blocks, pruned node services #721

Open
pinheadmz opened this issue Mar 8, 2019 · 1 comment
Labels
Milestone

Comments

@pinheadmz
Copy link
Member

pinheadmz commented Mar 8, 2019

  1. Message getBlocks is no longer used on the network and is likely to be deprecated in the future.

  2. Bitcoin Core syncs headers-first. (since version 0.10)

  3. The behavior for retrieving compact blocks is also different between bcoin and Core. From gmaxwell on IRC:

bitcoin won't send a CMCPT_BLOCK request when it's pretty confident that doing so will be larger than just requesting the block. [Core doesn't request CMPCT_BLOCK] because your mempool is empty, so compact blocks can't make the result smaller. it also needs to be able to fall back to getting an ordinary block if it finds a collision.

  1. bcoin always requests CMPCT_BLOCK as long as it's a certain depth below the chain tip (10 blocks in bcoin, 5 blocks in Core)

  2. Bitcoin Core pruned nodes can still serve the last 288 blocks to peers, pruned bcoin nodes don't even respond to requests for data.

See also:
https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki
https://en.bitcoin.it/wiki/Protocol_documentation#sendheaders
https://github.com/bitcoin/bips/blob/master/bip-0159.mediawiki

To reproduce: start up bcoin in regtest and generate 100 blocks, then connect to that node from both Bitcoin Core and again from a second bcoin node.

Core behavior

Core (client) bcoIn (server)
sendheaders-->
sendcmpct-->
getheaders[locator]-->
<--headers[100 blockheaders]
(verifies headers' POW)
getdata[100 hashes, type = full block]-->
<--block[100 blocks]

Two Core nodes together always use getheaders to sync. New blocks are announced with headers packets and when a node restarts to catch up and resync, it still sends getheaders, checkpoints or no.

bcoin behavior

bcoin (client) bcoin (server)
sendcmpct-->
getblocks[locator]-->
<--inv[100 block hashes]
getdata[100 hashes, type = compact block]-->
<--block[90 full blocks]
<--cmpctblock[10 compact blocks]

bcoin will sync headers-first only if its current height is below a checkpoint and checkpoints are enabled. For this test, restart the bcoin client after hard-coding the reversed hash of block 100 from the bcoin server as a regtest checkpoint and sync again.

bcoin (client) bcoin (server)
sendcmpct-->
getheaders[stop = checkpoint]-->
<--headers[100 blockheaders]
(verifies headers' POW)
getdata[100 hashes, type = compact block]-->
<--block[90 full blocks]
<--cmpctblock[10 compact blocks]

then each new block...

bcoin (client) bcoin (server)
<--inv[1 block hash]
getdata[1 hash, type = compact blocks]-->
<--cmpctblock[compact block]

...and after a restart we use getblocks again which triggers inv/getdata/block

bcoin (client) bcoin (server)
getblocks[locator]-->
@braydonf
Copy link
Contributor

braydonf commented Oct 8, 2019

This is resolved in the https://github.com/bcoin-org/bcoin/tree/chain-expansion branch, in regards to headers-first synchronization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants