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