Changeset View
Changeset View
Standalone View
Standalone View
src/qt/bitcoin.cpp
Show All 22 Lines | |||||
#include "winshutdownmonitor.h" | #include "winshutdownmonitor.h" | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
#include "paymentserver.h" | #include "paymentserver.h" | ||||
#include "walletmodel.h" | #include "walletmodel.h" | ||||
#endif | #endif | ||||
#include "init.h" | #include "init.h" | ||||
#include "interface/handler.h" | |||||
#include "interface/node.h" | |||||
#include "rpc/server.h" | #include "rpc/server.h" | ||||
#include "ui_interface.h" | #include "ui_interface.h" | ||||
#include "uint256.h" | #include "uint256.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "warnings.h" | #include "warnings.h" | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
#include "wallet/wallet.h" | // TODO: Remove this sections? | ||||
#endif | #endif | ||||
#include "walletinitinterface.h" | #include "walletinitinterface.h" | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <boost/filesystem/operations.hpp> | #include <boost/filesystem/operations.hpp> | ||||
#include <boost/thread.hpp> | #include <boost/thread.hpp> | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* Class encapsulating Bitcoin ABC startup and shutdown. | * Class encapsulating Bitcoin ABC startup and shutdown. | ||||
* Allows running startup and shutdown in a different thread from the UI thread. | * Allows running startup and shutdown in a different thread from the UI thread. | ||||
*/ | */ | ||||
class BitcoinABC : public QObject { | class BitcoinABC : public QObject { | ||||
Q_OBJECT | Q_OBJECT | ||||
public: | public: | ||||
explicit BitcoinABC(); | explicit BitcoinABC(interface::Node &node); | ||||
/** | |||||
* Basic initialization, before starting initialization/shutdown thread. | |||||
* Return true on success. | |||||
*/ | |||||
static bool baseInitialize(Config &config, RPCServer &rpcServer); | |||||
public Q_SLOTS: | public Q_SLOTS: | ||||
void initialize(Config *config, | void initialize(Config *config, | ||||
HTTPRPCRequestProcessor *httpRPCRequestProcessor); | HTTPRPCRequestProcessor *httpRPCRequestProcessor); | ||||
void shutdown(); | void shutdown(); | ||||
Q_SIGNALS: | Q_SIGNALS: | ||||
void initializeResult(bool success); | void initializeResult(bool success); | ||||
void shutdownResult(); | void shutdownResult(); | ||||
void runawayException(const QString &message); | void runawayException(const QString &message); | ||||
private: | private: | ||||
/// Pass fatal exception message to UI thread | /// Pass fatal exception message to UI thread | ||||
void handleRunawayException(const std::exception *e); | void handleRunawayException(const std::exception *e); | ||||
interface::Node &m_node; | |||||
}; | }; | ||||
/** Main Bitcoin application object */ | /** Main Bitcoin application object */ | ||||
class BitcoinApplication : public QApplication { | class BitcoinApplication : public QApplication { | ||||
Q_OBJECT | Q_OBJECT | ||||
public: | public: | ||||
explicit BitcoinApplication(int &argc, char **argv); | explicit BitcoinApplication(interface::Node &node, int &argc, char **argv); | ||||
~BitcoinApplication(); | ~BitcoinApplication(); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
/// Create payment server | /// Create payment server | ||||
void createPaymentServer(); | void createPaymentServer(); | ||||
#endif | #endif | ||||
/// parameter interaction/setup based on rules | /// parameter interaction/setup based on rules | ||||
void parameterSetup(); | void parameterSetup(); | ||||
Show All 27 Lines | Q_SIGNALS: | ||||
void requestedInitialize(Config *config, | void requestedInitialize(Config *config, | ||||
HTTPRPCRequestProcessor *httpRPCRequestProcessor); | HTTPRPCRequestProcessor *httpRPCRequestProcessor); | ||||
void requestedShutdown(); | void requestedShutdown(); | ||||
void stopThread(); | void stopThread(); | ||||
void splashFinished(QWidget *window); | void splashFinished(QWidget *window); | ||||
private: | private: | ||||
QThread *coreThread; | QThread *coreThread; | ||||
interface::Node &m_node; | |||||
OptionsModel *optionsModel; | OptionsModel *optionsModel; | ||||
ClientModel *clientModel; | ClientModel *clientModel; | ||||
BitcoinGUI *window; | BitcoinGUI *window; | ||||
QTimer *pollShutdownTimer; | QTimer *pollShutdownTimer; | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
PaymentServer *paymentServer; | PaymentServer *paymentServer; | ||||
std::vector<WalletModel *> m_wallet_models; | std::vector<WalletModel *> m_wallet_models; | ||||
#endif | #endif | ||||
int returnValue; | int returnValue; | ||||
const PlatformStyle *platformStyle; | const PlatformStyle *platformStyle; | ||||
std::unique_ptr<QWidget> shutdownWindow; | std::unique_ptr<QWidget> shutdownWindow; | ||||
void startThread(); | void startThread(); | ||||
}; | }; | ||||
#include "bitcoin.moc" | #include "bitcoin.moc" | ||||
BitcoinABC::BitcoinABC() : QObject() {} | BitcoinABC::BitcoinABC(interface::Node &node) : QObject(), m_node(node) {} | ||||
void BitcoinABC::handleRunawayException(const std::exception *e) { | void BitcoinABC::handleRunawayException(const std::exception *e) { | ||||
PrintExceptionContinue(e, "Runaway exception"); | PrintExceptionContinue(e, "Runaway exception"); | ||||
Q_EMIT runawayException(QString::fromStdString(GetWarnings("gui"))); | Q_EMIT runawayException(QString::fromStdString(m_node.getWarnings("gui"))); | ||||
} | |||||
bool BitcoinABC::baseInitialize(Config &config, RPCServer &rpcServer) { | |||||
if (!AppInitBasicSetup()) { | |||||
return false; | |||||
} | |||||
if (!AppInitParameterInteraction(config, rpcServer)) { | |||||
return false; | |||||
} | |||||
if (!AppInitSanityChecks()) { | |||||
return false; | |||||
} | |||||
if (!AppInitLockDataDirectory()) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | } | ||||
void BitcoinABC::initialize(Config *cfg, | void BitcoinABC::initialize(Config *cfg, | ||||
HTTPRPCRequestProcessor *httpRPCRequestProcessor) { | HTTPRPCRequestProcessor *httpRPCRequestProcessor) { | ||||
Config &config(*cfg); | Config &config(*cfg); | ||||
try { | try { | ||||
qDebug() << __func__ << ": Running initialization in thread"; | qDebug() << __func__ << ": Running initialization in thread"; | ||||
bool rv = AppInitMain(config, *httpRPCRequestProcessor); | bool rv = m_node.appInitMain(config, *httpRPCRequestProcessor); | ||||
Q_EMIT initializeResult(rv); | Q_EMIT initializeResult(rv); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
handleRunawayException(&e); | handleRunawayException(&e); | ||||
} catch (...) { | } catch (...) { | ||||
handleRunawayException(nullptr); | handleRunawayException(nullptr); | ||||
} | } | ||||
} | } | ||||
void BitcoinABC::shutdown() { | void BitcoinABC::shutdown() { | ||||
try { | try { | ||||
qDebug() << __func__ << ": Running Shutdown in thread"; | qDebug() << __func__ << ": Running Shutdown in thread"; | ||||
Interrupt(); | m_node.appShutdown(); | ||||
Shutdown(); | |||||
qDebug() << __func__ << ": Shutdown finished"; | qDebug() << __func__ << ": Shutdown finished"; | ||||
Q_EMIT shutdownResult(); | Q_EMIT shutdownResult(); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
handleRunawayException(&e); | handleRunawayException(&e); | ||||
} catch (...) { | } catch (...) { | ||||
handleRunawayException(nullptr); | handleRunawayException(nullptr); | ||||
} | } | ||||
} | } | ||||
BitcoinApplication::BitcoinApplication(int &argc, char **argv) | BitcoinApplication::BitcoinApplication(interface::Node &node, int &argc, | ||||
: QApplication(argc, argv), coreThread(0), optionsModel(0), clientModel(0), | char **argv) | ||||
window(0), pollShutdownTimer(0), | : QApplication(argc, argv), coreThread(0), m_node(node), optionsModel(0), | ||||
clientModel(0), window(0), pollShutdownTimer(0), | |||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
paymentServer(0), m_wallet_models(), | paymentServer(0), m_wallet_models(), | ||||
#endif | #endif | ||||
returnValue(0) { | returnValue(0) { | ||||
setQuitOnLastWindowClosed(false); | setQuitOnLastWindowClosed(false); | ||||
// UI per-platform customization. | // UI per-platform customization. | ||||
// This must be done inside the BitcoinApplication constructor, or after it, | // This must be done inside the BitcoinApplication constructor, or after it, | ||||
Show All 31 Lines | |||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
void BitcoinApplication::createPaymentServer() { | void BitcoinApplication::createPaymentServer() { | ||||
paymentServer = new PaymentServer(this); | paymentServer = new PaymentServer(this); | ||||
} | } | ||||
#endif | #endif | ||||
void BitcoinApplication::createOptionsModel(bool resetSettings) { | void BitcoinApplication::createOptionsModel(bool resetSettings) { | ||||
optionsModel = new OptionsModel(nullptr, resetSettings); | optionsModel = new OptionsModel(m_node, nullptr, resetSettings); | ||||
} | } | ||||
void BitcoinApplication::createWindow(const Config *config, | void BitcoinApplication::createWindow(const Config *config, | ||||
const NetworkStyle *networkStyle) { | const NetworkStyle *networkStyle) { | ||||
window = new BitcoinGUI(config, platformStyle, networkStyle, 0); | window = new BitcoinGUI(m_node, config, platformStyle, networkStyle, 0); | ||||
pollShutdownTimer = new QTimer(window); | pollShutdownTimer = new QTimer(window); | ||||
connect(pollShutdownTimer, SIGNAL(timeout()), window, | connect(pollShutdownTimer, SIGNAL(timeout()), window, | ||||
SLOT(detectShutdown())); | SLOT(detectShutdown())); | ||||
} | } | ||||
void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { | void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { | ||||
SplashScreen *splash = new SplashScreen(0, networkStyle); | SplashScreen *splash = new SplashScreen(m_node, 0, networkStyle); | ||||
// We don't hold a direct pointer to the splash screen after creation, but | // We don't hold a direct pointer to the splash screen after creation, but | ||||
// the splash screen will take care of deleting itself when slotFinish | // the splash screen will take care of deleting itself when slotFinish | ||||
// happens. | // happens. | ||||
splash->show(); | splash->show(); | ||||
connect(this, SIGNAL(splashFinished(QWidget *)), splash, | connect(this, SIGNAL(splashFinished(QWidget *)), splash, | ||||
SLOT(slotFinish(QWidget *))); | SLOT(slotFinish(QWidget *))); | ||||
connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close())); | connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close())); | ||||
} | } | ||||
void BitcoinApplication::startThread() { | void BitcoinApplication::startThread() { | ||||
if (coreThread) { | if (coreThread) { | ||||
return; | return; | ||||
} | } | ||||
coreThread = new QThread(this); | coreThread = new QThread(this); | ||||
BitcoinABC *executor = new BitcoinABC(); | BitcoinABC *executor = new BitcoinABC(m_node); | ||||
executor->moveToThread(coreThread); | executor->moveToThread(coreThread); | ||||
/* communication to and from thread */ | /* communication to and from thread */ | ||||
connect(executor, SIGNAL(initializeResult(bool)), this, | connect(executor, SIGNAL(initializeResult(bool)), this, | ||||
SLOT(initializeResult(bool))); | SLOT(initializeResult(bool))); | ||||
connect(executor, SIGNAL(shutdownResult()), this, SLOT(shutdownResult())); | connect(executor, SIGNAL(shutdownResult()), this, SLOT(shutdownResult())); | ||||
connect(executor, SIGNAL(runawayException(QString)), this, | connect(executor, SIGNAL(runawayException(QString)), this, | ||||
SLOT(handleRunawayException(QString))); | SLOT(handleRunawayException(QString))); | ||||
Show All 19 Lines | void BitcoinApplication::startThread() { | ||||
/* make sure executor object is deleted in its own thread */ | /* make sure executor object is deleted in its own thread */ | ||||
connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater())); | connect(this, SIGNAL(stopThread()), executor, SLOT(deleteLater())); | ||||
connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit())); | connect(this, SIGNAL(stopThread()), coreThread, SLOT(quit())); | ||||
coreThread->start(); | coreThread->start(); | ||||
} | } | ||||
void BitcoinApplication::parameterSetup() { | void BitcoinApplication::parameterSetup() { | ||||
InitLogging(); | m_node.initLogging(); | ||||
InitParameterInteraction(); | m_node.initParameterInteraction(); | ||||
} | } | ||||
void BitcoinApplication::requestInitialize( | void BitcoinApplication::requestInitialize( | ||||
Config &config, HTTPRPCRequestProcessor &httpRPCRequestProcessor) { | Config &config, HTTPRPCRequestProcessor &httpRPCRequestProcessor) { | ||||
qDebug() << __func__ << ": Requesting initialize"; | qDebug() << __func__ << ": Requesting initialize"; | ||||
startThread(); | startThread(); | ||||
// IMPORTANT: config must NOT be a reference to a temporary because below | // IMPORTANT: config must NOT be a reference to a temporary because below | ||||
// signal may be connected to a slot that will be executed as a queued | // signal may be connected to a slot that will be executed as a queued | ||||
Show All 18 Lines | #ifdef ENABLE_WALLET | ||||
for (WalletModel *walletModel : m_wallet_models) { | for (WalletModel *walletModel : m_wallet_models) { | ||||
delete walletModel; | delete walletModel; | ||||
} | } | ||||
m_wallet_models.clear(); | m_wallet_models.clear(); | ||||
#endif | #endif | ||||
delete clientModel; | delete clientModel; | ||||
clientModel = 0; | clientModel = 0; | ||||
StartShutdown(); | m_node.startShutdown(); | ||||
// Request shutdown from core thread | // Request shutdown from core thread | ||||
Q_EMIT requestedShutdown(); | Q_EMIT requestedShutdown(); | ||||
} | } | ||||
void BitcoinApplication::initializeResult(bool success) { | void BitcoinApplication::initializeResult(bool success) { | ||||
qDebug() << __func__ << ": Initialization result: " << success; | qDebug() << __func__ << ": Initialization result: " << success; | ||||
returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE; | returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE; | ||||
if (!success) { | if (!success) { | ||||
// Make sure splash screen doesn't stick around during shutdown. | // Make sure splash screen doesn't stick around during shutdown. | ||||
Q_EMIT splashFinished(window); | Q_EMIT splashFinished(window); | ||||
// Exit first main loop invocation. | // Exit first main loop invocation. | ||||
quit(); | quit(); | ||||
return; | return; | ||||
} | } | ||||
// Log this only after AppInit2 finishes, as then logging setup is | // Log this only after AppInit2 finishes, as then logging setup is | ||||
// guaranteed complete. | // guaranteed complete. | ||||
qWarning() << "Platform customization:" << platformStyle->getName(); | qWarning() << "Platform customization:" << platformStyle->getName(); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
PaymentServer::LoadRootCAs(); | PaymentServer::LoadRootCAs(); | ||||
paymentServer->setOptionsModel(optionsModel); | paymentServer->setOptionsModel(optionsModel); | ||||
#endif | #endif | ||||
clientModel = new ClientModel(optionsModel); | clientModel = new ClientModel(m_node, optionsModel); | ||||
window->setClientModel(clientModel); | window->setClientModel(clientModel); | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
bool fFirstWallet = true; | bool fFirstWallet = true; | ||||
for (CWalletRef pwallet : vpwallets) { | auto wallets = m_node.getWallets(); | ||||
WalletModel *const walletModel = | for (auto &wallet : wallets) { | ||||
new WalletModel(platformStyle, pwallet, optionsModel); | WalletModel *const walletModel = new WalletModel( | ||||
std::move(wallet), m_node, platformStyle, optionsModel); | |||||
window->addWallet(walletModel); | window->addWallet(walletModel); | ||||
if (fFirstWallet) { | if (fFirstWallet) { | ||||
window->setCurrentWallet(walletModel->getWalletName()); | window->setCurrentWallet(walletModel->getWalletName()); | ||||
fFirstWallet = false; | fFirstWallet = false; | ||||
} | } | ||||
connect(walletModel, | connect( | ||||
SIGNAL(coinsSent(CWallet *, SendCoinsRecipient, QByteArray)), | walletModel, | ||||
SIGNAL(coinsSent(WalletModel *, SendCoinsRecipient, QByteArray)), | |||||
paymentServer, | paymentServer, | ||||
SLOT(fetchPaymentACK(CWallet *, const SendCoinsRecipient &, | SLOT(fetchPaymentACK(WalletModel *, const SendCoinsRecipient &, | ||||
QByteArray))); | QByteArray))); | ||||
m_wallet_models.push_back(walletModel); | m_wallet_models.push_back(walletModel); | ||||
} | } | ||||
#endif | #endif | ||||
// If -min option passed, start window minimized. | // If -min option passed, start window minimized. | ||||
if (gArgs.GetBoolArg("-min", false)) { | if (gArgs.GetBoolArg("-min", false)) { | ||||
window->showMinimized(); | window->showMinimized(); | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | if (!legacyKeys.isEmpty() && abc.allKeys().isEmpty()) { | ||||
abc.setValue(key, legacy.value(key)); | abc.setValue(key, legacy.value(key)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||||
SetupEnvironment(); | SetupEnvironment(); | ||||
std::unique_ptr<interface::Node> node = interface::MakeNode(); | |||||
/// 1. Parse command-line options. These take precedence over anything else. | /// 1. Parse command-line options. These take precedence over anything else. | ||||
// Command-line options take precedence: | // Command-line options take precedence: | ||||
gArgs.ParseParameters(argc, argv); | node->parseParameters(argc, argv); | ||||
// Do not refer to data directory yet, this can be overridden by | // Do not refer to data directory yet, this can be overridden by | ||||
// Intro::pickDataDirectory | // Intro::pickDataDirectory | ||||
/// 2. Basic Qt initialization (not dependent on parameters or | /// 2. Basic Qt initialization (not dependent on parameters or | ||||
/// configuration) | /// configuration) | ||||
Q_INIT_RESOURCE(bitcoin); | Q_INIT_RESOURCE(bitcoin); | ||||
Q_INIT_RESOURCE(bitcoin_locale); | Q_INIT_RESOURCE(bitcoin_locale); | ||||
BitcoinApplication app(argc, argv); | BitcoinApplication app(*node, argc, argv); | ||||
#if QT_VERSION > 0x050100 | #if QT_VERSION > 0x050100 | ||||
// Generate high-dpi pixmaps | // Generate high-dpi pixmaps | ||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); | QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); | ||||
#endif | #endif | ||||
#if QT_VERSION >= 0x050600 | #if QT_VERSION >= 0x050600 | ||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); | ||||
#endif | #endif | ||||
#ifdef Q_OS_MAC | #ifdef Q_OS_MAC | ||||
Show All 37 Lines | #endif | ||||
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; | QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator; | ||||
initTranslations(qtTranslatorBase, qtTranslator, translatorBase, | initTranslations(qtTranslatorBase, qtTranslator, translatorBase, | ||||
translator); | translator); | ||||
translationInterface.Translate.connect(Translate); | translationInterface.Translate.connect(Translate); | ||||
// Show help message immediately after parsing command-line options (for | // Show help message immediately after parsing command-line options (for | ||||
// "-lang") and setting locale, but before showing splash screen. | // "-lang") and setting locale, but before showing splash screen. | ||||
if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { | if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { | ||||
HelpMessageDialog help(nullptr, gArgs.IsArgSet("-version")); | HelpMessageDialog help(*node, nullptr, gArgs.IsArgSet("-version")); | ||||
help.showOrPrint(); | help.showOrPrint(); | ||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||||
} | } | ||||
/// 5. Now that settings and translations are available, ask user for data | /// 5. Now that settings and translations are available, ask user for data | ||||
/// directory. User language is set up: pick a data directory. | /// directory. User language is set up: pick a data directory. | ||||
if (!Intro::pickDataDirectory()) { | if (!Intro::pickDataDirectory(*node)) { | ||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||||
} | } | ||||
/// 6. Determine availability of data directory and parse bitcoin.conf | /// 6. Determine availability of data directory and parse bitcoin.conf | ||||
/// - Do not call GetDataDir(true) before this step finishes. | /// - Do not call GetDataDir(true) before this step finishes. | ||||
if (!fs::is_directory(GetDataDir(false))) { | if (!fs::is_directory(GetDataDir(false))) { | ||||
QMessageBox::critical( | QMessageBox::critical( | ||||
0, QObject::tr(PACKAGE_NAME), | 0, QObject::tr(PACKAGE_NAME), | ||||
QObject::tr( | QObject::tr( | ||||
"Error: Specified data directory \"%1\" does not exist.") | "Error: Specified data directory \"%1\" does not exist.") | ||||
.arg(QString::fromStdString(gArgs.GetArg("-datadir", "")))); | .arg(QString::fromStdString(gArgs.GetArg("-datadir", "")))); | ||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
try { | try { | ||||
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); | node->readConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
QMessageBox::critical( | QMessageBox::critical( | ||||
0, QObject::tr(PACKAGE_NAME), | 0, QObject::tr(PACKAGE_NAME), | ||||
QObject::tr("Error: Cannot parse configuration file: %1. Only use " | QObject::tr("Error: Cannot parse configuration file: %1. Only use " | ||||
"key=value syntax.") | "key=value syntax.") | ||||
.arg(e.what())); | .arg(e.what())); | ||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
/// 7. Determine network (and switch to network specific options) | /// 7. Determine network (and switch to network specific options) | ||||
// - Do not call Params() before this step. | // - Do not call Params() before this step. | ||||
// - Do this after parsing the configuration file, as the network can be | // - Do this after parsing the configuration file, as the network can be | ||||
// switched there. | // switched there. | ||||
// - QSettings() will use the new application name after this, resulting in | // - QSettings() will use the new application name after this, resulting in | ||||
// network-specific settings. | // network-specific settings. | ||||
// - Needs to be done before createOptionsModel. | // - Needs to be done before createOptionsModel. | ||||
// Check for -testnet or -regtest parameter (Params() calls are only valid | // Check for -testnet or -regtest parameter (Params() calls are only valid | ||||
// after this clause) | // after this clause) | ||||
try { | try { | ||||
SelectParams(gArgs.GetChainName()); | node->selectParams(gArgs.GetChainName()); | ||||
} catch (std::exception &e) { | } catch (std::exception &e) { | ||||
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), | QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), | ||||
QObject::tr("Error: %1").arg(e.what())); | QObject::tr("Error: %1").arg(e.what())); | ||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
#ifdef ENABLE_WALLET | #ifdef ENABLE_WALLET | ||||
// Parse URIs on command line -- this can affect Params() | // Parse URIs on command line -- this can affect Params() | ||||
PaymentServer::ipcParseCommandLine(argc, argv); | PaymentServer::ipcParseCommandLine(*node, argc, argv); | ||||
#endif | #endif | ||||
QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate( | QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate( | ||||
QString::fromStdString(Params().NetworkIDString()))); | QString::fromStdString(Params().NetworkIDString()))); | ||||
assert(!networkStyle.isNull()); | assert(!networkStyle.isNull()); | ||||
// Allow for separate UI settings for testnets | // Allow for separate UI settings for testnets | ||||
QApplication::setApplicationName(networkStyle->getAppName()); | QApplication::setApplicationName(networkStyle->getAppName()); | ||||
// Re-initialize translations after changing application name (language in | // Re-initialize translations after changing application name (language in | ||||
Show All 33 Lines | #endif | ||||
// Install qDebug() message handler to route to debug.log | // Install qDebug() message handler to route to debug.log | ||||
qInstallMessageHandler(DebugMessageHandler); | qInstallMessageHandler(DebugMessageHandler); | ||||
// Allow parameter interaction before we create the options model | // Allow parameter interaction before we create the options model | ||||
app.parameterSetup(); | app.parameterSetup(); | ||||
// Load GUI settings from QSettings | // Load GUI settings from QSettings | ||||
app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false)); | app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false)); | ||||
// Subscribe to global signals from core | // Subscribe to global signals from core | ||||
uiInterface.InitMessage.connect(InitMessage); | std::unique_ptr<interface::Handler> handler = | ||||
node->handleInitMessage(InitMessage); | |||||
// Get global config | // Get global config | ||||
Config &config = const_cast<Config &>(GetConfig()); | Config &config = const_cast<Config &>(GetConfig()); | ||||
if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && | if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && | ||||
!gArgs.GetBoolArg("-min", false)) { | !gArgs.GetBoolArg("-min", false)) { | ||||
app.createSplashScreen(networkStyle.data()); | app.createSplashScreen(networkStyle.data()); | ||||
} | } | ||||
RPCServer rpcServer; | RPCServer rpcServer; | ||||
HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer); | HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer); | ||||
try { | try { | ||||
app.createWindow(&config, networkStyle.data()); | app.createWindow(&config, networkStyle.data()); | ||||
// Perform base initialization before spinning up | // Perform base initialization before spinning up | ||||
// initialization/shutdown thread. This is acceptable because this | // initialization/shutdown thread. This is acceptable because this | ||||
// function only contains steps that are quick to execute, so the GUI | // function only contains steps that are quick to execute, so the GUI | ||||
// thread won't be held up. | // thread won't be held up. | ||||
if (!BitcoinABC::baseInitialize(config, rpcServer)) { | if (!node->baseInitialize(config, rpcServer)) { | ||||
// A dialog with detailed error will have been shown by InitError() | // A dialog with detailed error will have been shown by InitError() | ||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
app.requestInitialize(config, httpRPCRequestProcessor); | app.requestInitialize(config, httpRPCRequestProcessor); | ||||
#if defined(Q_OS_WIN) | #if defined(Q_OS_WIN) | ||||
WinShutdownMonitor::registerShutdownBlockReason( | WinShutdownMonitor::registerShutdownBlockReason( | ||||
QObject::tr("%1 didn't yet exit safely...") | QObject::tr("%1 didn't yet exit safely...") | ||||
.arg(QObject::tr(PACKAGE_NAME)), | .arg(QObject::tr(PACKAGE_NAME)), | ||||
(HWND)app.getMainWinId()); | (HWND)app.getMainWinId()); | ||||
#endif | #endif | ||||
app.exec(); | app.exec(); | ||||
app.requestShutdown(config); | app.requestShutdown(config); | ||||
app.exec(); | app.exec(); | ||||
return app.getReturnValue(); | return app.getReturnValue(); | ||||
} catch (const std::exception &e) { | } catch (const std::exception &e) { | ||||
PrintExceptionContinue(&e, "Runaway exception"); | PrintExceptionContinue(&e, "Runaway exception"); | ||||
app.handleRunawayException(QString::fromStdString(GetWarnings("gui"))); | app.handleRunawayException( | ||||
QString::fromStdString(node->getWarnings("gui"))); | |||||
} catch (...) { | } catch (...) { | ||||
PrintExceptionContinue(nullptr, "Runaway exception"); | PrintExceptionContinue(nullptr, "Runaway exception"); | ||||
app.handleRunawayException(QString::fromStdString(GetWarnings("gui"))); | app.handleRunawayException( | ||||
QString::fromStdString(node->getWarnings("gui"))); | |||||
} | } | ||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
#endif // BITCOIN_QT_TEST | #endif // BITCOIN_QT_TEST |