IBC#021: Bitcoin Core Initialization, Step 7— Init and Load Chain State
Loading the Block Chain: Initialization and Loading of the Chain State
Hello everyone and welcome to this new episode of Inside Bitcoin Code.
A special welcome to the new people that recently subscribed to this newsletter, I hope that you will enjoy what I write. A small suggestion for you: if you know nothing about coding, start reading the posts from Learn2Code to get some basic knowledge before diving in the real deal.
A huge thanks to each of the 146 subscribers of this newsletter and to those who decided to contribute with some sats to this project. It means the world to me!
Last episode was focused on cache memory allocation. Today we are going to continue our trip inside the initialization of Bitcoin Core with the initialization and loading of the chain state. [Code Link]
Let’s start!
Re-indexing Arguments
In the last episode, we allocated the cache memory needed for all the databases of the node.
Now, the code parses the re-indexing options, passed as input arguments to the software and stores them in the do_reindex
and do_reindex_chainstate
boolean:
-reindex
: If enabled, the program wipes chain state and block index (entire blockchain), and rebuilds them from blk*.dat files on disk. It also wipes and rebuilds other optional indexes that are active.-reindex-chainstate
: If enabled, it only wipes chain state (current UTXO set), and rebuilds it from blk*.dat files on disk.
bool do_reindex{args.GetBoolArg(”-reindex”, false)};
const bool do_reindex_chainstate{args.GetBoolArg(”-reindex-chainstate”, false)};
Initialize and Loading the State Chain
Then, the program tries to initialize and load the chain state, through the InitAndLoadChainstate()
function. This function takes as inputs the NodeContext
structure, the previously parsed booleans, the size of the block index cache memory and the input arguments.
// Chainstate initialization and loading may be retried once with reindexing by GUI users
auto [status, error] = InitAndLoadChainstate(
node,
do_reindex,
do_reindex_chainstate,
kernel_cache_sizes,
args);
It returns a ChainstateLoadStatus
, an enum
that can assume one of the following values:
enum class ChainstateLoadStatus {
SUCCESS,
FAILURE, //!< Generic failure which reindexing may fix
FAILURE_FATAL, //!< Fatal error which should not prompt to reindex
FAILURE_INCOMPATIBLE_DB,
FAILURE_INSUFFICIENT_DBCACHE,
INTERRUPTED,
};
The return value is checked in an if
clause: if it fails and, at the same time, do_reindex
is false
and no shutdown was requested by the user, the code suggests the user through the UI to rebuild the databases. If the user clicks the “Abort” button (CClientUIInterface::BTN_ABORT
), do_retry
is set to false
and the initialization function quits.
if (status == ChainstateLoadStatus::FAILURE && !do_reindex && !ShutdownRequested(node)) {
// suggest a reindex
bool do_retry{HasTestOption(args, “reindex_after_failure_noninteractive_yes”) ||
uiInterface.ThreadSafeQuestion(
error + Untranslated(”.\n\n”) + _(”Do you want to rebuild the databases now?”),
error.original + “.\nPlease restart with -reindex or -reindex-chainstate to recover.”,
“”, CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT)};
if (!do_retry) {
return false;
}
On the other hand, if the user accepts the rebuild, do_index
is set to true
and the InitAndLoadChainstate()
function is called again. Before retrying, the program makes sure that the shutdown_signal
in the NodeContext
correctly resets.
do_reindex = true;
if (!Assert(node.shutdown_signal)->reset()) {
LogError(”Internal error: failed to reset shutdown signal.\n”);
}
std::tie(status, error) = InitAndLoadChainstate(
node,
do_reindex,
do_reindex_chainstate,
kernel_cache_sizes,
args);
}
Finally, the code check again that ChainstateLoadStatus
has succeeded and that it has not been interrupted by the user; if this happens, an InitError
is returned.
if (status != ChainstateLoadStatus::SUCCESS && status != ChainstateLoadStatus::INTERRUPTED) {
return InitError(error);
}
Let’s keep in touch:
Check out my writings on btc++ insider edition
Try my new app Sats Tracker, an expense tracker app for people living in the Bitcoin standard.
Zap me a coffee and leave me a message: tuma@wallet.yakihonne.com