- CheckBlock() --> Checks the info inside a block
- AcceptBlock() --> Additional checks + write to disk
- ProcessNewBlock() --> Calls both of the above and also a function called ActivateBestChain(), which decides whether propagation to the network is warranted, among other things.
- ConnectBlock() and DisconnectBlock() Append the block in question to the end of the blockchain (or take it off from there), linking it with the previous block's hash.
Bitcoin needs to be industrial-strength code, so expect to see checks everywhere, for anything that could possibly happen (i.e., >1 coinbase transactions in a block, etc.). Moreover, some database operations are atomic, there are decisions when to propagate new blocks to the network, and to further complicate matters, the source code itself is the best documentation out there (slowly changing though, Andreas' Book is just a start).
Let's start with CheckBlock(), which is called by other functions:
Its sequence of operations/function calls are:
- CheckBlockHeader() --> checks mostly that the PoW is there;
- fCheckMerkleRoot --> checks correctness of Merkle Root & that there are no duplicate transactions
- Checks size of the block, whether 1st transaction is coinbase, whether there are other (obviously invalid) coinbase transactions, and only then it checks the transactions and whether the maximum number of sig_ops has been surpassed (which prevents 'a "rogue miner" from creating an incredibly-expensive-to-validate block."');
AcceptBlock() will make its own checks and write to disk;
So, in sum, CheckBlock() makes sure that there are no shenanigans within a particular block, AcceptBlock() will write to disk. ProcessNewBlock() calls both CheckBlock() and AcceptBlock(), here's its outline:
- Call to CheckBlock(); verifying it's ok;
- Call to AcceptBlock(); as you can see from the comment prior to the call, AcceptBlock() will write it to disk;
- Calls and Checks whether ActivateBestChain() is successful
This leaves out ConnectBlock() and DisconnectBlock()...
ConnectBlock() and DisconnectBlock() Append the block in question to the end of the blockchain (or take it off from there). These are complex functions, in my opinion they are ripe for a slow refactoring, but see the final note:
Final note: I am not a bitcoin-core developer; if one could edit and help out here, I am sure this answer could be considerably improved. I know one thing, though: the more you study the code, the better your understanding and appreciation of the industrial strength of this magic internet money.