crypto.bi

qt/bitcoin.h in Qt Bitcoin Core source code

qt/bitcoin.h pulls the config/bitcoin-config.h definitions that were generated by the configure script during the build process.

This header also contains the Qt Q_OBJECT BitcoinCore class which handles 3 signals and provides 2 slots.

(If you’re not familiar with Qt, please go here for an intro to slots and signals or here for an explanation about the Q_OBJECT macro.)

Slots, signals and Q_OBJECT in a nutshell

If you’re in a hurry, all you need to know is Qt slots and signals are the mechanism by which Qt does multithreading. Qt manages its own loop where it orchestrates how signals received are sent to slots for processing. This is unrelated to Bitcoin and specific to the GUI framework.

The Q_OBJECT macro is required by the Qt MOC (meta-object compiler) which generates some Qt-specific boilerplate code.

All the BitcoinCore class does is hook the Bitcoin Core startup and shutdown procedures up to the Qt multithreading system.

The slots are aptly called initialize and shutdown. The class handles three signals: initializeResult, shutdownResult and runawayException.

BitcoinApplication

The bitcoin.h header then defines the BitcoinApplication class, which is also a Qt Q_OBJECT class that extends QApplication. As you may infer, this is the main Qt application class, which will run for as long as the graphical Bitcoin Core program is open.

For all practical purposes the BitcoinApplication class encapsulates what a console application’s main function does : it wraps the Qt program from start to finish. BitcoinApplication is the thing you see when you run bitcoin-qt

BitcoinApplication encapsulates everything the Bitcoin Core graphical interface  needs to run a full node, managing the following fields (field names in bold):

QThread *coreThread – This separate thread will take care of application initialization, shutdown and exceptions. It’s connected to several signals on qt/bitcoin.cpp.

interfaces::Node& m_node – The Node class (defined in interfaces/node.h) encapsulates the functionality of a bitcoind process. It does everything you expect a Bitcoin node to do including manage wallets, get BTC balances, activate and deactivate the network service, get blockchain data, ban network hosts and much more.

OptionsModel *optionsModel – This class encapsulates 21 application options. It’s a QAbstractListModelsubclass. Options are passed in from the command line or from configuration files. This is where the application stores options like database cache, UPnP port mapping toggle, what language to use, network proxy information and much more.

ClientModel *clientModel – The ClientModel class encapsulates Bitcoin networking functions in a Qt wrapper. It updates the Qt graphical user interface with data from the underlying Bitcoin network client.

BitcoinGUI *window – This is the main QMainWindow of the application. This is where all the user interaction handling happens.

Here are some of the actions handled by the BitcoinGUI window:

QAction* overviewAction = nullptr;
QAction* historyAction = nullptr;
QAction* quitAction = nullptr;
QAction* sendCoinsAction = nullptr;
QAction* sendCoinsMenuAction = nullptr;
QAction* usedSendingAddressesAction = nullptr;
QAction* usedReceivingAddressesAction = nullptr;
QAction* signMessageAction = nullptr;
QAction* verifyMessageAction = nullptr;
QAction* aboutAction = nullptr;
QAction* receiveCoinsAction = nullptr;
QAction* receiveCoinsMenuAction = nullptr;
QAction* optionsAction = nullptr;
QAction* toggleHideAction = nullptr;
QAction* encryptWalletAction = nullptr;
QAction* backupWalletAction = nullptr;
QAction* changePassphraseAction = nullptr;
QAction* aboutQtAction = nullptr;
QAction* openRPCConsoleAction = nullptr;
QAction* openAction = nullptr;
QAction* showHelpMessageAction = nullptr;
QAction* m_open_wallet_action{nullptr};
QMenu* m_open_wallet_menu{nullptr};
QAction* m_close_wallet_action{nullptr};
QAction* m_wallet_selector_label_action = nullptr;
QAction* m_wallet_selector_action = nullptr;

Note:QAction‘s are user interface actions that the window must respond to. The names are intuitive and give us an idea of all the things handled by BitcoinGUI.

QTimer *pollShutdownTimer – This is a QTimer object that’s instantiated when BitcoinGUI creates the main window. The timer gets started in the initializeResult handler in qt/bitcoin.cpp. When initialization is a success, the timer starts firing every 200 milliseconds throughout the lifetime of the Bitcoin client GUI, checking whether system shutdown has been requested from anywhere in the system. If any component of the system has requested shutdown, tested at BitcoinGUI::detectShutdown, then the RPC console is hidden and the application is sent the quit() message. This timer is the reason there’s a tiny lag between when you order the application shutdown and when it actually exits. All the messages are asynchronous.

Next up is a compilation-conditional block:

#ifdef ENABLE_WALLET
PaymentServer* paymentServer{nullptr};
WalletController* m_wallet_controller{nullptr};
#endif

The Bitcoin Core node can be compiled and run without a wallet in it! You can run a full verifying node without having a wallet. Such a node would contribute to the Bitcoin network, verifying and relaying transactions, but would not hold any coins nor perform any wallet-related functions (send/receive/check balance/etc).

If you compile Core with wallet functionality (default), then these two members are compiled into BitcoinGUI:

PaymentServer* paymentServer{nullptr} – This class handles payment requests when the user clicks on a Bitcoin link somewhere else in the operating system. Special care is taken to not handle such requests when the system isn’t in functional condition (starting up or shutting down, for example).

WalletController* m_wallet_controller{nullptr} – This class handles messages back and forth between the user interface and the underlying Wallet class. It’s a controller class that glues together Wallet‘s, the Node and the user interface.

int returnValue – This value is passed between BitcoinCore and BitcoinApplication classes through a Qt slot/signal connection. When BitcoinCore finishes initializing, it sends a signal which is handled by BitcoinApplication. returnValue is then checked. If all went well in the initialization, then BitcoinApplication starts running. Else the program exits.

const PlatformStyle *platformStyle – A class that encapsulates Windows, MAC OS X and “other” platform-specific settings. This controls icons on buttons and other GUI details for each platform.

std::unique_ptr<QWidget> shutdownWindow – This is a pointer to a QWidget dialog (or window) that is displayed when system shutdown is requested. As mentioned before, shutdown is asynchronous, so this little window sticks around while the rest of the system cleans up and exits. A bit more detail is given in the pollShutdownTimer section above.

Lastly on qt/bitcoin.h the GuiMain subroutine is declared:

int GuiMain(int argc, char* argv[]);

GuiMain is called from main(int argc, char* argv[]) which is discussed in the qt/main.cpp article.

(In fact GuiMain is the only thing main() does in bitcoin-qt. It’s a one liner.)

Links

crypto.bi Toolbox Home

About the Author
Published by @rektbuildr - Software developer and technical writer. In charge of fixing the coffee machine at crypto.bi. Interest include Java, Avalanche AVAX, C and C++, Spark, Hadoop, Scala language, golang, RedHat OpenShift and kubernetes, container tech, DevOps and related techs. Learn More About Us