Bitcoin ABC  0.24.7
P2P Digital Currency
bitcoin.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2019 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <qt/bitcoin.h>
6 
7 #include <chainparams.h>
8 #include <config.h>
9 #include <httprpc.h>
10 #include <init.h>
11 #include <interfaces/handler.h>
12 #include <interfaces/node.h>
13 #include <node/context.h>
14 #include <node/ui_interface.h>
15 #include <noui.h>
16 #include <qt/bitcoingui.h>
17 #include <qt/clientmodel.h>
18 #include <qt/guiconstants.h>
19 #include <qt/guiutil.h>
20 #include <qt/intro.h>
21 #include <qt/networkstyle.h>
22 #include <qt/optionsmodel.h>
23 #include <qt/platformstyle.h>
24 #include <qt/splashscreen.h>
25 #include <qt/utilitydialog.h>
26 #include <qt/winshutdownmonitor.h>
27 #include <uint256.h>
28 #include <util/ref.h>
29 #include <util/system.h>
30 #include <util/threadnames.h>
31 #include <util/translation.h>
32 #include <validation.h>
33 
34 #ifdef ENABLE_WALLET
35 #include <qt/paymentserver.h>
36 #include <qt/walletcontroller.h>
37 #include <qt/walletmodel.h>
38 #endif // ENABLE_WALLET
39 
40 #include <QDebug>
41 #include <QLibraryInfo>
42 #include <QLocale>
43 #include <QMessageBox>
44 #include <QSettings>
45 #include <QStringList>
46 #include <QThread>
47 #include <QTimer>
48 #include <QTranslator>
49 
50 #include <boost/signals2/connection.hpp>
51 
52 #if defined(QT_STATICPLUGIN)
53 #include <QtPlugin>
54 #if defined(QT_QPA_PLATFORM_XCB)
55 Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
56 #elif defined(QT_QPA_PLATFORM_WINDOWS)
57 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
58 #elif defined(QT_QPA_PLATFORM_COCOA)
59 Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
60 #endif
61 #endif
62 
63 // Declare meta types used for QMetaObject::invokeMethod
64 Q_DECLARE_METATYPE(bool *)
65 Q_DECLARE_METATYPE(Amount)
66 Q_DECLARE_METATYPE(SynchronizationState)
67 Q_DECLARE_METATYPE(uint256)
68 
69 // Config is non-copyable so we can only register pointers to it
70 Q_DECLARE_METATYPE(Config *)
71 
72 static void RegisterMetaTypes() {
73  // Register meta types used for QMetaObject::invokeMethod and
74  // Qt::QueuedConnection
75  qRegisterMetaType<bool *>();
76  qRegisterMetaType<SynchronizationState>();
77 #ifdef ENABLE_WALLET
78  qRegisterMetaType<WalletModel *>();
79 #endif
80  qRegisterMetaType<Amount>();
81  // Register typedefs (see
82  // http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType)
83  qRegisterMetaType<size_t>("size_t");
84 
85  qRegisterMetaType<std::function<void()>>("std::function<void()>");
86  qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon");
87  qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>(
88  "interfaces::BlockAndHeaderTipInfo");
89 
90  // Need to register any types Qt doesn't know about if you intend
91  // to use them with the signal/slot mechanism Qt provides. Even pointers.
92  // Note that class Config is noncopyable and so we can't register a
93  // non-pointer version of it with Qt, because Qt expects to be able to
94  // copy-construct non-pointers to objects for invoking slots
95  // behind-the-scenes in the 'Queued' connection case.
96  qRegisterMetaType<Config *>();
97 }
98 
99 static QString GetLangTerritory() {
100  QSettings settings;
101  // Get desired locale (e.g. "de_DE")
102  // 1) System default language
103  QString lang_territory = QLocale::system().name();
104  // 2) Language from QSettings
105  QString lang_territory_qsettings =
106  settings.value("language", "").toString();
107  if (!lang_territory_qsettings.isEmpty()) {
108  lang_territory = lang_territory_qsettings;
109  }
110  // 3) -lang command line argument
111  lang_territory = QString::fromStdString(
112  gArgs.GetArg("-lang", lang_territory.toStdString()));
113  return lang_territory;
114 }
115 
117 static void initTranslations(QTranslator &qtTranslatorBase,
118  QTranslator &qtTranslator,
119  QTranslator &translatorBase,
120  QTranslator &translator) {
121  // Remove old translators
122  QApplication::removeTranslator(&qtTranslatorBase);
123  QApplication::removeTranslator(&qtTranslator);
124  QApplication::removeTranslator(&translatorBase);
125  QApplication::removeTranslator(&translator);
126 
127  // Get desired locale (e.g. "de_DE")
128  // 1) System default language
129  QString lang_territory = GetLangTerritory();
130 
131  // Convert to "de" only by truncating "_DE"
132  QString lang = lang_territory;
133  lang.truncate(lang_territory.lastIndexOf('_'));
134 
135  // Load language files for configured locale:
136  // - First load the translator for the base language, without territory
137  // - Then load the more specific locale translator
138 
139  // Load e.g. qt_de.qm
140  if (qtTranslatorBase.load(
141  "qt_" + lang,
142  QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
143  QApplication::installTranslator(&qtTranslatorBase);
144  }
145 
146  // Load e.g. qt_de_DE.qm
147  if (qtTranslator.load(
148  "qt_" + lang_territory,
149  QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
150  QApplication::installTranslator(&qtTranslator);
151  }
152 
153  // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in
154  // bitcoin.qrc)
155  if (translatorBase.load(lang, ":/translations/")) {
156  QApplication::installTranslator(&translatorBase);
157  }
158 
159  // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in
160  // bitcoin.qrc)
161  if (translator.load(lang_territory, ":/translations/")) {
162  QApplication::installTranslator(&translator);
163  }
164 }
165 
166 /* qDebug() message handler --> debug.log */
167 void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context,
168  const QString &msg) {
169  Q_UNUSED(context);
170  if (type == QtDebugMsg) {
171  LogPrint(BCLog::QT, "GUI: %s\n", msg.toStdString());
172  } else {
173  LogPrintf("GUI: %s\n", msg.toStdString());
174  }
175 }
176 
177 BitcoinABC::BitcoinABC(interfaces::Node &node) : QObject(), m_node(node) {}
178 
179 void BitcoinABC::handleRunawayException(const std::exception *e) {
180  PrintExceptionContinue(e, "Runaway exception");
181  Q_EMIT runawayException(
182  QString::fromStdString(m_node.getWarnings().translated));
183 }
184 
185 void BitcoinABC::initialize(Config *config, RPCServer *rpcServer,
186  HTTPRPCRequestProcessor *httpRPCRequestProcessor) {
187  try {
188  util::ThreadRename("qt-init");
189  qDebug() << __func__ << ": Running initialization in thread";
191  bool rv = m_node.appInitMain(*config, *rpcServer,
192  *httpRPCRequestProcessor, &tip_info);
193  Q_EMIT initializeResult(rv, tip_info);
194  } catch (const std::exception &e) {
196  } catch (...) {
197  handleRunawayException(nullptr);
198  }
199 }
200 
202  try {
203  qDebug() << __func__ << ": Running Shutdown in thread";
205  qDebug() << __func__ << ": Shutdown finished";
206  Q_EMIT shutdownResult();
207  } catch (const std::exception &e) {
209  } catch (...) {
210  handleRunawayException(nullptr);
211  }
212 }
213 
214 static int qt_argc = 1;
215 static const char *qt_argv = "bitcoin-qt";
216 
218  : QApplication(qt_argc, const_cast<char **>(&qt_argv)), coreThread(nullptr),
219  optionsModel(nullptr), clientModel(nullptr), window(nullptr),
220  pollShutdownTimer(nullptr), returnValue(0), platformStyle(nullptr) {
221  // Qt runs setlocale(LC_ALL, "") on initialization.
223  setQuitOnLastWindowClosed(false);
224 }
225 
227  // UI per-platform customization
228  // This must be done inside the BitcoinApplication constructor, or after it,
229  // because PlatformStyle::instantiate requires a QApplication.
230  std::string platformName;
231  platformName = gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM);
232  platformStyle =
233  PlatformStyle::instantiate(QString::fromStdString(platformName));
234  // Fall back to "other" if specified name not found.
235  if (!platformStyle) {
237  }
238  assert(platformStyle);
239 }
240 
242  if (coreThread) {
243  qDebug() << __func__ << ": Stopping thread";
244  coreThread->quit();
245  coreThread->wait();
246  qDebug() << __func__ << ": Stopped thread";
247  }
248 
249  delete window;
250  window = nullptr;
251  delete platformStyle;
252  platformStyle = nullptr;
253 }
254 
255 #ifdef ENABLE_WALLET
256 void BitcoinApplication::createPaymentServer() {
257  paymentServer = new PaymentServer(this);
258 }
259 #endif
260 
261 void BitcoinApplication::createOptionsModel(bool resetSettings) {
262  optionsModel = new OptionsModel(this, resetSettings);
263 }
264 
266  const NetworkStyle *networkStyle) {
267  window =
268  new BitcoinGUI(node(), config, platformStyle, networkStyle, nullptr);
269 
270  pollShutdownTimer = new QTimer(window);
271  connect(pollShutdownTimer, &QTimer::timeout, window,
273 }
274 
276  assert(!m_splash);
277  m_splash = new SplashScreen(networkStyle);
278  // We don't hold a direct pointer to the splash screen after creation, but
279  // the splash screen will take care of deleting itself when finish()
280  // happens.
281  m_splash->show();
287  &QWidget::close);
288 }
289 
291  assert(!m_node);
292  m_node = &node;
293  if (optionsModel) {
295  }
296  if (m_splash) {
298  }
299 }
300 
302  return node().baseInitialize(config);
303 }
304 
306  if (coreThread) {
307  return;
308  }
309  coreThread = new QThread(this);
310  BitcoinABC *executor = new BitcoinABC(node());
311  executor->moveToThread(coreThread);
312 
313  /* communication to and from thread */
314  connect(executor, &BitcoinABC::initializeResult, this,
316  connect(executor, &BitcoinABC::shutdownResult, this,
318  connect(executor, &BitcoinABC::runawayException, this,
320 
321  // Note on how Qt works: it tries to directly invoke methods if the signal
322  // is emitted on the same thread that the target object 'lives' on.
323  // But if the target object 'lives' on another thread (executor here does)
324  // the SLOT will be invoked asynchronously at a later time in the thread
325  // of the target object. So.. we pass a pointer around. If you pass
326  // a reference around (even if it's non-const) you'll get Qt generating
327  // code to copy-construct the parameter in question (Q_DECLARE_METATYPE
328  // and qRegisterMetaType generate this code). For the Config class,
329  // which is noncopyable, we can't do this. So.. we have to pass
330  // pointers to Config around. Make sure Config &/Config * isn't a
331  // temporary (eg it lives somewhere aside from the stack) or this will
332  // crash because initialize() gets executed in another thread at some
333  // unspecified time (after) requestedInitialize() is emitted!
334  connect(this, &BitcoinApplication::requestedInitialize, executor,
336 
337  connect(this, &BitcoinApplication::requestedShutdown, executor,
339  /* make sure executor object is deleted in its own thread */
340  connect(coreThread, &QThread::finished, executor, &QObject::deleteLater);
341 
342  coreThread->start();
343 }
344 
346  // Default printtoconsole to false for the GUI. GUI programs should not
347  // print to the console unnecessarily.
348  gArgs.SoftSetBoolArg("-printtoconsole", false);
349 
352 }
353 
355  // If prune is set, intentionally override existing prune size with
356  // the default size since this is called when choosing a new datadir.
358 }
359 
361  Config &config, RPCServer &rpcServer,
362  HTTPRPCRequestProcessor &httpRPCRequestProcessor) {
363  qDebug() << __func__ << ": Requesting initialize";
364  startThread();
365  // IMPORTANT: config must NOT be a reference to a temporary because below
366  // signal may be connected to a slot that will be executed as a queued
367  // connection in another thread!
368  Q_EMIT requestedInitialize(&config, &rpcServer, &httpRPCRequestProcessor);
369 }
370 
372  // Show a simple window indicating shutdown status. Do this first as some of
373  // the steps may take some time below, for example the RPC console may still
374  // be executing a command.
376 
377  qDebug() << __func__ << ": Requesting shutdown";
378  startThread();
379  window->hide();
380  // Must disconnect node signals otherwise current thread can deadlock since
381  // no event loop is running.
383  // Request node shutdown, which can interrupt long operations, like
384  // rescanning a wallet.
385  node().startShutdown();
386  // Unsetting the client model can cause the current thread to wait for node
387  // to complete an operation, like wait for a RPC execution to complete.
388  window->setClientModel(nullptr);
389  pollShutdownTimer->stop();
390 
391  delete clientModel;
392  clientModel = nullptr;
393 
394  // Request shutdown from core thread
395  Q_EMIT requestedShutdown();
396 }
397 
399  bool success, interfaces::BlockAndHeaderTipInfo tip_info) {
400  qDebug() << __func__ << ": Initialization result: " << success;
401  returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
402  if (!success) {
403  // Make sure splash screen doesn't stick around during shutdown.
404  Q_EMIT splashFinished();
405  // Exit first main loop invocation.
406  quit();
407  return;
408  }
409  // Log this only after AppInitMain finishes, as then logging setup is
410  // guaranteed complete.
411  qInfo() << "Platform customization:" << platformStyle->getName();
413  window->setClientModel(clientModel, &tip_info);
414 #ifdef ENABLE_WALLET
416  m_wallet_controller =
418  window->setWalletController(m_wallet_controller);
419  if (paymentServer) {
420  paymentServer->setOptionsModel(optionsModel);
421 #ifdef ENABLE_BIP70
422  PaymentServer::LoadRootCAs();
423  connect(m_wallet_controller, &WalletController::coinsSent,
424  paymentServer, &PaymentServer::fetchPaymentACK);
425 #endif
426  }
427  }
428 #endif // ENABLE_WALLET
429 
430  // If -min option passed, start window minimized(iconified)
431  // or minimized to tray
432  if (!gArgs.GetBoolArg("-min", false)) {
433  window->show();
434  } else if (clientModel->getOptionsModel()->getMinimizeToTray() &&
435  window->hasTrayIcon()) {
436  // do nothing as the window is managed by the tray icon
437  } else {
438  window->showMinimized();
439  }
440  Q_EMIT splashFinished();
441  Q_EMIT windowShown(window);
442 
443 #ifdef ENABLE_WALLET
444  // Now that initialization/startup is done, process any command-line
445  // bitcoincash: URIs or payment requests:
446  if (paymentServer) {
447  connect(paymentServer, &PaymentServer::receivedPaymentRequest, window,
448  &BitcoinGUI::handlePaymentRequest);
449  connect(window, &BitcoinGUI::receivedURI, paymentServer,
451  connect(paymentServer, &PaymentServer::message,
452  [this](const QString &title, const QString &message,
453  unsigned int style) {
454  window->message(title, message, style);
455  });
456  QTimer::singleShot(100, paymentServer, &PaymentServer::uiReady);
457  }
458 #endif
459 
460  pollShutdownTimer->start(200);
461 }
462 
464  // Exit second main loop invocation after shutdown finished.
465  quit();
466 }
467 
468 void BitcoinApplication::handleRunawayException(const QString &message) {
469  QMessageBox::critical(
470  nullptr, "Runaway exception",
471  BitcoinGUI::tr("A fatal error occurred. %1 can no longer continue "
472  "safely and will quit.")
473  .arg(PACKAGE_NAME) +
474  QString("<br><br>") + message);
475  ::exit(EXIT_FAILURE);
476 }
477 
479  if (!window) {
480  return 0;
481  }
482 
483  return window->winId();
484 }
485 
486 static void SetupUIArgs(ArgsManager &argsman) {
487 #if defined(ENABLE_WALLET) && defined(ENABLE_BIP70)
488  argsman.AddArg(
489  "-allowselfsignedrootcertificates",
490  strprintf("Allow self signed root certificates (default: %d)",
493 #endif
494  argsman.AddArg("-choosedatadir",
495  strprintf("Choose data directory on startup (default: %d)",
498  argsman.AddArg(
499  "-lang=<lang>",
500  "Set language, for example \"de_DE\" (default: system locale)",
502  argsman.AddArg("-min", "Start minimized", ArgsManager::ALLOW_ANY,
504  argsman.AddArg(
505  "-rootcertificates=<file>",
506  "Set SSL root certificates for payment request (default: -system-)",
508  argsman.AddArg("-splash",
509  strprintf("Show splash screen on startup (default: %d)",
512  argsman.AddArg("-resetguisettings", "Reset all settings changed in the GUI",
514  argsman.AddArg("-uiplatform",
515  strprintf("Select platform to customize UI for (one of "
516  "windows, macosx, other; default: %s)",
520 }
521 
522 static void MigrateSettings() {
523  assert(!QApplication::applicationName().isEmpty());
524 
525  static const QString legacyAppName("Bitcoin-Qt"),
526 #ifdef Q_OS_DARWIN
527  // Macs and/or iOS et al use a domain-style name for Settings
528  // files. All other platforms use a simple orgname. This
529  // difference is documented in the QSettings class documentation.
530  legacyOrg("bitcoin.org");
531 #else
532  legacyOrg("Bitcoin");
533 #endif
534  QSettings
535  // below picks up settings file location based on orgname,appname
536  legacy(legacyOrg, legacyAppName),
537  // default c'tor below picks up settings file location based on
538  // QApplication::applicationName(), et al -- which was already set
539  // in main()
540  abc;
541 #ifdef Q_OS_DARWIN
542  // Disable bogus OSX keys from MacOS system-wide prefs that may cloud our
543  // judgement ;) (this behavior is also documented in QSettings docs)
544  legacy.setFallbacksEnabled(false);
545  abc.setFallbacksEnabled(false);
546 #endif
547  const QStringList legacyKeys(legacy.allKeys());
548 
549  // We only migrate settings if we have Core settings but no Bitcoin-ABC
550  // settings
551  if (!legacyKeys.isEmpty() && abc.allKeys().isEmpty()) {
552  for (const QString &key : legacyKeys) {
553  // now, copy settings over
554  abc.setValue(key, legacy.value(key));
555  }
556  }
557 }
558 
559 int GuiMain(int argc, char *argv[]) {
560 #ifdef WIN32
561  util::WinCmdLineArgs winArgs;
562  std::tie(argc, argv) = winArgs.get();
563 #endif
566 
567  NodeContext node_context;
568  std::unique_ptr<interfaces::Node> node =
569  interfaces::MakeNode(&node_context);
570 
571  // Subscribe to global signals from core
572  boost::signals2::scoped_connection handler_message_box =
573  ::uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox);
574  boost::signals2::scoped_connection handler_question =
575  ::uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion);
576  boost::signals2::scoped_connection handler_init_message =
577  ::uiInterface.InitMessage_connect(noui_InitMessage);
578 
579  // Do not refer to data directory yet, this can be overridden by
580  // Intro::pickDataDirectory
581 
584  Q_INIT_RESOURCE(bitcoin);
585  Q_INIT_RESOURCE(bitcoin_locale);
586 
587  // Generate high-dpi pixmaps
588  QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
589  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
590 
591  BitcoinApplication app;
592 
595  // Command-line options take precedence:
596  SetupServerArgs(node_context);
598  std::string error;
599  if (!gArgs.ParseParameters(argc, argv, error)) {
601  Untranslated("Error parsing command line arguments: %s\n"), error));
602  // Create a message box, because the gui has neither been created nor
603  // has subscribed to core signals
604  QMessageBox::critical(
605  nullptr, PACKAGE_NAME,
606  // message can not be translated because translations have not been
607  // initialized
608  QString::fromStdString("Error parsing command line arguments: %1.")
609  .arg(QString::fromStdString(error)));
610  return EXIT_FAILURE;
611  }
612 
613  // Now that the QApplication is setup and we have parsed our parameters, we
614  // can set the platform style
615  app.setupPlatformStyle();
616 
618  // must be set before OptionsModel is initialized or translations are
619  // loaded, as it is used to locate QSettings.
620  // Note: If you move these calls somewhere else, be sure to bring
621  // MigrateSettings() below along for the ride.
622  QApplication::setOrganizationName(QAPP_ORG_NAME);
623  QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
624  QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
625  // Migrate settings from core's/our old GUI settings to Bitcoin ABC
626  // only if core's exist but Bitcoin ABC's doesn't.
627  // NOTE -- this function needs to be called *after* the above 3 lines
628  // that set the app orgname and app name! If you move the above 3 lines
629  // to elsewhere, take this call with you!
630  MigrateSettings();
631 
634  QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
635  initTranslations(qtTranslatorBase, qtTranslator, translatorBase,
636  translator);
637 
638  // Show help message immediately after parsing command-line options (for
639  // "-lang") and setting locale, but before showing splash screen.
640  if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
641  HelpMessageDialog help(nullptr, gArgs.IsArgSet("-version"));
642  help.showOrPrint();
643  return EXIT_SUCCESS;
644  }
645 
648  bool did_show_intro = false;
649  // Intro dialog prune check box
650  bool prune = false;
651  // Gracefully exit if the user cancels
652  if (!Intro::showIfNeeded(did_show_intro, prune)) {
653  return EXIT_SUCCESS;
654  }
655 
659  if (!CheckDataDirOption()) {
661  Untranslated("Specified data directory \"%s\" does not exist.\n"),
662  gArgs.GetArg("-datadir", "")));
663  QMessageBox::critical(
664  nullptr, PACKAGE_NAME,
665  QObject::tr(
666  "Error: Specified data directory \"%1\" does not exist.")
667  .arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
668  return EXIT_FAILURE;
669  }
670  if (!gArgs.ReadConfigFiles(error)) {
672  Untranslated("Error reading configuration file: %s\n"), error));
673  QMessageBox::critical(
674  nullptr, PACKAGE_NAME,
675  QObject::tr("Error: Cannot parse configuration file: %1.")
676  .arg(QString::fromStdString(error)));
677  return EXIT_FAILURE;
678  }
679 
681  // - Do not call Params() before this step.
682  // - Do this after parsing the configuration file, as the network can be
683  // switched there.
684  // - QSettings() will use the new application name after this, resulting in
685  // network-specific settings.
686  // - Needs to be done before createOptionsModel.
687 
688  // Check for -chain, -testnet or -regtest parameter (Params() calls are only
689  // valid after this clause)
690  try {
692  } catch (std::exception &e) {
693  InitError(Untranslated(strprintf("%s\n", e.what())));
694  QMessageBox::critical(nullptr, PACKAGE_NAME,
695  QObject::tr("Error: %1").arg(e.what()));
696  return EXIT_FAILURE;
697  }
698 #ifdef ENABLE_WALLET
699  // Parse URIs on command line -- this can affect Params()
701 #endif
702  if (!gArgs.InitSettings(error)) {
704  QMessageBox::critical(nullptr, PACKAGE_NAME,
705  QObject::tr("Error initializing settings: %1")
706  .arg(QString::fromStdString(error)));
707  return EXIT_FAILURE;
708  }
709 
710  QScopedPointer<const NetworkStyle> networkStyle(
711  NetworkStyle::instantiate(Params().NetworkIDString()));
712  assert(!networkStyle.isNull());
713  // Allow for separate UI settings for testnets
714  QApplication::setApplicationName(networkStyle->getAppName());
715  // Re-initialize translations after changing application name (language in
716  // network-specific settings can be different)
717  initTranslations(qtTranslatorBase, qtTranslator, translatorBase,
718  translator);
719 
720 #ifdef ENABLE_WALLET
721  // - Do this early as we don't want to bother initializing if we are just
723  // calling IPC
724  // - Do this *after* setting up the data directory, as the data directory
725  // hash is used in the name
726  // of the server.
727  // - Do this after creating app and setting up translations, so errors are
728  // translated properly.
730  exit(EXIT_SUCCESS);
731  }
732 
733  // Start up the payment server early, too, so impatient users that click on
734  // bitcoincash: links repeatedly have their payment requests routed to this
735  // process:
737  app.createPaymentServer();
738  }
739 #endif // ENABLE_WALLET
740 
742  // Install global event filter that makes sure that long tooltips can be
743  // word-wrapped.
744  app.installEventFilter(
746  // Install global event filter that makes sure that out-of-focus labels do
747  // not contain text cursor.
748  app.installEventFilter(new GUIUtil::LabelOutOfFocusEventFilter(&app));
749 #if defined(Q_OS_WIN)
750  // Install global event filter for processing Windows session related
751  // Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
752  qApp->installNativeEventFilter(new WinShutdownMonitor());
753 #endif
754  // Install qDebug() message handler to route to debug.log
755  qInstallMessageHandler(DebugMessageHandler);
756  // Allow parameter interaction before we create the options model
757  app.parameterSetup();
759  // Load GUI settings from QSettings
760  app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
761 
762  if (did_show_intro) {
763  // Store intro dialog settings other than datadir (network specific)
764  app.InitializePruneSetting(prune);
765  }
766 
767  // Get global config
768  Config &config = const_cast<Config &>(GetConfig());
769 
770  if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) &&
771  !gArgs.GetBoolArg("-min", false)) {
772  app.createSplashScreen(networkStyle.data());
773  }
774 
775  app.setNode(*node);
776 
777  RPCServer rpcServer;
778  util::Ref context{node_context};
779  HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer, context);
780 
781  try {
782  app.createWindow(&config, networkStyle.data());
783  // Perform base initialization before spinning up
784  // initialization/shutdown thread. This is acceptable because this
785  // function only contains steps that are quick to execute, so the GUI
786  // thread won't be held up.
787  if (!app.baseInitialize(config)) {
788  // A dialog with detailed error will have been shown by InitError()
789  return EXIT_FAILURE;
790  }
791  app.requestInitialize(config, rpcServer, httpRPCRequestProcessor);
792 #if defined(Q_OS_WIN)
793  WinShutdownMonitor::registerShutdownBlockReason(
794  QObject::tr("%1 didn't yet exit safely...").arg(PACKAGE_NAME),
795  (HWND)app.getMainWinId());
796 #endif
797  app.exec();
798  app.requestShutdown(config);
799  app.exec();
800  return app.getReturnValue();
801  } catch (const std::exception &e) {
802  PrintExceptionContinue(&e, "Runaway exception");
804  QString::fromStdString(app.node().getWarnings().translated));
805  } catch (...) {
806  PrintExceptionContinue(nullptr, "Runaway exception");
808  QString::fromStdString(app.node().getWarnings().translated));
809  }
810  return EXIT_FAILURE;
811 }
winshutdownmonitor.h
BitcoinGUI::setClientModel
void setClientModel(ClientModel *clientModel=nullptr, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)
Set the client model.
Definition: bitcoingui.cpp:654
GUIUtil::ToolTipToRichTextFilter
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
Definition: guiutil.h:184
BitcoinApplication::setupPlatformStyle
void setupPlatformStyle()
Setup platform style.
Definition: bitcoin.cpp:226
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:517
BitcoinApplication::createSplashScreen
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
Definition: bitcoin.cpp:275
ref.h
DEFAULT_SPLASHSCREEN
static const bool DEFAULT_SPLASHSCREEN
Definition: guiconstants.h:19
BitcoinApplication::setNode
void setNode(interfaces::Node &node)
Definition: bitcoin.cpp:290
SplashScreen::setNode
void setNode(interfaces::Node &node)
Definition: splashscreen.cpp:154
BitcoinApplication::splashFinished
void splashFinished()
QAPP_ORG_NAME
#define QAPP_ORG_NAME
Definition: guiconstants.h:45
BitcoinApplication::platformStyle
const PlatformStyle * platformStyle
Definition: bitcoin.h:131
BitcoinApplication::node
interfaces::Node & node() const
Definition: bitcoin.h:99
BitcoinApplication::~BitcoinApplication
~BitcoinApplication()
Definition: bitcoin.cpp:241
GetLangTerritory
static QString GetLangTerritory()
Definition: bitcoin.cpp:99
HelpMessageDialog
"Help message" dialog box
Definition: utilitydialog.h:20
BitcoinGUI::receivedURI
void receivedURI(const QString &uri)
Signal raised when a URI was entered or dragged to the GUI.
InitParameterInteraction
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:1562
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:818
BitcoinABC::initializeResult
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
DEFAULT_SELFSIGNED_ROOTCERTS
static const bool DEFAULT_SELFSIGNED_ROOTCERTS
Definition: paymentrequestplus.h:22
ArgsManager::ALLOW_ANY
@ ALLOW_ANY
Definition: system.h:159
BitcoinApplication::handleRunawayException
void handleRunawayException(const QString &message)
Handle runaway exceptions.
Definition: bitcoin.cpp:468
interfaces::Node::baseInitialize
virtual bool baseInitialize(Config &config)=0
Initialize app dependencies.
BitcoinApplication::pollShutdownTimer
QTimer * pollShutdownTimer
Definition: bitcoin.h:125
ArgsManager::SoftSetBoolArg
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:534
uiInterface
CClientUIInterface uiInterface
Definition: ui_interface.cpp:12
InitLogging
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:1674
help
static RPCHelpMan help()
Definition: server.cpp:177
qt_argc
static int qt_argc
Definition: bitcoin.cpp:214
walletcontroller.h
intro.h
walletmodel.h
PaymentServer::message
void message(const QString &title, const QString &message, unsigned int style)
SplashScreen::finish
void finish()
Hide the splash screen window and schedule the splash screen object for deletion.
Definition: splashscreen.cpp:180
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1306
utilitydialog.h
WalletModel::isWalletEnabled
static bool isWalletEnabled()
Definition: walletmodel.cpp:514
initTranslations
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
Set up translations.
Definition: bitcoin.cpp:117
uint256.h
ArgsManager::GetChainName
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: system.cpp:1033
BitcoinABC::BitcoinABC
BitcoinABC(interfaces::Node &node)
Definition: bitcoin.cpp:177
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:400
node.h
handler.h
BitcoinApplication::optionsModel
OptionsModel * optionsModel
Definition: bitcoin.h:122
HTTPRPCRequestProcessor
Definition: httprpc.h:17
NetworkStyle
Definition: networkstyle.h:13
interfaces::BlockAndHeaderTipInfo
Block and header tip information.
Definition: node.h:46
PlatformStyle::getName
const QString & getName() const
Definition: platformstyle.h:18
ArgsManager::InitSettings
bool InitSettings(std::string &error)
Read and update settings file with saved settings.
Definition: system.cpp:404
SetupServerArgs
void SetupServerArgs(NodeContext &node)
Register all arguments with the ArgsManager.
Definition: init.cpp:388
interfaces::Node::appInitMain
virtual bool appInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)=0
Start node.
PaymentServer::ipcParseCommandLine
static void ipcParseCommandLine(int argc, char *argv[])
Definition: paymentserver.cpp:119
SplashScreen::handleLoadWallet
void handleLoadWallet()
Handle wallet load notifications.
Definition: splashscreen.cpp:220
BitcoinApplication::getReturnValue
int getReturnValue() const
Get process return value.
Definition: bitcoin.h:91
chainparams.h
BitcoinABC::shutdownResult
void shutdownResult()
context.h
BitcoinGUI::message
void message(const QString &title, QString message, unsigned int style, bool *ret=nullptr, const QString &detailed_message=QString())
Notify the user of an event from the core network or transaction handling code.
Definition: bitcoingui.cpp:1201
RPCServer
Class for registering and managing all RPC calls.
Definition: server.h:40
BitcoinGUI::hasTrayIcon
bool hasTrayIcon() const
Get the tray icon status.
Definition: bitcoingui.h:113
BitcoinApplication::requestInitialize
void requestInitialize(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor)
Request core initialization.
Definition: bitcoin.cpp:360
PaymentServer::uiReady
void uiReady()
Definition: paymentserver.cpp:299
interfaces::Node::appShutdown
virtual void appShutdown()=0
Stop node.
BitcoinApplication::requestedShutdown
void requestedShutdown()
TOOLTIP_WRAP_THRESHOLD
static const int TOOLTIP_WRAP_THRESHOLD
Definition: guiconstants.h:40
GUIUtil::LabelOutOfFocusEventFilter
Qt event filter that intercepts QEvent::FocusOut events for QLabel objects, and resets their ‘textInt...
Definition: guiutil.h:204
PaymentServer::ipcSendCommandLine
static bool ipcSendCommandLine()
Definition: paymentserver.cpp:198
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:671
Config
Definition: config.h:17
BitcoinApplication::m_node
interfaces::Node * m_node
Definition: bitcoin.h:134
util::Ref
Type-safe dynamic reference.
Definition: ref.h:21
OptionsModel
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:49
ClientModel::getOptionsModel
OptionsModel * getOptionsModel()
Definition: clientmodel.cpp:165
PaymentServer
Definition: paymentserver.h:63
BitcoinABC
Class encapsulating Bitcoin ABC startup and shutdown.
Definition: bitcoin.h:36
interfaces::MakeNode
std::unique_ptr< Node > MakeNode(NodeContext *context)
Return implementation of Node interface.
Definition: node.cpp:318
RegisterMetaTypes
static void RegisterMetaTypes()
Definition: bitcoin.cpp:72
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36
BitcoinGUI::unsubscribeFromCoreSignals
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
Definition: bitcoingui.cpp:1578
QAPP_APP_NAME_DEFAULT
#define QAPP_APP_NAME_DEFAULT
Definition: guiconstants.h:47
BitcoinApplication::baseInitialize
bool baseInitialize(Config &config)
Basic initialization, before starting initialization/shutdown thread.
Definition: bitcoin.cpp:301
OptionsModel::SetPruneTargetGB
void SetPruneTargetGB(int prune_target_gb, bool force=false)
Definition: optionsmodel.cpp:300
init.h
BitcoinApplication::createWindow
void createWindow(const Config *, const NetworkStyle *networkStyle)
Create main window.
Definition: bitcoin.cpp:265
BitcoinApplication::requestedInitialize
void requestedInitialize(Config *config, RPCServer *rpcServer, HTTPRPCRequestProcessor *httpRPCRequestProcessor)
ArgsManager::DEBUG_ONLY
@ DEBUG_ONLY
Definition: system.h:160
PaymentServer::receivedPaymentRequest
void receivedPaymentRequest(SendCoinsRecipient)
InitError
bool InitError(const bilingual_str &str)
Show error message.
Definition: ui_interface.cpp:96
BitcoinApplication::InitializePruneSetting
void InitializePruneSetting(bool prune)
Initialize prune setting.
Definition: bitcoin.cpp:354
noui_InitMessage
void noui_InitMessage(const std::string &message)
Non-GUI handler, which only logs a message.
Definition: noui.cpp:55
ArgsManager::AddArg
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:565
util::ThreadRename
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
Definition: threadnames.cpp:48
interfaces::Node::startShutdown
virtual void startShutdown()=0
Start shutdown.
WalletController
Controller between interfaces::Node, WalletModel instances and the GUI.
Definition: walletcontroller.h:48
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:498
BitcoinABC::initialize
void initialize(Config *config, RPCServer *rpcServer, HTTPRPCRequestProcessor *httpRPCRequestProcessor)
Definition: bitcoin.cpp:185
BitcoinApplication::returnValue
int returnValue
Definition: bitcoin.h:130
WalletController::coinsSent
void coinsSent(interfaces::Wallet &wallet, SendCoinsRecipient recipient, QByteArray transaction)
guiutil.h
BCLog::QT
@ QT
Definition: logging.h:57
SelectParams
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
Definition: chainparams.cpp:530
BitcoinApplication::createOptionsModel
void createOptionsModel(bool resetSettings)
Create options model.
Definition: bitcoin.cpp:261
ArgsManager::ParseParameters
NODISCARD bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:317
bilingual_str::translated
std::string translated
Definition: translation.h:19
uint256
256-bit opaque blob.
Definition: uint256.h:127
Amount
Definition: amount.h:19
LogPrint
#define LogPrint(category,...)
Definition: logging.h:193
ArgsManager::ReadConfigFiles
NODISCARD bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:930
BitcoinGUI::detectShutdown
void detectShutdown()
called by a timer to check if ShutdownRequested() has been set
Definition: bitcoingui.cpp:1499
BitcoinApplication::coreThread
QThread * coreThread
Definition: bitcoin.h:121
BitcoinApplication::shutdownWindow
std::unique_ptr< QWidget > shutdownWindow
Definition: bitcoin.h:132
bitcoin.h
BitcoinApplication::requestShutdown
void requestShutdown(Config &config)
Request core shutdown.
Definition: bitcoin.cpp:371
PlatformStyle::instantiate
static const PlatformStyle * instantiate(const QString &platformId)
Get style associated with provided platform name, or 0 if not known.
Definition: platformstyle.cpp:115
GuiMain
int GuiMain(int argc, char *argv[])
Definition: bitcoin.cpp:559
interfaces::Node
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:55
BitcoinApplication::window
BitcoinGUI * window
Definition: bitcoin.h:124
SetupUIArgs
static void SetupUIArgs(ArgsManager &argsman)
Definition: bitcoin.cpp:486
OptionsModel::setNode
void setNode(interfaces::Node &node)
Definition: optionsmodel.h:117
ui_interface.h
platformstyle.h
system.h
m_node
NodeContext & m_node
Definition: chain.cpp:485
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
ClientModel
Model for Bitcoin network client.
Definition: clientmodel.h:36
BitcoinABC::m_node
interfaces::Node & m_node
Definition: bitcoin.h:56
SplashScreen
Class for the splashscreen with information of the running client.
Definition: splashscreen.h:26
BitcoinApplication::BitcoinApplication
BitcoinApplication()
Definition: bitcoin.cpp:217
httprpc.h
guiconstants.h
NetworkStyle::instantiate
static const NetworkStyle * instantiate(const std::string &networkId)
Get style associated with provided BIP70 network id, or 0 if not known.
Definition: networkstyle.cpp:77
ArgsManager
Definition: system.h:152
BitcoinApplication::startThread
void startThread()
Definition: bitcoin.cpp:305
translation.h
splashscreen.h
networkstyle.h
gArgs
ArgsManager gArgs
Definition: system.cpp:75
BitcoinABC::runawayException
void runawayException(const QString &message)
ShutdownWindow::showShutdownWindow
static QWidget * showShutdownWindow(QMainWindow *window)
Definition: utilitydialog.cpp:149
BitcoinApplication::m_splash
SplashScreen * m_splash
Definition: bitcoin.h:133
GUIUtil::LogQtInfo
void LogQtInfo()
Writes to debug.log short info about the used Qt and the host system.
Definition: guiutil.cpp:930
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:508
interfaces::Node::getWarnings
virtual bilingual_str getWarnings()=0
Get warnings.
noui.h
DEFAULT_PRUNE_TARGET_GB
static constexpr int DEFAULT_PRUNE_TARGET_GB
Definition: guiconstants.h:55
BitcoinApplication::initializeResult
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
Definition: bitcoin.cpp:398
bitcoingui.h
BitcoinApplication::getMainWinId
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
Definition: bitcoin.cpp:478
config.h
MigrateSettings
static void MigrateSettings()
Definition: bitcoin.cpp:522
SynchronizationState
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:130
DEFAULT_CHOOSE_DATADIR
static const bool DEFAULT_CHOOSE_DATADIR
Definition: intro.h:12
PaymentServer::handleURIOrFile
void handleURIOrFile(const QString &s)
Definition: paymentserver.cpp:374
BitcoinABC::handleRunawayException
void handleRunawayException(const std::exception *e)
Pass fatal exception message to UI thread.
Definition: bitcoin.cpp:179
optionsmodel.h
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
BitcoinApplication::windowShown
void windowShown(BitcoinGUI *window)
DebugMessageHandler
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
Definition: bitcoin.cpp:167
NodeContext
NodeContext struct containing references to chain state and connection state.
Definition: context.h:36
qt_argv
static const char * qt_argv
Definition: bitcoin.cpp:215
OptionsCategory::GUI
@ GUI
OptionsModel::getMinimizeToTray
bool getMinimizeToTray() const
Definition: optionsmodel.h:95
BitcoinGUI
Bitcoin GUI main class.
Definition: bitcoingui.h:68
threadnames.h
GetConfig
const Config & GetConfig()
Definition: config.cpp:34
BitcoinApplication::parameterSetup
void parameterSetup()
parameter interaction/setup based on rules
Definition: bitcoin.cpp:345
BitcoinApplication
Main Bitcoin application object.
Definition: bitcoin.h:60
BitcoinABC::shutdown
void shutdown()
Definition: bitcoin.cpp:201
BitcoinApplication::shutdownResult
void shutdownResult()
Definition: bitcoin.cpp:463
util::ThreadSetInternalName
void ThreadSetInternalName(std::string &&)
Set the internal (in-memory) name of the current thread only.
Definition: threadnames.cpp:53
LogPrintf
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:175
BitcoinGUI::DEFAULT_UIPLATFORM
static const std::string DEFAULT_UIPLATFORM
Definition: bitcoingui.h:72
clientmodel.h
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:716
Intro::showIfNeeded
static bool showIfNeeded(bool &did_show_intro, bool &prune)
Determine data directory.
Definition: intro.cpp:178
QAPP_ORG_DOMAIN
#define QAPP_ORG_DOMAIN
Definition: guiconstants.h:46
noui_ThreadSafeQuestion
bool noui_ThreadSafeQuestion(const bilingual_str &, const std::string &message, const std::string &caption, unsigned int style)
Non-GUI handler, which logs and prints questions.
Definition: noui.cpp:48
BitcoinApplication::clientModel
ClientModel * clientModel
Definition: bitcoin.h:123
noui_ThreadSafeMessageBox
bool noui_ThreadSafeMessageBox(const bilingual_str &message, const std::string &caption, unsigned int style)
Non-GUI handler, which logs and prints messages.
Definition: noui.cpp:20
paymentserver.h