Bitcoin Core  22.99.0
P2P Digital Currency
bitcoin.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 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 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <qt/bitcoin.h>
10 
11 #include <chainparams.h>
12 #include <init.h>
13 #include <interfaces/handler.h>
14 #include <interfaces/init.h>
15 #include <interfaces/node.h>
16 #include <node/ui_interface.h>
17 #include <noui.h>
18 #include <qt/bitcoingui.h>
19 #include <qt/clientmodel.h>
20 #include <qt/guiconstants.h>
21 #include <qt/guiutil.h>
22 #include <qt/initexecutor.h>
23 #include <qt/intro.h>
24 #include <qt/networkstyle.h>
25 #include <qt/optionsmodel.h>
26 #include <qt/platformstyle.h>
27 #include <qt/splashscreen.h>
28 #include <qt/utilitydialog.h>
29 #include <qt/winshutdownmonitor.h>
30 #include <uint256.h>
31 #include <util/string.h>
32 #include <util/system.h>
33 #include <util/threadnames.h>
34 #include <util/translation.h>
35 #include <validation.h>
36 
37 #ifdef ENABLE_WALLET
38 #include <qt/paymentserver.h>
39 #include <qt/walletcontroller.h>
40 #include <qt/walletmodel.h>
41 #endif // ENABLE_WALLET
42 
43 #include <boost/signals2/connection.hpp>
44 #include <chrono>
45 #include <memory>
46 
47 #include <QApplication>
48 #include <QDebug>
49 #include <QLatin1String>
50 #include <QLibraryInfo>
51 #include <QLocale>
52 #include <QMessageBox>
53 #include <QSettings>
54 #include <QThread>
55 #include <QTimer>
56 #include <QTranslator>
57 #include <QWindow>
58 
59 #if defined(QT_STATICPLUGIN)
60 #include <QtPlugin>
61 #if defined(QT_QPA_PLATFORM_XCB)
62 Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
63 #elif defined(QT_QPA_PLATFORM_WINDOWS)
64 Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
65 Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin);
66 #elif defined(QT_QPA_PLATFORM_COCOA)
67 Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
68 Q_IMPORT_PLUGIN(QMacStylePlugin);
69 #elif defined(QT_QPA_PLATFORM_ANDROID)
70 Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
71 #endif
72 #endif
73 
74 // Declare meta types used for QMetaObject::invokeMethod
75 Q_DECLARE_METATYPE(bool*)
76 Q_DECLARE_METATYPE(CAmount)
77 Q_DECLARE_METATYPE(SynchronizationState)
78 Q_DECLARE_METATYPE(uint256)
79 
80 using node::NodeContext;
81 
82 static void RegisterMetaTypes()
83 {
84  // Register meta types used for QMetaObject::invokeMethod and Qt::QueuedConnection
85  qRegisterMetaType<bool*>();
86  qRegisterMetaType<SynchronizationState>();
87  #ifdef ENABLE_WALLET
88  qRegisterMetaType<WalletModel*>();
89  #endif
90  // Register typedefs (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType)
91  // IMPORTANT: if CAmount is no longer a typedef use the normal variant above (see https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType-1)
92  qRegisterMetaType<CAmount>("CAmount");
93  qRegisterMetaType<size_t>("size_t");
94 
95  qRegisterMetaType<std::function<void()>>("std::function<void()>");
96  qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon");
97  qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>("interfaces::BlockAndHeaderTipInfo");
98 }
99 
100 static QString GetLangTerritory()
101 {
102  QSettings settings;
103  // Get desired locale (e.g. "de_DE")
104  // 1) System default language
105  QString lang_territory = QLocale::system().name();
106  // 2) Language from QSettings
107  QString lang_territory_qsettings = settings.value("language", "").toString();
108  if(!lang_territory_qsettings.isEmpty())
109  lang_territory = lang_territory_qsettings;
110  // 3) -lang command line argument
111  lang_territory = QString::fromStdString(gArgs.GetArg("-lang", lang_territory.toStdString()));
112  return lang_territory;
113 }
114 
116 static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
117 {
118  // Remove old translators
119  QApplication::removeTranslator(&qtTranslatorBase);
120  QApplication::removeTranslator(&qtTranslator);
121  QApplication::removeTranslator(&translatorBase);
122  QApplication::removeTranslator(&translator);
123 
124  // Get desired locale (e.g. "de_DE")
125  // 1) System default language
126  QString lang_territory = GetLangTerritory();
127 
128  // Convert to "de" only by truncating "_DE"
129  QString lang = lang_territory;
130  lang.truncate(lang_territory.lastIndexOf('_'));
131 
132  // Load language files for configured locale:
133  // - First load the translator for the base language, without territory
134  // - Then load the more specific locale translator
135 
136  // Load e.g. qt_de.qm
137  if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
138  QApplication::installTranslator(&qtTranslatorBase);
139 
140  // Load e.g. qt_de_DE.qm
141  if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
142  QApplication::installTranslator(&qtTranslator);
143 
144  // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
145  if (translatorBase.load(lang, ":/translations/"))
146  QApplication::installTranslator(&translatorBase);
147 
148  // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
149  if (translator.load(lang_territory, ":/translations/"))
150  QApplication::installTranslator(&translator);
151 }
152 
153 static bool InitSettings()
154 {
155  if (!gArgs.GetSettingsPath()) {
156  return true; // Do nothing if settings file disabled.
157  }
158 
159  std::vector<std::string> errors;
160  if (!gArgs.ReadSettingsFile(&errors)) {
161  std::string error = QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be read");
162  std::string error_translated = QCoreApplication::translate("bitcoin-core", error.c_str()).toStdString();
163  InitError(Untranslated(strprintf("%s:\n%s\n", error, MakeUnorderedList(errors))));
164 
165  QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error_translated)), QMessageBox::Reset | QMessageBox::Abort);
166  /*: Explanatory text shown on startup when the settings file cannot be read.
167  Prompts user to make a choice between resetting or aborting. */
168  messagebox.setInformativeText(QObject::tr("Do you want to reset settings to default values, or to abort without making changes?"));
169  messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(errors)));
170  messagebox.setTextFormat(Qt::PlainText);
171  messagebox.setDefaultButton(QMessageBox::Reset);
172  switch (messagebox.exec()) {
173  case QMessageBox::Reset:
174  break;
175  case QMessageBox::Abort:
176  return false;
177  default:
178  assert(false);
179  }
180  }
181 
182  errors.clear();
183  if (!gArgs.WriteSettingsFile(&errors)) {
184  std::string error = QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be written");
185  std::string error_translated = QCoreApplication::translate("bitcoin-core", error.c_str()).toStdString();
186  InitError(Untranslated(strprintf("%s:\n%s\n", error, MakeUnorderedList(errors))));
187 
188  QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error_translated)), QMessageBox::Ok);
189  /*: Explanatory text shown on startup when the settings file could not be written.
190  Prompts user to check that we have the ability to write to the file.
191  Explains that the user has the option of running without a settings file.*/
192  messagebox.setInformativeText(QObject::tr("A fatal error occurred. Check that settings file is writable, or try running with -nosettings."));
193  messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(errors)));
194  messagebox.setTextFormat(Qt::PlainText);
195  messagebox.setDefaultButton(QMessageBox::Ok);
196  messagebox.exec();
197  return false;
198  }
199  return true;
200 }
201 
202 /* qDebug() message handler --> debug.log */
203 void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg)
204 {
205  Q_UNUSED(context);
206  if (type == QtDebugMsg) {
207  LogPrint(BCLog::QT, "GUI: %s\n", msg.toStdString());
208  } else {
209  LogPrintf("GUI: %s\n", msg.toStdString());
210  }
211 }
212 
213 static int qt_argc = 1;
214 static const char* qt_argv = "bitcoin-qt";
215 
217  QApplication(qt_argc, const_cast<char **>(&qt_argv)),
218  optionsModel(nullptr),
219  clientModel(nullptr),
220  window(nullptr),
221  pollShutdownTimer(nullptr),
222  returnValue(0),
223  platformStyle(nullptr)
224 {
225  // Qt runs setlocale(LC_ALL, "") on initialization.
227  setQuitOnLastWindowClosed(false);
228 }
229 
231 {
232  // UI per-platform customization
233  // This must be done inside the BitcoinApplication constructor, or after it, because
234  // PlatformStyle::instantiate requires a QApplication
235  std::string platformName;
236  platformName = gArgs.GetArg("-uiplatform", BitcoinGUI::DEFAULT_UIPLATFORM);
237  platformStyle = PlatformStyle::instantiate(QString::fromStdString(platformName));
238  if (!platformStyle) // Fall back to "other" if specified name not found
241 }
242 
244 {
245  m_executor.reset();
246 
247  delete window;
248  window = nullptr;
249  delete platformStyle;
250  platformStyle = nullptr;
251 }
252 
253 #ifdef ENABLE_WALLET
254 void BitcoinApplication::createPaymentServer()
255 {
256  paymentServer = new PaymentServer(this);
257 }
258 #endif
259 
261 {
262  optionsModel = new OptionsModel(this, resetSettings);
263 }
264 
266 {
267  window = new BitcoinGUI(node(), platformStyle, networkStyle, nullptr);
269 
270  pollShutdownTimer = new QTimer(window);
271  connect(pollShutdownTimer, &QTimer::timeout, [this]{
272  if (!QApplication::activeModalWidget()) {
274  }
275  });
276 }
277 
279 {
280  assert(!m_splash);
281  m_splash = new SplashScreen(networkStyle);
282  // We don't hold a direct pointer to the splash screen after creation, but the splash
283  // screen will take care of deleting itself when finish() happens.
284  m_splash->show();
286  connect(this, &BitcoinApplication::requestedShutdown, m_splash, &QWidget::close);
287 }
288 
290 {
291  assert(!m_node);
292  m_node = init.makeNode();
295 }
296 
298 {
299  return node().baseInitialize();
300 }
301 
303 {
304  assert(!m_executor);
305  m_executor.emplace(node());
306 
307  /* communication to and from thread */
309  connect(&m_executor.value(), &InitExecutor::shutdownResult, this, &QCoreApplication::quit);
313 }
314 
316 {
317  // Default printtoconsole to false for the GUI. GUI programs should not
318  // print to the console unnecessarily.
319  gArgs.SoftSetBoolArg("-printtoconsole", false);
320 
323 }
324 
326 {
327  optionsModel->SetPruneTargetGB(PruneMiBtoGB(prune_MiB), true);
328 }
329 
331 {
332  qDebug() << __func__ << ": Requesting initialize";
333  startThread();
334  Q_EMIT requestedInitialize();
335 }
336 
338 {
339  for (const auto w : QGuiApplication::topLevelWindows()) {
340  w->hide();
341  }
342 
343  // Show a simple window indicating shutdown status
344  // Do this first as some of the steps may take some time below,
345  // for example the RPC console may still be executing a command.
347 
348  qDebug() << __func__ << ": Requesting shutdown";
349 
350  // Must disconnect node signals otherwise current thread can deadlock since
351  // no event loop is running.
353  // Request node shutdown, which can interrupt long operations, like
354  // rescanning a wallet.
355  node().startShutdown();
356  // Unsetting the client model can cause the current thread to wait for node
357  // to complete an operation, like wait for a RPC execution to complete.
358  window->setClientModel(nullptr);
359  pollShutdownTimer->stop();
360 
361 #ifdef ENABLE_WALLET
362  // Delete wallet controller here manually, instead of relying on Qt object
363  // tracking (https://doc.qt.io/qt-5/objecttrees.html). This makes sure
364  // walletmodel m_handle_* notification handlers are deleted before wallets
365  // are unloaded, which can simplify wallet implementations. It also avoids
366  // these notifications having to be handled while GUI objects are being
367  // destroyed, making GUI code less fragile as well.
368  delete m_wallet_controller;
369  m_wallet_controller = nullptr;
370 #endif // ENABLE_WALLET
371 
372  delete clientModel;
373  clientModel = nullptr;
374 
375  // Request shutdown from core thread
376  Q_EMIT requestedShutdown();
377 }
378 
380 {
381  qDebug() << __func__ << ": Initialization result: " << success;
382  // Set exit result.
383  returnValue = success ? EXIT_SUCCESS : EXIT_FAILURE;
384  if(success)
385  {
386  // Log this only after AppInitMain finishes, as then logging setup is guaranteed complete
387  qInfo() << "Platform customization:" << platformStyle->getName();
389  window->setClientModel(clientModel, &tip_info);
390 #ifdef ENABLE_WALLET
392  m_wallet_controller = new WalletController(*clientModel, platformStyle, this);
393  window->setWalletController(m_wallet_controller);
394  if (paymentServer) {
395  paymentServer->setOptionsModel(optionsModel);
396  }
397  }
398 #endif // ENABLE_WALLET
399 
400  // If -min option passed, start window minimized (iconified) or minimized to tray
401  if (!gArgs.GetBoolArg("-min", false)) {
402  window->show();
404  // do nothing as the window is managed by the tray icon
405  } else {
406  window->showMinimized();
407  }
408  Q_EMIT splashFinished();
409  Q_EMIT windowShown(window);
410 
411 #ifdef ENABLE_WALLET
412  // Now that initialization/startup is done, process any command-line
413  // bitcoin: URIs or payment requests:
414  if (paymentServer) {
415  connect(paymentServer, &PaymentServer::receivedPaymentRequest, window, &BitcoinGUI::handlePaymentRequest);
417  connect(paymentServer, &PaymentServer::message, [this](const QString& title, const QString& message, unsigned int style) {
418  window->message(title, message, style);
419  });
420  QTimer::singleShot(100ms, paymentServer, &PaymentServer::uiReady);
421  }
422 #endif
424  } else {
425  Q_EMIT splashFinished(); // Make sure splash screen doesn't stick around during shutdown
426  requestShutdown();
427  }
428 }
429 
430 void BitcoinApplication::handleRunawayException(const QString &message)
431 {
432  QMessageBox::critical(
433  nullptr, tr("Runaway exception"),
434  tr("A fatal error occurred. %1 can no longer continue safely and will quit.").arg(PACKAGE_NAME) +
435  QLatin1String("<br><br>") + GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
436  ::exit(EXIT_FAILURE);
437 }
438 
440 {
441  assert(QThread::currentThread() == thread());
442  QMessageBox::warning(
443  nullptr, tr("Internal error"),
444  tr("An internal error occurred. %1 will attempt to continue safely. This is "
445  "an unexpected bug which can be reported as described below.").arg(PACKAGE_NAME) +
446  QLatin1String("<br><br>") + GUIUtil::MakeHtmlLink(message, PACKAGE_BUGREPORT));
447 }
448 
450 {
451  if (!window)
452  return 0;
453 
454  return window->winId();
455 }
456 
457 static void SetupUIArgs(ArgsManager& argsman)
458 {
459  argsman.AddArg("-choosedatadir", strprintf("Choose data directory on startup (default: %u)", DEFAULT_CHOOSE_DATADIR), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
460  argsman.AddArg("-lang=<lang>", "Set language, for example \"de_DE\" (default: system locale)", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
461  argsman.AddArg("-min", "Start minimized", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
462  argsman.AddArg("-resetguisettings", "Reset all settings changed in the GUI", ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
463  argsman.AddArg("-splash", strprintf("Show splash screen on startup (default: %u)", DEFAULT_SPLASHSCREEN), ArgsManager::ALLOW_ANY, OptionsCategory::GUI);
464  argsman.AddArg("-uiplatform", strprintf("Select platform to customize UI for (one of windows, macosx, other; default: %s)", BitcoinGUI::DEFAULT_UIPLATFORM), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::GUI);
465 }
466 
467 int GuiMain(int argc, char* argv[])
468 {
469 #ifdef WIN32
470  util::WinCmdLineArgs winArgs;
471  std::tie(argc, argv) = winArgs.get();
472 #endif
473 
474  std::unique_ptr<interfaces::Init> init = interfaces::MakeGuiInit(argc, argv);
475 
478 
479  // Subscribe to global signals from core
480  boost::signals2::scoped_connection handler_message_box = ::uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBox);
481  boost::signals2::scoped_connection handler_question = ::uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestion);
482  boost::signals2::scoped_connection handler_init_message = ::uiInterface.InitMessage_connect(noui_InitMessage);
483 
484  // Do not refer to data directory yet, this can be overridden by Intro::pickDataDirectory
485 
487  Q_INIT_RESOURCE(bitcoin);
488  Q_INIT_RESOURCE(bitcoin_locale);
489 
490  // Generate high-dpi pixmaps
491  QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
492  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
493 
494 #if defined(QT_QPA_PLATFORM_ANDROID)
495  QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
496  QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
497  QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
498 #endif
499 
500  BitcoinApplication app;
501  GUIUtil::LoadFont(QStringLiteral(":/fonts/monospace"));
502 
504  // Command-line options take precedence:
507  std::string error;
508  if (!gArgs.ParseParameters(argc, argv, error)) {
509  InitError(strprintf(Untranslated("Error parsing command line arguments: %s\n"), error));
510  // Create a message box, because the gui has neither been created nor has subscribed to core signals
511  QMessageBox::critical(nullptr, PACKAGE_NAME,
512  // message can not be translated because translations have not been initialized
513  QString::fromStdString("Error parsing command line arguments: %1.").arg(QString::fromStdString(error)));
514  return EXIT_FAILURE;
515  }
516 
517  // Now that the QApplication is setup and we have parsed our parameters, we can set the platform style
518  app.setupPlatformStyle();
519 
521  // must be set before OptionsModel is initialized or translations are loaded,
522  // as it is used to locate QSettings
523  QApplication::setOrganizationName(QAPP_ORG_NAME);
524  QApplication::setOrganizationDomain(QAPP_ORG_DOMAIN);
525  QApplication::setApplicationName(QAPP_APP_NAME_DEFAULT);
526 
528  // Now that QSettings are accessible, initialize translations
529  QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
530  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
531 
532  // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
533  // but before showing splash screen.
534  if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
535  HelpMessageDialog help(nullptr, gArgs.IsArgSet("-version"));
536  help.showOrPrint();
537  return EXIT_SUCCESS;
538  }
539 
540  // Install global event filter that makes sure that long tooltips can be word-wrapped
541  app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
542 
544  // User language is set up: pick a data directory
545  bool did_show_intro = false;
546  int64_t prune_MiB = 0; // Intro dialog prune configuration
547  // Gracefully exit if the user cancels
548  if (!Intro::showIfNeeded(did_show_intro, prune_MiB)) return EXIT_SUCCESS;
549 
552  if (!CheckDataDirOption()) {
553  InitError(strprintf(Untranslated("Specified data directory \"%s\" does not exist.\n"), gArgs.GetArg("-datadir", "")));
554  QMessageBox::critical(nullptr, PACKAGE_NAME,
555  QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
556  return EXIT_FAILURE;
557  }
558  if (!gArgs.ReadConfigFiles(error, true)) {
559  InitError(strprintf(Untranslated("Error reading configuration file: %s\n"), error));
560  QMessageBox::critical(nullptr, PACKAGE_NAME,
561  QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error)));
562  return EXIT_FAILURE;
563  }
564 
566  // - Do not call Params() before this step
567  // - Do this after parsing the configuration file, as the network can be switched there
568  // - QSettings() will use the new application name after this, resulting in network-specific settings
569  // - Needs to be done before createOptionsModel
570 
571  // Check for chain settings (Params() calls are only valid after this clause)
572  try {
574  } catch(std::exception &e) {
575  InitError(Untranslated(strprintf("%s\n", e.what())));
576  QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: %1").arg(e.what()));
577  return EXIT_FAILURE;
578  }
579 #ifdef ENABLE_WALLET
580  // Parse URIs on command line -- this can affect Params()
582 #endif
583 
584  if (!InitSettings()) {
585  return EXIT_FAILURE;
586  }
587 
588  QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(Params().NetworkIDString()));
589  assert(!networkStyle.isNull());
590  // Allow for separate UI settings for testnets
591  QApplication::setApplicationName(networkStyle->getAppName());
592  // Re-initialize translations after changing application name (language in network-specific settings can be different)
593  initTranslations(qtTranslatorBase, qtTranslator, translatorBase, translator);
594 
595 #ifdef ENABLE_WALLET
596  // - Do this early as we don't want to bother initializing if we are just calling IPC
598  // - Do this *after* setting up the data directory, as the data directory hash is used in the name
599  // of the server.
600  // - Do this after creating app and setting up translations, so errors are
601  // translated properly.
603  exit(EXIT_SUCCESS);
604 
605  // Start up the payment server early, too, so impatient users that click on
606  // bitcoin: links repeatedly have their payment requests routed to this process:
608  app.createPaymentServer();
609  }
610 #endif // ENABLE_WALLET
611 
613  // Install global event filter that makes sure that out-of-focus labels do not contain text cursor.
614  app.installEventFilter(new GUIUtil::LabelOutOfFocusEventFilter(&app));
615 #if defined(Q_OS_WIN)
616  // Install global event filter for processing Windows session related Windows messages (WM_QUERYENDSESSION and WM_ENDSESSION)
617  qApp->installNativeEventFilter(new WinShutdownMonitor());
618 #endif
619  // Install qDebug() message handler to route to debug.log
620  qInstallMessageHandler(DebugMessageHandler);
621  // Allow parameter interaction before we create the options model
622  app.parameterSetup();
624  // Load GUI settings from QSettings
625  app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
626 
627  if (did_show_intro) {
628  // Store intro dialog settings other than datadir (network specific)
629  app.InitPruneSetting(prune_MiB);
630  }
631 
632  if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false))
633  app.createSplashScreen(networkStyle.data());
634 
635  app.createNode(*init);
636 
637  int rv = EXIT_SUCCESS;
638  try
639  {
640  app.createWindow(networkStyle.data());
641  // Perform base initialization before spinning up initialization/shutdown thread
642  // This is acceptable because this function only contains steps that are quick to execute,
643  // so the GUI thread won't be held up.
644  if (app.baseInitialize()) {
645  app.requestInitialize();
646 #if defined(Q_OS_WIN)
647  WinShutdownMonitor::registerShutdownBlockReason(QObject::tr("%1 didn't yet exit safely…").arg(PACKAGE_NAME), (HWND)app.getMainWinId());
648 #endif
649  app.exec();
650  rv = app.getReturnValue();
651  } else {
652  // A dialog with detailed error will have been shown by InitError()
653  rv = EXIT_FAILURE;
654  }
655  } catch (const std::exception& e) {
656  PrintExceptionContinue(&e, "Runaway exception");
657  app.handleRunawayException(QString::fromStdString(app.node().getWarnings().translated));
658  } catch (...) {
659  PrintExceptionContinue(nullptr, "Runaway exception");
660  app.handleRunawayException(QString::fromStdString(app.node().getWarnings().translated));
661  }
662  return rv;
663 }
PruneMiBtoGB
static int PruneMiBtoGB(int64_t mib)
Convert configured prune target MiB to displayed GB.
Definition: optionsmodel.h:25
winshutdownmonitor.h
BitcoinGUI::setClientModel
void setClientModel(ClientModel *clientModel=nullptr, interfaces::BlockAndHeaderTipInfo *tip_info=nullptr)
Set the client model.
Definition: bitcoingui.cpp:565
SetupUIArgs
static void SetupUIArgs(ArgsManager &argsman)
Definition: bitcoin.cpp:457
GUIUtil::ToolTipToRichTextFilter
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
Definition: guiutil.h:179
BitcoinApplication::setupPlatformStyle
void setupPlatformStyle()
Setup platform style.
Definition: bitcoin.cpp:230
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:600
BitcoinApplication::createSplashScreen
void createSplashScreen(const NetworkStyle *networkStyle)
Create splash screen.
Definition: bitcoin.cpp:278
DEFAULT_SPLASHSCREEN
static const bool DEFAULT_SPLASHSCREEN
Definition: guiconstants.h:25
SplashScreen::setNode
void setNode(interfaces::Node &node)
Definition: splashscreen.cpp:140
assert
assert(!tx.IsCoinBase())
BitcoinApplication::splashFinished
void splashFinished()
QAPP_ORG_NAME
#define QAPP_ORG_NAME
Definition: guiconstants.h:49
BitcoinApplication::platformStyle
const PlatformStyle * platformStyle
Definition: bitcoin.h:106
BitcoinApplication::node
interfaces::Node & node() const
Definition: bitcoin.h:74
BitcoinApplication::~BitcoinApplication
~BitcoinApplication()
Definition: bitcoin.cpp:243
InitExecutor::shutdown
void shutdown()
Definition: initexecutor.cpp:57
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.
PACKAGE_BUGREPORT
#define PACKAGE_BUGREPORT
Definition: bitcoin-config.h:351
InitParameterInteraction
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:659
BitcoinApplication::handleRunawayException
void handleRunawayException(const QString &message)
Handle runaway exceptions. Shows a message box with the problem and quits the program.
Definition: bitcoin.cpp:430
BitcoinApplication::pollShutdownTimer
QTimer * pollShutdownTimer
Definition: bitcoin.h:100
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:614
uiInterface
CClientUIInterface uiInterface
Definition: ui_interface.cpp:12
InitLogging
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:737
help
static RPCHelpMan help()
Definition: server.cpp:133
BitcoinApplication::m_executor
std::optional< InitExecutor > m_executor
Definition: bitcoin.h:96
walletcontroller.h
intro.h
initTranslations
static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTranslator, QTranslator &translatorBase, QTranslator &translator)
Set up translations.
Definition: bitcoin.cpp:116
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:164
string.h
utilitydialog.h
WalletModel::isWalletEnabled
static bool isWalletEnabled()
Definition: walletmodel.cpp:572
uint256.h
ArgsManager::ALLOW_ANY
@ ALLOW_ANY
disable validation
Definition: system.h:172
ArgsManager::GetChainName
std::string GetChainName() const
Returns the appropriate chain name from the program arguments.
Definition: system.cpp:987
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:494
node::NodeContext
NodeContext struct containing references to chain state and connection state.
Definition: context.h:40
interfaces::Init
Initial interface created when a process is first started, and used to give and get access to other i...
Definition: init.h:28
handler.h
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1301
Intro::showIfNeeded
static bool showIfNeeded(bool &did_show_intro, int64_t &prune_MiB)
Determine data directory.
Definition: intro.cpp:205
BitcoinApplication::optionsModel
OptionsModel * optionsModel
Definition: bitcoin.h:97
InitExecutor::runawayException
void runawayException(const QString &message)
NetworkStyle
Definition: networkstyle.h:13
BitcoinApplication::requestedInitialize
void requestedInitialize()
interfaces::BlockAndHeaderTipInfo
Block and header tip information.
Definition: node.h:48
PlatformStyle::getName
const QString & getName() const
Definition: platformstyle.h:19
PaymentServer::ipcParseCommandLine
static void ipcParseCommandLine(int argc, char *argv[])
Definition: paymentserver.cpp:76
BitcoinApplication::getReturnValue
int getReturnValue() const
Get process return value.
Definition: bitcoin.h:66
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:737
bitcoin.h
bitcoin-config.h
chainparams.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:1122
interfaces::MakeGuiInit
std::unique_ptr< Init > MakeGuiInit(int argc, char *argv[])
Return implementation of Init interface for the gui process.
Definition: bitcoin-gui.cpp:43
ArgsManager::DEBUG_ONLY
@ DEBUG_ONLY
Definition: system.h:179
qt_argv
static const char * qt_argv
Definition: bitcoin.cpp:214
BitcoinGUI::hasTrayIcon
bool hasTrayIcon() const
Get the tray icon status.
Definition: bitcoingui.h:101
PaymentServer::uiReady
void uiReady()
Definition: paymentserver.cpp:204
BitcoinApplication::requestedShutdown
void requestedShutdown()
InitExecutor::shutdownResult
void shutdownResult()
MakeUnorderedList
std::string MakeUnorderedList(const std::vector< std::string > &items)
Create an unordered multi-line list of items.
Definition: string.h:70
TOOLTIP_WRAP_THRESHOLD
static const int TOOLTIP_WRAP_THRESHOLD
Definition: guiconstants.h:44
GUIUtil::LabelOutOfFocusEventFilter
Qt event filter that intercepts QEvent::FocusOut events for QLabel objects, and resets their ‘textInt...
Definition: guiutil.h:199
PaymentServer::ipcSendCommandLine
static bool ipcSendCommandLine()
Definition: paymentserver.cpp:117
OptionsModel
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:38
ClientModel::getOptionsModel
OptionsModel * getOptionsModel()
Definition: clientmodel.cpp:183
DebugMessageHandler
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
Definition: bitcoin.cpp:203
PaymentServer
Definition: paymentserver.h:57
GetLangTerritory
static QString GetLangTerritory()
Definition: bitcoin.cpp:100
ArgsManager::GetSettingsPath
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false) const
Get settings file path, or return false if read-write settings were disabled with -nosettings.
Definition: system.cpp:517
BitcoinApplication::createWindow
void createWindow(const NetworkStyle *networkStyle)
Create main window.
Definition: bitcoin.cpp:265
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:46
BitcoinGUI::unsubscribeFromCoreSignals
void unsubscribeFromCoreSignals()
Disconnect core signals from GUI client.
Definition: bitcoingui.cpp:1477
QAPP_APP_NAME_DEFAULT
#define QAPP_APP_NAME_DEFAULT
Definition: guiconstants.h:51
GuiMain
int GuiMain(int argc, char *argv[])
Definition: bitcoin.cpp:467
PACKAGE_NAME
#define PACKAGE_NAME
Definition: bitcoin-config.h:354
OptionsModel::SetPruneTargetGB
void SetPruneTargetGB(int prune_target_gb, bool force=false)
Definition: optionsmodel.cpp:295
InitSettings
static bool InitSettings()
Definition: bitcoin.cpp:153
PaymentServer::receivedPaymentRequest
void receivedPaymentRequest(SendCoinsRecipient)
node.h
InitError
bool InitError(const bilingual_str &str)
Show error message.
Definition: ui_interface.cpp:59
noui_InitMessage
void noui_InitMessage(const std::string &message)
Non-GUI handler, which only logs a message.
Definition: noui.cpp:54
ArgsManager::AddArg
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:640
ArgsManager::WriteSettingsFile
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr) const
Write settings file.
Definition: system.cpp:563
interfaces::Node::startShutdown
virtual void startShutdown()=0
Start shutdown.
BitcoinApplication::requestInitialize
void requestInitialize()
Request core initialization.
Definition: bitcoin.cpp:330
WalletController
Controller between interfaces::Node, WalletModel instances and the GUI.
Definition: walletcontroller.h:45
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:588
LogPrintf
#define LogPrintf(...)
Definition: logging.h:188
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
init.h
context
WalletContext context
Definition: notifications.cpp:37
BitcoinApplication::returnValue
int returnValue
Definition: bitcoin.h:105
BitcoinApplication::createNode
void createNode(interfaces::Init &init)
Create or spawn node.
Definition: bitcoin.cpp:289
guiutil.h
BCLog::QT
@ QT
Definition: logging.h:58
SelectParams
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given chain name.
Definition: chainparams.cpp:580
BitcoinApplication::createOptionsModel
void createOptionsModel(bool resetSettings)
Create options model.
Definition: bitcoin.cpp:260
bilingual_str::translated
std::string translated
Definition: translation.h:18
ArgsManager::ParseParameters
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:297
uint256
256-bit opaque blob.
Definition: uint256.h:126
LogPrint
#define LogPrint(category,...)
Definition: logging.h:192
ArgsManager::ReadConfigFiles
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:895
SHUTDOWN_POLLING_DELAY
static constexpr auto SHUTDOWN_POLLING_DELAY
Definition: guiconstants.h:17
BitcoinGUI::detectShutdown
void detectShutdown()
called by a timer to check if ShutdownRequested() has been set
Definition: bitcoingui.cpp:1410
BitcoinApplication::shutdownWindow
std::unique_ptr< QWidget > shutdownWindow
Definition: bitcoin.h:107
gArgs
ArgsManager gArgs
Definition: system.cpp:87
InitExecutor::initialize
void initialize()
Definition: initexecutor.cpp:40
PlatformStyle::instantiate
static const PlatformStyle * instantiate(const QString &platformId)
Get style associated with provided platform name, or 0 if not known.
Definition: platformstyle.cpp:124
GUIUtil::MakeHtmlLink
QString MakeHtmlLink(const QString &source, const QString &link)
Replaces a plain text link with an HTML tagged one.
Definition: guiutil.cpp:969
BitcoinApplication::window
BitcoinGUI * window
Definition: bitcoin.h:99
OptionsModel::setNode
void setNode(interfaces::Node &node)
Definition: optionsmodel.h:106
ui_interface.h
platformstyle.h
ArgsManager::ReadSettingsFile
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: system.cpp:540
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:811
system.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
ClientModel
Model for Bitcoin network client.
Definition: clientmodel.h:47
SplashScreen
Class for the splashscreen with information of the running client.
Definition: splashscreen.h:26
qt_argc
static int qt_argc
Definition: bitcoin.cpp:213
BitcoinApplication::BitcoinApplication
BitcoinApplication()
Definition: bitcoin.cpp:216
guiconstants.h
NetworkStyle::instantiate
static const NetworkStyle * instantiate(const std::string &networkId)
Get style associated with provided network id, or 0 if not known.
Definition: networkstyle.cpp:80
ArgsManager
Definition: system.h:164
BitcoinApplication::startThread
void startThread()
Definition: bitcoin.cpp:302
translation.h
splashscreen.h
networkstyle.h
BitcoinApplication::requestShutdown
void requestShutdown()
Request core shutdown.
Definition: bitcoin.cpp:337
ShutdownWindow::showShutdownWindow
static QWidget * showShutdownWindow(QMainWindow *window)
Definition: utilitydialog.cpp:152
init
Definition: bitcoin-gui.cpp:16
BitcoinApplication::m_splash
SplashScreen * m_splash
Definition: bitcoin.h:108
GUIUtil::LogQtInfo
void LogQtInfo()
Writes to debug.log short info about the used Qt and the host system.
Definition: guiutil.cpp:898
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:561
initexecutor.h
interfaces::Node::getWarnings
virtual bilingual_str getWarnings()=0
Get warnings.
BitcoinGUI::quitRequested
void quitRequested()
BitcoinApplication::baseInitialize
bool baseInitialize()
Basic initialization, before starting initialization/shutdown thread. Return true on success.
Definition: bitcoin.cpp:297
noui.h
BitcoinApplication::initializeResult
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
Definition: bitcoin.cpp:379
bitcoingui.h
BitcoinApplication::getMainWinId
WId getMainWinId() const
Get window identifier of QMainWindow (BitcoinGUI)
Definition: bitcoin.cpp:449
SynchronizationState
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:105
BitcoinApplication::handleNonFatalException
void handleNonFatalException(const QString &message)
A helper function that shows a message box with details about a non-fatal exception.
Definition: bitcoin.cpp:439
DEFAULT_CHOOSE_DATADIR
static const bool DEFAULT_CHOOSE_DATADIR
Definition: intro.h:12
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:779
PaymentServer::handleURIOrFile
void handleURIOrFile(const QString &s)
Definition: paymentserver.cpp:214
InitExecutor::initializeResult
void initializeResult(bool success, interfaces::BlockAndHeaderTipInfo tip_info)
optionsmodel.h
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
RegisterMetaTypes
static void RegisterMetaTypes()
Definition: bitcoin.cpp:82
BitcoinApplication::windowShown
void windowShown(BitcoinGUI *window)
BitcoinApplication::InitPruneSetting
void InitPruneSetting(int64_t prune_MiB)
Initialize prune setting.
Definition: bitcoin.cpp:325
GUIUtil::LoadFont
void LoadFont(const QString &file_name)
Loads the font from the file specified by file_name, aborts if it fails.
Definition: guiutil.cpp:281
OptionsCategory::GUI
@ GUI
OptionsModel::getMinimizeToTray
bool getMinimizeToTray() const
Definition: optionsmodel.h:87
BitcoinGUI
Bitcoin GUI main class.
Definition: bitcoingui.h:68
threadnames.h
BitcoinApplication::m_node
std::unique_ptr< interfaces::Node > m_node
Definition: bitcoin.h:109
BitcoinApplication::parameterSetup
void parameterSetup()
parameter interaction/setup based on rules
Definition: bitcoin.cpp:315
BitcoinApplication
Main Bitcoin application object.
Definition: bitcoin.h:36
SetupServerArgs
void SetupServerArgs(ArgsManager &argsman)
Register all arguments with the ArgsManager.
Definition: init.cpp:374
util::ThreadSetInternalName
void ThreadSetInternalName(std::string &&)
Set the internal (in-memory) name of the current thread only.
Definition: threadnames.cpp:63
BitcoinGUI::DEFAULT_UIPLATFORM
static const std::string DEFAULT_UIPLATFORM
Definition: bitcoingui.h:73
interfaces::Node::baseInitialize
virtual bool baseInitialize()=0
Initialize app dependencies.
clientmodel.h
QAPP_ORG_DOMAIN
#define QAPP_ORG_DOMAIN
Definition: guiconstants.h:50
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:49
BitcoinApplication::clientModel
ClientModel * clientModel
Definition: bitcoin.h:98
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:22
paymentserver.h