IBC#024: Bitcoin Core Initialization, Step 9 and 10
Load Wallet and Data Directory Maintenance
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 147 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 Step 8, which was dedicated to starting indexers. Today we are going to move to step 9 and 10 of the initialization of Bitcoin Core. [Code Link]
Let’s start!
Loading Wallet
Step 9 of the node initialization is dedicated to loading the different clients the node has to interact with, mainly wallets. A for loop iterates through the list of ChainClients registered to the node and loads them.
for (const auto& client : node.chain_clients) {
if (!client->load()) {
return false;
}
}If any error occurs while loading a client, the load() function returns false and the initialization stops.
Data Directory Maintenance
Moving to step 10, the code enters a conditional step that depends on whether or not the node was configured with the -pruned argument.
if (chainman.m_blockman.IsPruneMode()) {
.
.
.
} else {
.
.
.
}Running a pruned node means that the older blocks are removed from the data storage to save disk space, keeping only the latest data needed for validation. Blockstore pruning happens only after any wallet rescanning has taken place.
In case IsPruneMode() returns true, another if clause checks the value of thel m_blockfiles_indexed boolean, which signals if all blockfiles have been added to the block tree database. If so, the programs locks a global mutex1, called cs_main throught the LOCK() function. A mutex is simply an object that prevents two processes to access the same part at the same time.
Then, a for loops iterates over all the Chainstate objects currently in use and prunes blockfiles from the disk flushes chainstate changes.
if (chainman.m_blockman.m_blockfiles_indexed) {
LOCK(cs_main);
for (Chainstate* chainstate : chainman.GetAll()) {
uiInterface.InitMessage(_(”Pruning blockstore…”));
chainstate->PruneAndFlush();
}
}On the other hand, if we are not running in pruned mode, the code enters the else clause. Here, a second if clause checks if the synching is still in progress. If not, the NODE_NETWORK2 flag is activated, signaling that the node is capable of serving the complete block chain to other peers.
if (!WITH_LOCK(chainman.GetMutex(), return chainman.BackgroundSyncInProgress())) {
LogInfo(”Setting NODE_NETWORK on non-prune mode”);
g_local_services = ServiceFlags(g_local_services | NODE_NETWORK);
} else {
LogInfo(”Running node in NODE_NETWORK_LIMITED mode until snapshot background sync completes”);
}If the synching is still ongoing, the NODE_NETWORK_LIMITED flag is set to signal that the node is only able to provide the last 288 blocks.
I am thinking about expanding this newsletter a bit more, adding another side quest with the goal of explaining each Bitcoin Improvement Proposal (BIP) currently activated in Bitcoin! Answer the poll and let me know what you think!
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


