diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp --- a/src/dummywallet.cpp +++ b/src/dummywallet.cpp @@ -10,6 +10,7 @@ class CChainParams; class CWallet; enum class WalletCreationStatus; +struct bilingual_str; namespace interfaces { class Chain; @@ -55,8 +56,9 @@ std::shared_ptr LoadWallet(const CChainParams &chainParams, interfaces::Chain &chain, - const std::string &name, std::string &error, - std::vector &warnings) { + const std::string &name, + bilingual_str &error, + std::vector &warnings) { throw std::logic_error("Wallet function called in non-wallet build."); } @@ -64,8 +66,8 @@ interfaces::Chain &chain, const SecureString &passphrase, uint64_t wallet_creation_flags, - const std::string &name, std::string &error, - std::vector &warnings, + const std::string &name, bilingual_str &error, + std::vector &warnings, std::shared_ptr &result) { throw std::logic_error("Wallet function called in non-wallet build."); } diff --git a/src/interfaces/node.h b/src/interfaces/node.h --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -34,6 +34,7 @@ class RPCTimerInterface; class UniValue; enum class WalletCreationStatus; +struct bilingual_str; namespace interfaces { class Handler; @@ -207,14 +208,14 @@ //! with handleLoadWallet. virtual std::unique_ptr loadWallet(const CChainParams ¶ms, const std::string &name, - std::string &error, - std::vector &warnings) const = 0; + bilingual_str &error, + std::vector &warnings) const = 0; //! Create a wallet from file virtual WalletCreationStatus createWallet(const CChainParams ¶ms, const SecureString &passphrase, uint64_t wallet_creation_flags, const std::string &name, - std::string &error, std::vector &warnings, + bilingual_str &error, std::vector &warnings, std::unique_ptr &result) = 0; //! Register handler for init messages. diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -44,14 +44,15 @@ std::vector> GetWallets(); std::shared_ptr LoadWallet(const CChainParams &chainParams, interfaces::Chain &chain, - const std::string &name, std::string &error, - std::vector &warnings); + const std::string &name, + bilingual_str &error, + std::vector &warnings); WalletCreationStatus CreateWallet(const CChainParams ¶ms, interfaces::Chain &chain, const SecureString &passphrase, uint64_t wallet_creation_flags, - const std::string &name, std::string &error, - std::vector &warnings, + const std::string &name, bilingual_str &error, + std::vector &warnings, std::shared_ptr &result); std::unique_ptr HandleLoadWallet(interfaces::Node::LoadWalletFn load_wallet); @@ -281,15 +282,15 @@ } std::unique_ptr loadWallet(const CChainParams ¶ms, const std::string &name, - std::string &error, - std::vector &warnings) const override { + bilingual_str &error, + std::vector &warnings) const override { return MakeWallet( LoadWallet(params, *m_context.chain, name, error, warnings)); } WalletCreationStatus createWallet(const CChainParams ¶ms, const SecureString &passphrase, uint64_t wallet_creation_flags, const std::string &name, - std::string &error, std::vector &warnings, + bilingual_str &error, std::vector &warnings, std::unique_ptr &result) override { std::shared_ptr wallet; WalletCreationStatus status = CreateWallet( diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h --- a/src/qt/walletcontroller.h +++ b/src/qt/walletcontroller.h @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -107,8 +108,8 @@ QWidget *const m_parent_widget; QProgressDialog *m_progress_dialog{nullptr}; WalletModel *m_wallet_model{nullptr}; - std::string m_error_message; - std::vector m_warning_message; + bilingual_str m_error_message; + std::vector m_warning_message; const CChainParams &m_chainparams; }; diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -238,13 +239,14 @@ void CreateWalletActivity::finish() { m_progress_dialog->hide(); - if (!m_error_message.empty()) { - QMessageBox::critical(m_parent_widget, tr("Create wallet failed"), - QString::fromStdString(m_error_message)); + if (!m_error_message.original.empty()) { + QMessageBox::critical( + m_parent_widget, tr("Create wallet failed"), + QString::fromStdString(m_error_message.translated)); } else if (!m_warning_message.empty()) { - QMessageBox::warning( - m_parent_widget, tr("Create wallet warning"), - QString::fromStdString(Join(m_warning_message, "\n"))); + QMessageBox::warning(m_parent_widget, tr("Create wallet warning"), + QString::fromStdString( + Join(m_warning_message, "\n", OpTranslated))); } if (m_wallet_model) { @@ -280,13 +282,14 @@ void OpenWalletActivity::finish() { m_progress_dialog->hide(); - if (!m_error_message.empty()) { - QMessageBox::critical(m_parent_widget, tr("Open wallet failed"), - QString::fromStdString(m_error_message)); + if (!m_error_message.original.empty()) { + QMessageBox::critical( + m_parent_widget, tr("Open wallet failed"), + QString::fromStdString(m_error_message.translated)); } else if (!m_warning_message.empty()) { - QMessageBox::warning( - m_parent_widget, tr("Open wallet warning"), - QString::fromStdString(Join(m_warning_message, "\n"))); + QMessageBox::warning(m_parent_widget, tr("Open wallet warning"), + QString::fromStdString( + Join(m_warning_message, "\n", OpTranslated))); } if (m_wallet_model) { diff --git a/src/util/translation.h b/src/util/translation.h --- a/src/util/translation.h +++ b/src/util/translation.h @@ -19,6 +19,25 @@ std::string translated; }; +inline bilingual_str operator+(const bilingual_str &lhs, + const bilingual_str &rhs) { + return bilingual_str{lhs.original + rhs.original, + lhs.translated + rhs.translated}; +} + +/** Mark a bilingual_str as untranslated */ +inline static bilingual_str Untranslated(std::string original) { + return {original, original}; +} +/** Unary operator to return the original */ +inline static std::string OpOriginal(const bilingual_str &b) { + return b.original; +} +/** Unary operator to return the translation */ +inline static std::string OpTranslated(const bilingual_str &b) { + return b.translated; +} + namespace tinyformat { template bilingual_str format(const bilingual_str &fmt, const Args &... args) { diff --git a/src/wallet/db.h b/src/wallet/db.h --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -21,6 +21,8 @@ #include #include +struct bilingual_str; + static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100; static const bool DEFAULT_WALLET_PRIVDB = true; @@ -271,12 +273,12 @@ static bool PeriodicFlush(BerkeleyDatabase &database); /* verifies the database environment */ static bool VerifyEnvironment(const fs::path &file_path, - std::string &errorStr); + bilingual_str &errorStr); /* verifies the database file */ static bool VerifyDatabaseFile(const fs::path &file_path, - std::vector &warnings, - std::string &errorStr, + std::vector &warnings, + bilingual_str &errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc); template bool Read(const K &key, T &value) { diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -425,7 +425,7 @@ } bool BerkeleyBatch::VerifyEnvironment(const fs::path &file_path, - std::string &errorStr) { + bilingual_str &errorStr) { std::string walletFile; std::shared_ptr env = GetWalletEnv(file_path, walletFile); @@ -437,8 +437,7 @@ if (!env->Open(true /* retry */)) { errorStr = strprintf( - _("Error initializing wallet database environment %s!").translated, - walletDir); + _("Error initializing wallet database environment %s!"), walletDir); return false; } @@ -446,8 +445,9 @@ } bool BerkeleyBatch::VerifyDatabaseFile( - const fs::path &file_path, std::vector &warnings, - std::string &errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc) { + const fs::path &file_path, std::vector &warnings, + bilingual_str &errorStr, + BerkeleyEnvironment::recoverFunc_type recoverFunc) { std::string walletFile; std::shared_ptr env = GetWalletEnv(file_path, walletFile); @@ -458,16 +458,15 @@ BerkeleyEnvironment::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename); if (r == BerkeleyEnvironment::VerifyResult::RECOVER_OK) { - warnings.push_back(strprintf( - _("Warning: Wallet file corrupt, data salvaged! Original %s " - "saved as %s in %s; if your balance or transactions are " - "incorrect you should restore from a backup.") - .translated, - walletFile, backup_filename, walletDir)); + warnings.push_back( + strprintf(_("Warning: Wallet file corrupt, data salvaged!" + " Original %s saved as %s in %s; if your balance " + "or transactions are incorrect you should restore " + "from a backup."), + walletFile, backup_filename, walletDir)); } if (r == BerkeleyEnvironment::VerifyResult::RECOVER_FAIL) { - errorStr = strprintf(_("%s corrupt, salvage failed").translated, - walletFile); + errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile); return false; } } diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -65,18 +65,16 @@ return false; } - std::string error_string; - std::vector warnings; + bilingual_str error_string; + std::vector warnings; bool verify_success = CWallet::Verify(chainParams, chain, location, salvage_wallet, error_string, warnings); - if (!error_string.empty()) { - chain.initError(error_string); - } if (!warnings.empty()) { - chain.initWarning(Join(warnings, "\n")); + chain.initWarning(Join(warnings, "\n", OpTranslated)); } if (!verify_success) { + chain.initError(error_string.translated); return false; } } @@ -87,15 +85,15 @@ bool LoadWallets(const CChainParams &chainParams, interfaces::Chain &chain, const std::vector &wallet_files) { for (const std::string &walletFile : wallet_files) { - std::string error; - std::vector warnings; + bilingual_str error; + std::vector warnings; std::shared_ptr pwallet = CWallet::CreateWalletFromFile( chainParams, chain, WalletLocation(walletFile), error, warnings); if (!warnings.empty()) { - chain.initWarning(Join(warnings, "\n")); + chain.initWarning(Join(warnings, "\n", OpTranslated)); } if (!pwallet) { - chain.initError(error); + chain.initError(error.translated); return false; } AddWallet(pwallet); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -3090,17 +3091,17 @@ } } - std::string error; - std::vector warning; + bilingual_str error; + std::vector warnings; std::shared_ptr const wallet = - LoadWallet(chainParams, *g_rpc_chain, location, error, warning); + LoadWallet(chainParams, *g_rpc_chain, location, error, warnings); if (!wallet) { - throw JSONRPCError(RPC_WALLET_ERROR, error); + throw JSONRPCError(RPC_WALLET_ERROR, error.original); } UniValue obj(UniValue::VOBJ); obj.pushKV("name", wallet->GetName()); - obj.pushKV("warning", Join(warning, "\n")); + obj.pushKV("warning", Join(warnings, "\n", OpOriginal)); return obj; } @@ -3226,13 +3227,14 @@ SecureString passphrase; passphrase.reserve(100); - std::vector warnings; + std::vector warnings; if (!request.params[3].isNull()) { passphrase = request.params[3].get_str().c_str(); if (passphrase.empty()) { // Empty string means unencrypted - warnings.emplace_back("Empty string given as passphrase, wallet " - "will not be encrypted."); + warnings.emplace_back( + Untranslated("Empty string given as passphrase, wallet will " + "not be encrypted.")); } } @@ -3240,16 +3242,16 @@ flags |= WALLET_FLAG_AVOID_REUSE; } - std::string error; + bilingual_str error; std::shared_ptr wallet; WalletCreationStatus status = CreateWallet(config.GetChainParams(), *g_rpc_chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet); switch (status) { case WalletCreationStatus::CREATION_FAILED: - throw JSONRPCError(RPC_WALLET_ERROR, error); + throw JSONRPCError(RPC_WALLET_ERROR, error.original); case WalletCreationStatus::ENCRYPTION_FAILED: - throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, error); + throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, error.original); case WalletCreationStatus::SUCCESS: break; // no default case, so the compiler can warn about missing cases @@ -3257,7 +3259,7 @@ UniValue obj(UniValue::VOBJ); obj.pushKV("name", wallet->GetName()); - obj.pushKV("warning", Join(warnings, "\n")); + obj.pushKV("warning", Join(warnings, "\n", OpOriginal)); return obj; } diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -15,6 +15,7 @@ #include enum class OutputType; +struct bilingual_str; // Wallet storage things that ScriptPubKeyMans need in order to be able to store // things to the wallet database. It provides access to things that are part of @@ -192,7 +193,9 @@ virtual bool CanGetAddresses(bool internal = false) { return false; } /** Upgrades the wallet to the specified version */ - virtual bool Upgrade(int prev_version, std::string &error) { return false; } + virtual bool Upgrade(int prev_version, bilingual_str &error) { + return false; + } virtual bool HavePrivateKeys() const { return false; } @@ -329,7 +332,7 @@ bool SetupGeneration(bool force = false) override; - bool Upgrade(int prev_version, std::string &error) override; + bool Upgrade(int prev_version, bilingual_str &error) override; bool HavePrivateKeys() const override; diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -324,9 +324,8 @@ return keypool_has_keys; } -bool LegacyScriptPubKeyMan::Upgrade(int prev_version, std::string &error) { +bool LegacyScriptPubKeyMan::Upgrade(int prev_version, bilingual_str &error) { AssertLockHeld(cs_wallet); - error = ""; bool hd_upgrade = false; bool split_upgrade = false; if (m_storage.CanSupportFeature(FEATURE_HD) && !IsHDEnabled()) { @@ -351,7 +350,7 @@ // Regenerate the keypool if upgraded to HD if (hd_upgrade) { if (!TopUp()) { - error = _("Unable to generate keys").translated; + error = _("Unable to generate keys"); return false; } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -40,6 +40,8 @@ using LoadWalletFn = std::function wallet)>; +struct bilingual_str; + //! Explicitly unload and delete the wallet. //! Blocks the current thread after signaling the unload intent so that all //! wallet clients release the wallet. @@ -55,8 +57,8 @@ std::shared_ptr LoadWallet(const CChainParams &chainParams, interfaces::Chain &chain, const WalletLocation &location, - std::string &error, - std::vector &warnings); + bilingual_str &error, + std::vector &warnings); std::unique_ptr HandleLoadWallet(LoadWalletFn load_wallet); enum class WalletCreationStatus { SUCCESS, CREATION_FAILED, ENCRYPTION_FAILED }; @@ -65,8 +67,8 @@ interfaces::Chain &chain, const SecureString &passphrase, uint64_t wallet_creation_flags, - const std::string &name, std::string &error, - std::vector &warnings, + const std::string &name, bilingual_str &error, + std::vector &warnings, std::shared_ptr &result); //! -paytxfee default constexpr Amount DEFAULT_PAY_TX_FEE = Amount::zero(); @@ -1270,17 +1272,19 @@ //! Verify wallet naming and perform salvage on the wallet if required static bool Verify(const CChainParams &chainParams, interfaces::Chain &chain, const WalletLocation &location, - bool salvage_wallet, std::string &error_string, - std::vector &warnings); + bool salvage_wallet, bilingual_str &error_string, + std::vector &warnings); /** * Initializes the wallet, returns a new CWallet instance or a null pointer * in case of an error. */ - static std::shared_ptr CreateWalletFromFile( - const CChainParams &chainParams, interfaces::Chain &chain, - const WalletLocation &location, std::string &error, - std::vector &warnings, uint64_t wallet_creation_flags = 0); + static std::shared_ptr + CreateWalletFromFile(const CChainParams &chainParams, + interfaces::Chain &chain, + const WalletLocation &location, bilingual_str &error, + std::vector &warnings, + uint64_t wallet_creation_flags = 0); /** * Wallet post-init setup diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -153,18 +154,18 @@ std::shared_ptr LoadWallet(const CChainParams &chainParams, interfaces::Chain &chain, const WalletLocation &location, - std::string &error, - std::vector &warnings) { + bilingual_str &error, + std::vector &warnings) { if (!CWallet::Verify(chainParams, chain, location, false, error, warnings)) { - error = "Wallet file verification failed: " + error; + error = Untranslated("Wallet file verification failed: ") + error; return nullptr; } std::shared_ptr wallet = CWallet::CreateWalletFromFile( chainParams, chain, location, error, warnings); if (!wallet) { - error = "Wallet loading failed: " + error; + error = Untranslated("Wallet loading failed: ") + error; return nullptr; } AddWallet(wallet); @@ -174,8 +175,9 @@ std::shared_ptr LoadWallet(const CChainParams &chainParams, interfaces::Chain &chain, - const std::string &name, std::string &error, - std::vector &warnings) { + const std::string &name, + bilingual_str &error, + std::vector &warnings) { return LoadWallet(chainParams, chain, WalletLocation(name), error, warnings); } @@ -184,8 +186,8 @@ interfaces::Chain &chain, const SecureString &passphrase, uint64_t wallet_creation_flags, - const std::string &name, std::string &error, - std::vector &warnings, + const std::string &name, bilingual_str &error, + std::vector &warnings, std::shared_ptr &result) { // Indicate that the wallet is actually supposed to be blank and not just // blank to make it encrypted @@ -199,23 +201,26 @@ // Check the wallet file location WalletLocation location(name); if (location.Exists()) { - error = "Wallet " + location.GetName() + " already exists."; + error = strprintf(Untranslated("Wallet %s already exists."), + location.GetName()); return WalletCreationStatus::CREATION_FAILED; } // Wallet::Verify will check if we're trying to create a wallet with a // duplicate name. if (!CWallet::Verify(params, chain, location, false, error, warnings)) { - error = "Wallet file verification failed: " + error; + error = Untranslated("Wallet file verification failed.") + + Untranslated(" ") + error; return WalletCreationStatus::CREATION_FAILED; } // Do not allow a passphrase when private keys are disabled if (!passphrase.empty() && (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { - error = "Passphrase provided but private keys are disabled. A " - "passphrase is only used to encrypt private keys, so cannot be " - "used for wallets with private keys disabled."; + error = Untranslated( + "Passphrase provided but private keys are disabled. A passphrase " + "is only used to encrypt private keys, so cannot be used for " + "wallets with private keys disabled."); return WalletCreationStatus::CREATION_FAILED; } @@ -223,7 +228,8 @@ std::shared_ptr wallet = CWallet::CreateWalletFromFile( params, chain, location, error, warnings, wallet_creation_flags); if (!wallet) { - error = "Wallet creation failed: " + error; + error = + Untranslated("Wallet creation failed.") + Untranslated(" ") + error; return WalletCreationStatus::CREATION_FAILED; } @@ -231,13 +237,15 @@ if (!passphrase.empty() && !(wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { if (!wallet->EncryptWallet(passphrase)) { - error = "Error: Wallet created but failed to encrypt."; + error = + Untranslated("Error: Wallet created but failed to encrypt."); return WalletCreationStatus::ENCRYPTION_FAILED; } if (!create_blank) { // Unlock the wallet if (!wallet->Unlock(passphrase)) { - error = "Error: Wallet was encrypted but could not be unlocked"; + error = Untranslated( + "Error: Wallet was encrypted but could not be unlocked"); return WalletCreationStatus::ENCRYPTION_FAILED; } @@ -245,7 +253,7 @@ { if (auto spk_man = wallet->m_spk_man.get()) { if (!spk_man->SetupGeneration()) { - error = "Unable to generate initial keys"; + error = Untranslated("Unable to generate initial keys"); return WalletCreationStatus::CREATION_FAILED; } } @@ -3942,8 +3950,8 @@ bool CWallet::Verify(const CChainParams &chainParams, interfaces::Chain &chain, const WalletLocation &location, bool salvage_wallet, - std::string &error_string, - std::vector &warnings) { + bilingual_str &error_string, + std::vector &warnings) { // Do some checking on wallet path. It should be either a: // // 1. Path where a directory can be created. @@ -3957,22 +3965,22 @@ (path_type == fs::symlink_file && fs::is_directory(wallet_path)) || (path_type == fs::regular_file && fs::path(location.GetName()).filename() == location.GetName()))) { - error_string = + error_string = Untranslated( strprintf("Invalid -wallet path '%s'. -wallet path should point to " "a directory where wallet.dat and " "database/log.?????????? files can be stored, a location " "where such a directory could be created, " "or (for backwards compatibility) the name of an " "existing data file in -walletdir (%s)", - location.GetName(), GetWalletDir()); + location.GetName(), GetWalletDir())); return false; } // Make sure that the wallet path doesn't clash with an existing wallet path if (IsWalletLoaded(wallet_path)) { - error_string = strprintf( + error_string = Untranslated(strprintf( "Error loading wallet %s. Duplicate -wallet filename specified.", - location.GetName()); + location.GetName())); return false; } @@ -3986,9 +3994,9 @@ return false; } } catch (const fs::filesystem_error &e) { - error_string = + error_string = Untranslated( strprintf("Error loading wallet %s. %s", location.GetName(), - fsbridge::get_filesystem_error_message(e)); + fsbridge::get_filesystem_error_message(e))); return false; } @@ -4014,8 +4022,8 @@ std::shared_ptr CWallet::CreateWalletFromFile( const CChainParams &chainParams, interfaces::Chain &chain, - const WalletLocation &location, std::string &error, - std::vector &warnings, uint64_t wallet_creation_flags) { + const WalletLocation &location, bilingual_str &error, + std::vector &warnings, uint64_t wallet_creation_flags) { const std::string walletFile = WalletDataFilePath(location.GetPath()).string(); @@ -4031,8 +4039,8 @@ WalletDatabase::Create(location.GetPath())); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DBErrors::LOAD_OK) { - error = strprintf( - _("Error loading %s: Wallet corrupted").translated, walletFile); + error = + strprintf(_("Error loading %s: Wallet corrupted"), walletFile); return nullptr; } } @@ -4050,31 +4058,29 @@ DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DBErrors::LOAD_OK) { if (nLoadWalletRet == DBErrors::CORRUPT) { - error = strprintf( - _("Error loading %s: Wallet corrupted").translated, walletFile); + error = + strprintf(_("Error loading %s: Wallet corrupted"), walletFile); return nullptr; } if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR) { - warnings.push_back(strprintf( - _("Error reading %s! All keys read correctly, but transaction " - "data or address book entries might be missing or incorrect.") - .translated, - walletFile)); + warnings.push_back( + strprintf(_("Error reading %s! All keys read correctly, but " + "transaction data or address book entries might be " + "missing or incorrect."), + walletFile)); } else if (nLoadWalletRet == DBErrors::TOO_NEW) { error = strprintf( - _("Error loading %s: Wallet requires newer version of %s") - .translated, + _("Error loading %s: Wallet requires newer version of %s"), walletFile, PACKAGE_NAME); return nullptr; } else if (nLoadWalletRet == DBErrors::NEED_REWRITE) { error = strprintf( - _("Wallet needed to be rewritten: restart %s to complete") - .translated, + _("Wallet needed to be rewritten: restart %s to complete"), PACKAGE_NAME); return nullptr; } else { - error = strprintf(_("Error loading %s").translated, walletFile); + error = strprintf(_("Error loading %s"), walletFile); return nullptr; } } @@ -4095,7 +4101,7 @@ } if (nMaxVersion < walletInstance->GetVersion()) { - error = _("Cannot downgrade wallet").translated; + error = _("Cannot downgrade wallet"); return nullptr; } @@ -4115,8 +4121,7 @@ error = _("Cannot upgrade a non HD split wallet without upgrading to " "support pre split keypool. Please use -upgradewallet=200300 " - "or -upgradewallet with no version specified.") - .translated; + "or -upgradewallet with no version specified."); return nullptr; } @@ -4137,7 +4142,7 @@ (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) { if (auto spk_man = walletInstance->m_spk_man.get()) { if (!spk_man->SetupGeneration()) { - error = _("Unable to generate initial keys").translated; + error = _("Unable to generate initial keys"); return nullptr; } } @@ -4148,8 +4153,7 @@ } else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) { // Make it impossible to disable private keys after creation error = strprintf(_("Error loading %s: Private keys can only be " - "disabled during creation") - .translated, + "disabled during creation"), walletFile); return nullptr; } else if (walletInstance->IsWalletFlagSet( @@ -4158,8 +4162,7 @@ if (walletInstance->m_spk_man->HavePrivateKeys()) { warnings.push_back( strprintf(_("Warning: Private keys detected in wallet {%s} " - "with disabled private keys") - .translated, + "with disabled private keys"), walletFile)); } } @@ -4169,15 +4172,13 @@ Amount n = Amount::zero(); if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || n == Amount::zero()) { - error = AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")) - .translated; + error = AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")); return nullptr; } if (n > HIGH_TX_FEE_PER_KB) { - warnings.push_back(AmountHighWarn("-mintxfee").translated + " " + + warnings.push_back(AmountHighWarn("-mintxfee") + Untranslated(" ") + _("This is the minimum transaction fee you pay " - "on every transaction.") - .translated); + "on every transaction.")); } walletInstance->m_min_fee = CFeeRate(n); } @@ -4185,16 +4186,16 @@ if (gArgs.IsArgSet("-fallbackfee")) { Amount nFeePerK = Amount::zero(); if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) { - error = strprintf( - _("Invalid amount for -fallbackfee=: '%s'").translated, - gArgs.GetArg("-fallbackfee", "")); + error = + strprintf(_("Invalid amount for -fallbackfee=: '%s'"), + gArgs.GetArg("-fallbackfee", "")); return nullptr; } if (nFeePerK > HIGH_TX_FEE_PER_KB) { - warnings.push_back(AmountHighWarn("-fallbackfee").translated + " " + + warnings.push_back(AmountHighWarn("-fallbackfee") + + Untranslated(" ") + _("This is the transaction fee you may pay when " - "fee estimates are not available.") - .translated); + "fee estimates are not available.")); } walletInstance->m_fallback_fee = CFeeRate(nFeePerK); } @@ -4205,21 +4206,18 @@ if (gArgs.IsArgSet("-paytxfee")) { Amount nFeePerK = Amount::zero(); if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) { - error = AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")) - .translated; + error = AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")); return nullptr; } if (nFeePerK > HIGH_TX_FEE_PER_KB) { - warnings.push_back(AmountHighWarn("-paytxfee").translated + " " + + warnings.push_back(AmountHighWarn("-paytxfee") + Untranslated(" ") + _("This is the transaction fee you will pay if " - "you send a transaction.") - .translated); + "you send a transaction.")); } walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000); if (walletInstance->m_pay_tx_fee < chain.relayMinFee()) { error = strprintf(_("Invalid amount for -paytxfee=: '%s' " - "(must be at least %s)") - .translated, + "(must be at least %s)"), gArgs.GetArg("-paytxfee", ""), chain.relayMinFee().ToString()); return nullptr; @@ -4229,20 +4227,18 @@ if (gArgs.IsArgSet("-maxtxfee")) { Amount nMaxFee = Amount::zero(); if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) { - error = AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")) - .translated; + error = AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")); return nullptr; } if (nMaxFee > HIGH_MAX_TX_FEE) { warnings.push_back(_("-maxtxfee is set very high! Fees this large " - "could be paid on a single transaction.") - .translated); + "could be paid on a single transaction.")); } if (CFeeRate(nMaxFee, 1000) < chain.relayMinFee()) { error = strprintf( _("Invalid amount for -maxtxfee=: '%s' (must be at " - "least the minrelay fee of %s to prevent stuck transactions)") - .translated, + "least the minrelay fee of %s to prevent stuck " + "transactions)"), gArgs.GetArg("-maxtxfee", ""), chain.relayMinFee().ToString()); return nullptr; } @@ -4251,9 +4247,8 @@ if (chain.relayMinFee().GetFeePerK() > HIGH_TX_FEE_PER_KB) { warnings.push_back( - AmountHighWarn("-minrelaytxfee").translated + " " + - _("The wallet will avoid paying less than the minimum relay fee.") - .translated); + AmountHighWarn("-minrelaytxfee") + Untranslated(" ") + + _("The wallet will avoid paying less than the minimum relay fee.")); } walletInstance->m_spend_zero_conf_change = @@ -4312,8 +4307,7 @@ if (rescan_height != block_height) { error = _("Prune: last wallet synchronisation goes beyond " "pruned data. You need to -reindex (download the " - "whole blockchain again in case of pruned node)") - .translated; + "whole blockchain again in case of pruned node)"); return nullptr; } } @@ -4350,8 +4344,7 @@ locked_chain->getBlockHash(rescan_height), BlockHash(), reserver, true /* update */) .status)) { - error = _("Failed to rescan the wallet during initialization") - .translated; + error = _("Failed to rescan the wallet during initialization"); return nullptr; } } diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -246,11 +246,11 @@ static bool IsKeyType(const std::string &strType); /* verifies the database environment */ static bool VerifyEnvironment(const fs::path &wallet_path, - std::string &errorStr); + bilingual_str &errorStr); /* verifies the database file */ static bool VerifyDatabaseFile(const fs::path &wallet_path, - std::vector &warnings, - std::string &errorStr); + std::vector &warnings, + bilingual_str &errorStr); //! write the hdchain model (external chain child index counter) bool WriteHDChain(const CHDChain &chain); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -781,13 +781,13 @@ } bool WalletBatch::VerifyEnvironment(const fs::path &wallet_path, - std::string &errorStr) { + bilingual_str &errorStr) { return BerkeleyBatch::VerifyEnvironment(wallet_path, errorStr); } bool WalletBatch::VerifyDatabaseFile(const fs::path &wallet_path, - std::vector &warnings, - std::string &errorStr) { + std::vector &warnings, + bilingual_str &errorStr) { return BerkeleyBatch::VerifyDatabaseFile(wallet_path, warnings, errorStr, WalletBatch::Recover); } diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -136,7 +137,7 @@ tfm::format(std::cerr, "Error: no wallet file at %s\n", name); return false; } - std::string error; + bilingual_str error; if (!WalletBatch::VerifyEnvironment(path, error)) { tfm::format( std::cerr,