As we discovered in Coding #103, the entry point of every C++ project is the main()
function; of course, the same can be said for Bitcoin Core.
The main()
function of Bitcoin Core can be found in the bitcoind.cpp file1, inside the src folder2.
Here we are. We are ready to dive Inside Bitcoin Code!
Main(): overall function
Here, the main()
function is reported:
MAIN_FUNCTION
{
#ifdef WIN32
common::WinCmdLineArgs winArgs;
std::tie(argc, argv) = winArgs.get();
#endif
NodeContext node;
int exit_status;
std::unique_ptr<interfaces::Init> init = interfaces::MakeNodeInit(node, argc, argv, exit_status);
if (!init) {
return exit_status;
}
SetupEnvironment();
// Connect bitcoind signal handlers
noui_connect();
return (AppInit(node, argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}
The first thing that can be noticed is that there isn’t the classical main:
int main(int argc, char* argv[])
Where argc
represents the number of inputs and argv
an array of arrays of char that contains the inputs.
However, here there is something more compact:
MAIN_FUNCTION
This is a preprocessor definition that can be found in compact.h3, and allows to prevent a bug that occurs when building using the mingw-w64 compiler and exporting for a 32 bit windows machine.
Main(): step-by step
Command line arguments
First of all, the code checks if the target is a 32-bit Windows machine:
#ifdef WIN32
common::WinCmdLineArgs winArgs;
std::tie(argc, argv) = winArgs.get();
#endif
This is done by using the preprocessor directive #ifdef
. This directive checks if a variable (WIN32
in our case), is defined; if so, the functions inside the block are called, otherwise they are skipped. #endif
closes the block.
This blocks takes the main()
arguments form command line from a tuple (a special container that holds a collection of elements) and fills the argc
and argv
variables.
Node context initialization
After that, a NodeContext
, a structure containing references to chain state and connection state, is created and initialized:
NodeContext node;
int exit_status;
std::unique_ptr<interfaces::Init> init =
interfaces::MakeNodeInit(node, argc, argv, exit_status);
if (!init) {
return exit_status;
}
The exit_status
variable is declared in order to hold the return status of the initialization, in case it fails.
A std::unique_ptr
(a special type of smart pointer, we will talk about it in Learn2Code) that holds the node initialization is then declared and is defined by the MakeNodeInit
funtcion.
Finally, if initialization fails, the main()
function returns reporting the exit_status
.
Setting up the environment
Later, a function to set up the environment is called:
SetupEnvironment();
This functions sets up the environemnt according to the target machine and it can be found in the system.cpp file4. It sets up things like the input/output default charset.
Event handlers connection
Once the environment is set up, Bitcoin Core creates and connects all the events not connected to the Graphic User Interface (GUI).
noui_connect();
These handlers are used for logging and printing messages.
Launching the application
Once everything is set up, it is finally possible to launch the application:
return (AppInit(node, argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
Here, the AppInit
function takes as input the node and the command line arguments.
The return value of the main()
function is chosen through a so-called ternary operator, which presents the following syntax:
condition ? val1 : val2
if condition evaluates to TRUE, the value taken into consideration will be val1
else it will be val2
. Thus, if AppInit
returns a TRUE value, the return value of the main()
will be EXIT_SUCCESS
, else it would be EXIT_FAILURE
. These values are defined inside stdlib.h, the C standard library.
If you got here, good job again! You now know what happens inside the main()
functions of Bitcoin Core.
Thank you again for reading Inside Bitcoin Code, your support is truly appreciated. Consider sharing this post and this newsletter with anyone you think might be interested and let me know in the comments section what you think.
See you next week!
The first read of the morning! Great explanation. I like how you source ideas and wait for the end to post the links. This is very nice for keeping me from getting distracted by clicking away.