As all of you following our blog are aware, we have previously released several bitcoin-related packages (btcwire, btcjson, btcutil, btcdb, btcec, and btcscript) on our way towards the full release of btcd.
We are happy to announce our next package from btcd. The package is named btcchain and it implements the bitcoin block handling and chain selection rules. The code can be reviewed on github here:
Overall Package Design
The bitcoin block handling and chain selection rules are an integral, and quite likely the most important, part of bitcoin. Unfortunately, at the time of this writing, these rules are also largely undocumented and had to be ascertained from the bitcoind source code. At its core, bitcoin is a distributed consensus of which blocks are valid and which ones will comprise the main block chain (public ledger) that ultimately determines accepted transactions, so it is extremely important that fully validating nodes agree on all rules.
At a high level, this package provides support for inserting new blocks into the block chain according to this distributed consensus of rules. It includes functionality such as rejecting duplicate blocks, ensuring blocks and transactions follow all rules, orphan handling, and best chain selection along with reorganization.
One of the design goals for the packages used to build btcd has been reusability. To that end, btcchain optionally provides notifications via an asynchronous channel when certain modifications to the block chain take place. For an example of how these notifications are actually used within btcd, when an orphan block is processed, the missing blocks need to be requested from the peer that sent the orphan. Rather than trying to make the chain code understand peers and network requests thus tightly coupling it to other sub-systems, btcd listens for a notification and requests the missing blocks. In this way, btcchain is completely agnostic to the rest of the sub-systems.
Another example of how notifications might be used by a caller is to update wallets with transactions paying coins to the addresses in the wallet. As in the previous example, this means btcchain does not need to know anything about wallets.
The test coverage for chain is currently only around 60%, but it does include a full blown unit test for chain reorganization using test data provided on the bitcoin talk forums as outlined in this post. Credits for the following diagram go to etotheipi, the author of the linked post and image.
The reorganization test in btcchain uses a slight tweak in the order the blocks are loaded as compared to the order presented in the referenced post in order to ensure orphan handling and a reorganization caused by inserting the parent of an orphaned side chain works correctly as well. In particular, it loads the first 4 blocks from the main chain (1-4 in the diagram), then the second block from the side chain (4A), the third block from the side chain (5A), and finally the first block on the side chain (3A) which completes the side chain and forces it to become the new main chain due to higher difficulty.
We do plan to increase the test coverage further, though testing the error conditions will likely take a while as it will require quite an effort to mine a suite of blocks that are mostly valid except for the specific errors being tested.
This will be the final package released before btcd. That’s right folks, you read it here first. The next release will be btcd!