IBC#013: Bitcoin Core initialization — Part 7
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 102 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!
Checking connection port
After initializing the fee estimator, as seen in IBC#012, the connection port is checked. A port1 is a number that uniquely identifies the connection endpoint used by the transmission protocol.
// Check port numbers
for (const std::string port_option : {
"-port",
"-rpcport",
}) {
if (args.IsArgSet(port_option)) {
const std::string port = args.GetArg(port_option, "");
uint16_t n;
if (!ParseUInt16(port, &n) || n == 0) {
return InitError(InvalidPortErrMsg(port_option, port));
}
}
}
First, a FOR loop checks for every possible port_option
, a std::string
variable that takes first the value “-port”
and then the value “-rpcport”
. Then the code checks which port_option
value is the one set as argument and controls that the value passed with it and stored in the variable n
exists, otherwise the application returns an error.
Later, the application checks the options for the connection, since Bitcoin Core can be run under different services such as I2P2 and Tor3:
for (const std::string port_option : {
"-i2psam",
"-onion",
"-proxy",
"-rpcbind",
"-torcontrol",
"-whitebind",
"-zmqpubhashblock",
"-zmqpubhashtx",
"-zmqpubrawblock",
"-zmqpubrawtx",
"-zmqpubsequence",
}) {
for (const std::string& socket_addr : args.GetArgs(port_option)) {
std::string host_out;
uint16_t port_out{0};
if (!SplitHostPort(socket_addr, port_out, host_out)) {
return InitError(InvalidPortErrMsg(port_option, socket_addr));
}
}
}
For each of the possible options, the application takes the arguments through the GetArgs
function, loops on all of them, and checks if the addresses or port numbers selected are valid. In case it is not, the application returns another error.
In the end, the -bind
argument parameters are checked; this argument can bind the process to one of the many IP addresses in the system, in case it has more than one network card.
for (const std::string& socket_addr : args.GetArgs("-bind")) {
std::string host_out;
uint16_t port_out{0};
std::string bind_socket_addr = socket_addr.substr(0, socket_addr.rfind('='));
if (!SplitHostPort(bind_socket_addr, port_out, host_out)) {
return InitError(InvalidPortErrMsg("-bind", socket_addr));
}
}
The -bind
command is called like this:
-bind=<address>
Thus, the code checks the <address>
after the “=
“ and and checks if the one selected is valid. In case it is not, the application returns another error.
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!