In the past days, I wrote a first implementation of a blockchain, using TDD (Test-Driven Development). Simplicity guides my decision: the blockchain is in-memory, and blocks are identified by number and a hash. Two blocks with number 42 are differente blocks if they have different hashes. A block has the parent block hash (the parent block number is deduced, it’s the block number minus one). A genesis block has number 0, and null parent hash. In this way, I have all the ingredients to build a blockchain, from genesis block to best block, chaining the blocks using their numbers and hashes.
I have a class BlockChain (yes, I prefer the mixed case name). There is a method to add a new block to the blockchain. It controls the new block has as parent the current best block in the blockchain.
But there are other nodes, that send other blocks, that can or cannot be added to the blockchain. How to process those blocks? I collect the blocks that cannot be added to the current blockchain in other objects, I call them blockbranch:
In the second blockbranch, parent block for block 41 is unknown, so, the blockbranch is waiting for the arrival of that block. The first blockbranch is connected to blockchain, as an alternative branch. But is has a height less than blockchain height.
A block branch has one or more consecutive blocks. The blocks are not part of the current blockchain. But they are proto-blockchain.
In the second blockbranch of the above figure, parent block for block 41 is unknown, so, the blockbranch is waiting for the arrival of that block. The first blockbranch is connected to blockchain, as an alternative branch. But is has a height less than blockchain height.
When I have sufficient blocks in a block branch (maybe, connect the bottom of the blockbranch to an existing block in another blockbranch or in the current blockchain), and I can build a list of blocks from genesis to the block in block branch, the branch is a candidate to be the new blockchain. Suppose a new block arrives:
The new block can be added to the second block branch, and it has an existing parent in the current blockchain. So, the block branch now has a complete path of block from genesis.
If the block branch is valid (applying their blocks to a known valid state at end of main block 39), and its height is greater than the current blockchain, the block branch is promoted to be the new blockchain:
The process works even if the new blocks arrives in random order. To manage the creation, growth, and promotion of blockchain and related blockbranches, I have a separate object, of class BlockProcessor, in charge of all this orchestration. The processor receives the new blocks, and send them to the corresponding blockchain or branch. Then, it can detect any new connection between branches, and the formation of branches that can be promoted to blockchains.
In the next post: details of a DSL (Domain Specific Language) I’m using to test different scenarios for the block processor.