IBC#012: Bitcoin Core initialization — Part 6
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 99 subscribers to this newsletter and to those who decided to contribute with some sats to this project. It means the world to me!
Today we are going to continue our trip inside the initialization of Bitcoin Core.
Let’s start!
Ban Manager
Sometimes, users may have the necessity to avoid connections from peer nodes in the Bitcoin network. Why is that? Here are some reasons1:
Maybe you want to not allow connections from/to certain cloud providers. They have a lot of IP ranges
It’s rather for not up-to-date nodes or bugged nodes
Ban nodes not sending blocks or nodes attempting to swarm your node.
To keep the network healthy from bad actors such as spy nodes
Thus, in the initialization of Bitcoin Core the user has the possibility to pass a list of banned peers to the node manager class.
assert(!node.banman);
node.banman = std::make_unique<BanMan>(args.GetDataDirNet() / "banlist", &uiInterface, args.GetIntArg("-bantime", DEFAULT_MISBEHAVING_BANTIME));
After that, the connection manager is instantiated passing as parameters all the structure created in the previous lines of code (check the previous episodes to know more):
assert(!node.connman);
node.connman = std::make_unique<CConnman>(GetRand<uint64_t>(),
GetRand<uint64_t>(),
*node.addrman, *node.netgroupman, chainparams, args.GetBoolArg("-networkactive", true));
Fee Estimator
Later, the structure in charge of estimating the network fees is initialized. First, the function checks if the code should ignore the incoming transactions to estimate the fees; if not, the code checks the input arguments to see if the old estimates should be read. However, this is possible only on the REGTEST
chain thus, if we are not on that chain, the function returns with an error.
assert(!node.fee_estimator);
// Don't initialize fee estimation with old data if we don't relay transactions,
// as they would never get updated.
if (!peerman_opts.ignore_incoming_txs) {
bool read_stale_estimates = args.GetBoolArg("-acceptstalefeeestimates", DEFAULT_ACCEPT_STALE_FEE_ESTIMATES);
if (read_stale_estimates && (chainparams.GetChainType() != ChainType::REGTEST)) {
return InitError(strprintf(_("acceptstalefeeestimates is not supported on %s chain."), chainparams.GetChainTypeString()));
}
In case everything is ok, the fee estimator is instantiated using the fee estimates file. This file contains history of transactions and groups them into buckets with similar feerates in order to estimate what fee should be paid in order to have transactions confirmed in a certain number of blocks.
Moreover, this file is updated with new batch of transactions every FEE_FLUSH_INTERVAL
amount of time
node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(args), read_stale_estimates);
// Flush estimates to disk periodically
CBlockPolicyEstimator* fee_estimator = node.fee_estimator.get();
node.scheduler->scheduleEvery([fee_estimator] { fee_estimator->FlushFeeEstimates(); }, FEE_FLUSH_INTERVAL);
}
Enough for today! Thank you, as always, for reading this article. It really means the world to me! Leave a comment and let me know your opinion.
See you next time!
Tuma
Did you find value in this newsletter? Three way you can support my work:
Offer me a coffee at tuma@getalby.com
Zap me some sats on Nostr (tuma@nostrplebs.com)
Share my work to other plebs who might be interested!