aboutsummaryrefslogtreecommitdiff
path: root/src/qt/bitcoin.cpp
diff options
context:
space:
mode:
authorRyan Ofsky <ryan@ofsky.org>2023-02-23 15:56:15 -0500
committerRyan Ofsky <ryan@ofsky.org>2023-02-28 12:04:47 -0500
commit802cc1ef536e11944608fe9ab782d3e962037703 (patch)
tree19008ea3dfb639d73a0d5fbb91c2f793aea8bb8f /src/qt/bitcoin.cpp
parentd172b5c6718b69200c8ad211fe709860081bd692 (diff)
Deduplicate bitcoind and bitcoin-qt init code
Add common InitConfig function to deduplicate bitcoind and bitcoin-qt code reading config files and creating the datadir. There are a few minor changes in behavior: - In bitcoin-qt, when there is a problem reading the configuration file, the GUI error text has changed from "Error: Cannot parse configuration file:" to "Error reading configuration file:" to be consistent with bitcoind. - In bitcoind, when there is a problem reading the settings.json file, the error text has changed from "Failed loading settings file" to "Settings file could not be read" to be consistent with bitcoin-qt. - In bitcoind, when there is a problem writing the settings.json file, the error text has changed from "Failed saving settings file" to "Settings file could not be written" to be consistent with bitcoin-qt. - In bitcoin-qt, if there datadir is not accessible (e.g. no permission to read), there is an normal error dialog showing "Error: filesystem error: status: Permission denied [.../settings.json]", instead of an uncaught exception
Diffstat (limited to 'src/qt/bitcoin.cpp')
-rw-r--r--src/qt/bitcoin.cpp120
1 files changed, 44 insertions, 76 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 440f475757..5244b72689 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -9,6 +9,7 @@
#include <qt/bitcoin.h>
#include <chainparams.h>
+#include <common/init.h>
#include <init.h>
#include <interfaces/handler.h>
#include <interfaces/init.h>
@@ -165,54 +166,36 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans
}
}
-static bool InitSettings()
+static bool ErrorSettingsRead(const bilingual_str& error, const std::vector<std::string>& details)
{
- gArgs.EnsureDataDir();
- if (!gArgs.GetSettingsPath()) {
- return true; // Do nothing if settings file disabled.
- }
-
- std::vector<std::string> errors;
- if (!gArgs.ReadSettingsFile(&errors)) {
- std::string error = QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be read");
- std::string error_translated = QCoreApplication::translate("bitcoin-core", error.c_str()).toStdString();
- InitError(Untranslated(strprintf("%s:\n%s", error, MakeUnorderedList(errors))));
-
- QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error_translated)), QMessageBox::Reset | QMessageBox::Abort);
- /*: Explanatory text shown on startup when the settings file cannot be read.
- Prompts user to make a choice between resetting or aborting. */
- messagebox.setInformativeText(QObject::tr("Do you want to reset settings to default values, or to abort without making changes?"));
- messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(errors)));
- messagebox.setTextFormat(Qt::PlainText);
- messagebox.setDefaultButton(QMessageBox::Reset);
- switch (messagebox.exec()) {
- case QMessageBox::Reset:
- break;
- case QMessageBox::Abort:
- return false;
- default:
- assert(false);
- }
- }
-
- errors.clear();
- if (!gArgs.WriteSettingsFile(&errors)) {
- std::string error = QT_TRANSLATE_NOOP("bitcoin-core", "Settings file could not be written");
- std::string error_translated = QCoreApplication::translate("bitcoin-core", error.c_str()).toStdString();
- InitError(Untranslated(strprintf("%s:\n%s", error, MakeUnorderedList(errors))));
-
- QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error_translated)), QMessageBox::Ok);
- /*: Explanatory text shown on startup when the settings file could not be written.
- Prompts user to check that we have the ability to write to the file.
- Explains that the user has the option of running without a settings file.*/
- messagebox.setInformativeText(QObject::tr("A fatal error occurred. Check that settings file is writable, or try running with -nosettings."));
- messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(errors)));
- messagebox.setTextFormat(Qt::PlainText);
- messagebox.setDefaultButton(QMessageBox::Ok);
- messagebox.exec();
+ QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error.translated)), QMessageBox::Reset | QMessageBox::Abort);
+ /*: Explanatory text shown on startup when the settings file cannot be read.
+ Prompts user to make a choice between resetting or aborting. */
+ messagebox.setInformativeText(QObject::tr("Do you want to reset settings to default values, or to abort without making changes?"));
+ messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(details)));
+ messagebox.setTextFormat(Qt::PlainText);
+ messagebox.setDefaultButton(QMessageBox::Reset);
+ switch (messagebox.exec()) {
+ case QMessageBox::Reset:
return false;
+ case QMessageBox::Abort:
+ return true;
+ default:
+ assert(false);
}
- return true;
+}
+
+static void ErrorSettingsWrite(const bilingual_str& error, const std::vector<std::string>& details)
+{
+ QMessageBox messagebox(QMessageBox::Critical, PACKAGE_NAME, QString::fromStdString(strprintf("%s.", error.translated)), QMessageBox::Ok);
+ /*: Explanatory text shown on startup when the settings file could not be written.
+ Prompts user to check that we have the ability to write to the file.
+ Explains that the user has the option of running without a settings file.*/
+ messagebox.setInformativeText(QObject::tr("A fatal error occurred. Check that settings file is writable, or try running with -nosettings."));
+ messagebox.setDetailedText(QString::fromStdString(MakeUnorderedList(details)));
+ messagebox.setTextFormat(Qt::PlainText);
+ messagebox.setDefaultButton(QMessageBox::Ok);
+ messagebox.exec();
}
/* qDebug() message handler --> debug.log */
@@ -587,34 +570,23 @@ int GuiMain(int argc, char* argv[])
// Gracefully exit if the user cancels
if (!Intro::showIfNeeded(did_show_intro, prune_MiB)) return EXIT_SUCCESS;
- /// 6a. Determine availability of data directory
- if (!CheckDataDirOption(gArgs)) {
- InitError(strprintf(Untranslated("Specified data directory \"%s\" does not exist."), gArgs.GetArg("-datadir", "")));
- QMessageBox::critical(nullptr, PACKAGE_NAME,
- QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
- return EXIT_FAILURE;
- }
- try {
- /// 6b. Parse bitcoin.conf
- /// - Do not call gArgs.GetDataDirNet() before this step finishes
- if (!gArgs.ReadConfigFiles(error, true)) {
- InitError(strprintf(Untranslated("Error reading configuration file: %s"), error));
- QMessageBox::critical(nullptr, PACKAGE_NAME,
- QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error)));
- return EXIT_FAILURE;
+ /// 6-7. Parse bitcoin.conf, determine network, switch to network specific
+ /// options, and create datadir and settings.json.
+ // - Do not call gArgs.GetDataDirNet() before this step finishes
+ // - Do not call Params() before this step
+ // - QSettings() will use the new application name after this, resulting in network-specific settings
+ // - Needs to be done before createOptionsModel
+ if (auto error = common::InitConfig(gArgs, ErrorSettingsRead)) {
+ InitError(error->message, error->details);
+ if (error->status == common::ConfigStatus::FAILED_WRITE) {
+ // Show a custom error message to provide more information in the
+ // case of a datadir write error.
+ ErrorSettingsWrite(error->message, error->details);
+ } else if (error->status != common::ConfigStatus::ABORTED) {
+ // Show a generic message in other cases, and no additional error
+ // message in the case of a read error if the user decided to abort.
+ QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: %1").arg(QString::fromStdString(error->message.translated)));
}
-
- /// 7. Determine network (and switch to network specific options)
- // - Do not call Params() before this step
- // - Do this after parsing the configuration file, as the network can be switched there
- // - QSettings() will use the new application name after this, resulting in network-specific settings
- // - Needs to be done before createOptionsModel
-
- // Check for chain settings (Params() calls are only valid after this clause)
- SelectParams(gArgs.GetChainName());
- } catch(std::exception &e) {
- InitError(Untranslated(strprintf("%s", e.what())));
- QMessageBox::critical(nullptr, PACKAGE_NAME, QObject::tr("Error: %1").arg(e.what()));
return EXIT_FAILURE;
}
#ifdef ENABLE_WALLET
@@ -622,10 +594,6 @@ int GuiMain(int argc, char* argv[])
PaymentServer::ipcParseCommandLine(argc, argv);
#endif
- if (!InitSettings()) {
- return EXIT_FAILURE;
- }
-
QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(Params().NetworkIDString()));
assert(!networkStyle.isNull());
// Allow for separate UI settings for testnets