diff --git a/src/common/args.cpp b/src/common/args.cpp index ca04175696..b85d3dfc3d 100644 --- a/src/common/args.cpp +++ b/src/common/args.cpp @@ -543,9 +543,14 @@ bool ArgsManager::SoftSetBoolArg(const std::string& strArg, bool fValue) } void ArgsManager::ForceSetArg(const std::string& strArg, const std::string& strValue) +{ + ForceSetArgV(strArg, common::SettingsValue{strValue}); +} + +void ArgsManager::ForceSetArgV(const std::string& arg, const common::SettingsValue& value) { LOCK(cs_args); - m_settings.forced_settings[SettingName(strArg)] = strValue; + m_settings.forced_settings[SettingName(arg)] = value; } void ArgsManager::AddCommand(const std::string& cmd, const std::string& help) diff --git a/src/common/args.h b/src/common/args.h index ae3ed02bc7..7051692838 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -322,7 +322,8 @@ protected: // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already // been set. Also called directly in testing. - void ForceSetArg(const std::string& strArg, const std::string& strValue); + void ForceSetArg(const std::string& arg, const std::string& value); + void ForceSetArgV(const std::string& arg, const common::SettingsValue& value); /** * Returns the appropriate chain type from the program arguments. diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index dea868f844..1a740352bd 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -301,6 +301,9 @@ public: //! Send init error. virtual void initError(const bilingual_str& message) = 0; + //! Ask init question. + virtual bool initQuestion(const bilingual_str& message, const bilingual_str& non_interactive_message, const bilingual_str& caption, unsigned int style) = 0; + //! Send progress indicator. virtual void showProgress(const std::string& title, int progress, bool resume_possible) = 0; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 3930280797..ae4cf083d7 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -750,6 +750,9 @@ public: void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); } void initWarning(const bilingual_str& message) override { InitWarning(message); } void initError(const bilingual_str& message) override { InitError(message); } + bool initQuestion(const bilingual_str& message, const bilingual_str& non_interactive_message, const bilingual_str& caption, unsigned int style) override { + return uiInterface.ThreadSafeQuestion(message, non_interactive_message.translated, caption.translated, style); + } void showProgress(const std::string& title, int progress, bool resume_possible) override { ::uiInterface.ShowProgress(title, progress, resume_possible); diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp index 4cdfadbee2..f90048709e 100644 --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -22,6 +23,17 @@ #include namespace wallet { + +bool HandleWalletLoadError(interfaces::Chain& chain, const std::string& wallet_file, const bilingual_str& error_string) +{ + if (!chain.initQuestion(error_string + Untranslated("\n\n") + _("Continue without this wallet?"), error_string, _("Error"), CClientUIInterface::MSG_ERROR | CClientUIInterface::MODAL | CClientUIInterface::BTN_OK | CClientUIInterface::BTN_ABORT)) { + return false; + } + + RemoveWalletSetting(chain, wallet_file); + return true; +} + bool VerifyWallets(WalletContext& context) { interfaces::Chain& chain = *context.chain; @@ -74,6 +86,7 @@ bool VerifyWallets(WalletContext& context) // Keep track of each wallet absolute path to detect duplicates. std::set wallet_paths; + bool modified_wallet_list = false; for (const auto& wallet : chain.getSettingsList("wallet")) { const auto& wallet_file = wallet.get_str(); const fs::path path = fsbridge::AbsPathJoin(GetWalletDir(), fs::PathFromString(wallet_file)); @@ -93,12 +106,20 @@ bool VerifyWallets(WalletContext& context) if (status == DatabaseStatus::FAILED_NOT_FOUND) { chain.initWarning(Untranslated(strprintf("Skipping -wallet path that doesn't exist. %s", error_string.original))); } else { - chain.initError(error_string); - return false; + if (HandleWalletLoadError(chain, wallet_file, error_string)) { + modified_wallet_list = true; + } else { + return false; + } } } } + if (modified_wallet_list) { + // Ensure new wallet list overrides commandline options + args.ForceSetArgV("wallet", chain.getRwSetting("wallet")); + } + return true; } @@ -127,8 +148,11 @@ bool LoadWallets(WalletContext& context) std::shared_ptr pwallet = database ? CWallet::Create(context, name, std::move(database), options.create_flags, error, warnings) : nullptr; if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n"))); if (!pwallet) { - chain.initError(error); - return false; + if (HandleWalletLoadError(chain, name, error)) { + continue; + } else { + return false; + } } NotifyWalletLoaded(context, pwallet);