Merge #16224: gui: Bilingual GUI error messages

18bd83b1fee2eb47ed4ad05c91f2d6cc311fc9ad util: Cleanup translation.h (Hennadii Stepanov)
e95e658b8ec6e02229691a1941d688e96d4df6af doc: Do not translate technical or extremely rare errors (Hennadii Stepanov)
7e923d47ba9891856b86bc9f718cf2f1f773bdf6 Make InitError bilingual (Hennadii Stepanov)
917ca93553917251e0fd59717a347c63cdfd8a14 Make ThreadSafe{MessageBox|Question} bilingual (Hennadii Stepanov)
23b9fa2e5ec0425980301d2eebad81e660a5ea39 gui: Add detailed text to BitcoinGUI::message (Hennadii Stepanov)

Pull request description:

  This is an alternative to #15340 (it works with the `Chain` interface; see: https://github.com/bitcoin/bitcoin/pull/15340#issuecomment-502674004).
  Refs:
  - #16218 (partial fix)
  - https://github.com/bitcoin/bitcoin/pull/15894#issuecomment-487947077

  This PR:
  - makes GUI error messages bilingual: user's native language + untranslated (i.e. English)
  - insures that only untranslated messages are written to the debug log file and to `stderr` (that is not the case on master).

  If a translated string is unavailable only an English string appears to a user.

  Here are some **examples** (updated):

  ![Screenshot from 2020-04-24 17-08-37](https://user-images.githubusercontent.com/32963518/80222043-e2458780-864e-11ea-83fc-197b7121dba5.png)

  ![Screenshot from 2020-04-24 17-12-17](https://user-images.githubusercontent.com/32963518/80222051-e5407800-864e-11ea-92f7-dfef1144becd.png)

  * `qt5ct: using qt5ct plugin` message is my local environment specific; please ignore it.

  ---

  Note for reviewers: `InitWarning()` is out of this PR scope.

ACKs for top commit:
  Sjors:
    re-tACK 18bd83b1fee2eb47ed4ad05c91f2d6cc311fc9ad
  MarcoFalke:
    ACK 18bd83b1fee2eb47ed4ad05c91f2d6cc311fc9ad 🐦

Tree-SHA512: 3cc8ec44f84403e54b57d11714c86b0855ed90eb794b5472e432005073354b9e3f7b4e8e7bf347a4c21be47299dbc7170f2d0c4b80e308205ff09596e55a4f96

# Conflicts:
#	src/dashd.cpp
#	src/httpserver.cpp
#	src/index/base.cpp
#	src/init.cpp
#	src/interfaces/chain.cpp
#	src/interfaces/chain.h
#	src/interfaces/node.cpp
#	src/net.h
#	src/qt/bitcoingui.cpp
#	src/ui_interface.h
#	src/wallet/init.cpp
#	src/wallet/load.cpp
This commit is contained in:
MarcoFalke 2020-05-08 12:17:47 -04:00 committed by pasta
parent 903291788c
commit af00598c9a
23 changed files with 202 additions and 179 deletions

View File

@ -23,7 +23,8 @@ On a high level, these strings are to be translated:
### GUI strings ### GUI strings
Anything that appears to the user in the GUI is to be translated. This includes labels, menu items, button texts, tooltips and window titles. Do not translate technical or extremely rare errors.
Anything else that appears to the user in the GUI is to be translated. This includes labels, menu items, button texts, tooltips and window titles.
This includes messages passed to the GUI through the UI interface through `InitMessage`, `ThreadSafeMessageBox` or `ShowProgress`. This includes messages passed to the GUI through the UI interface through `InitMessage`, `ThreadSafeMessageBox` or `ShowProgress`.
General recommendations General recommendations

View File

@ -56,7 +56,7 @@ static bool AppInit(int argc, char* argv[])
SetupServerArgs(); SetupServerArgs();
std::string error; std::string error;
if (!gArgs.ParseParameters(argc, argv, error)) { if (!gArgs.ParseParameters(argc, argv, error)) {
return InitError(strprintf("Error parsing command line arguments: %s\n", error)); return InitError(Untranslated(strprintf("Error parsing command line arguments: %s\n", error)));
} }
if (gArgs.IsArgSet("-printcrashinfo")) { if (gArgs.IsArgSet("-printcrashinfo")) {
@ -87,10 +87,10 @@ static bool AppInit(int argc, char* argv[])
bool datadirFromCmdLine = gArgs.IsArgSet("-datadir"); bool datadirFromCmdLine = gArgs.IsArgSet("-datadir");
if (datadirFromCmdLine && !fs::is_directory(GetDataDir(false))) if (datadirFromCmdLine && !fs::is_directory(GetDataDir(false)))
{ {
return InitError(strprintf("Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""))); return InitError(Untranslated(strprintf("Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""))));
} }
if (!gArgs.ReadConfigFiles(error, true)) { if (!gArgs.ReadConfigFiles(error, true)) {
return InitError(strprintf("Error reading configuration file: %s\n", error)); return InitError(Untranslated(strprintf("Error reading configuration file: %s\n", error)));
} }
if (!datadirFromCmdLine && !fs::is_directory(GetDataDir(false))) if (!datadirFromCmdLine && !fs::is_directory(GetDataDir(false)))
{ {
@ -101,13 +101,13 @@ static bool AppInit(int argc, char* argv[])
try { try {
SelectParams(gArgs.GetChainName()); SelectParams(gArgs.GetChainName());
} catch (const std::exception& e) { } catch (const std::exception& e) {
return InitError(strprintf("%s\n", e.what())); return InitError(Untranslated(strprintf("%s\n", e.what())));
} }
// Error out when loose non-argument tokens are encountered on command line // Error out when loose non-argument tokens are encountered on command line
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (!IsSwitchChar(argv[i][0])) { if (!IsSwitchChar(argv[i][0])) {
return InitError(strprintf("Command line contains unexpected token '%s', see dashd -h for a list of options.\n", argv[i])); return InitError(Untranslated(strprintf("Command line contains unexpected token '%s', see dashd -h for a list of options.\n", argv[i])));
} }
} }
@ -142,13 +142,13 @@ static bool AppInit(int argc, char* argv[])
// Daemonize // Daemonize
if (daemon(1, 0)) { // don't chdir (1), do close FDs (0) if (daemon(1, 0)) { // don't chdir (1), do close FDs (0)
return InitError(strprintf("daemon() failed: %s\n", strerror(errno))); return InitError(Untranslated(strprintf("daemon() failed: %s\n", strerror(errno))));
} }
#if defined(MAC_OSX) #if defined(MAC_OSX)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#else #else
return InitError("-daemon is not supported on this operating system\n"); return InitError(Untranslated("-daemon is not supported on this operating system\n"));
#endif // HAVE_DECL_DAEMON #endif // HAVE_DECL_DAEMON
} }
// Lock data directory after daemonization // Lock data directory after daemonization

View File

@ -219,7 +219,7 @@ static bool InitRPCAuthentication()
LogPrintf("Using random cookie authentication.\n"); LogPrintf("Using random cookie authentication.\n");
if (!GenerateAuthCookie(&strRPCUserColonPass)) { if (!GenerateAuthCookie(&strRPCUserColonPass)) {
uiInterface.ThreadSafeMessageBox( uiInterface.ThreadSafeMessageBox(
_("Error: A fatal internal error occurred, see debug.log for details").translated, // Same message as AbortNode _("Error: A fatal internal error occurred, see debug.log for details"), // Same message as AbortNode
"", CClientUIInterface::MSG_ERROR); "", CClientUIInterface::MSG_ERROR);
return false; return false;
} }

View File

@ -5,14 +5,15 @@
#include <httpserver.h> #include <httpserver.h>
#include <chainparamsbase.h> #include <chainparamsbase.h>
#include <util/system.h>
#include <util/strencodings.h>
#include <util/threadnames.h>
#include <netbase.h> #include <netbase.h>
#include <rpc/protocol.h> // For HTTP status codes #include <rpc/protocol.h> // For HTTP status codes
#include <shutdown.h> #include <shutdown.h>
#include <sync.h> #include <sync.h>
#include <ui_interface.h> #include <ui_interface.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/threadnames.h>
#include <util/translation.h>
#include <deque> #include <deque>
#include <stdio.h> #include <stdio.h>
@ -173,7 +174,7 @@ static bool InitHTTPAllowList()
LookupSubNet(strAllow.c_str(), subnet); LookupSubNet(strAllow.c_str(), subnet);
if (!subnet.IsValid()) { if (!subnet.IsValid()) {
uiInterface.ThreadSafeMessageBox( uiInterface.ThreadSafeMessageBox(
strprintf("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24).", strAllow), strprintf(Untranslated("Invalid -rpcallowip subnet specification: %s. Valid are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24)."), strAllow),
"", CClientUIInterface::MSG_ERROR); "", CClientUIInterface::MSG_ERROR);
return false; return false;
} }

View File

@ -7,6 +7,7 @@
#include <shutdown.h> #include <shutdown.h>
#include <tinyformat.h> #include <tinyformat.h>
#include <ui_interface.h> #include <ui_interface.h>
#include <util/translation.h>
#include <validation.h> #include <validation.h>
#include <warnings.h> #include <warnings.h>
@ -22,7 +23,7 @@ static void FatalError(const char* fmt, const Args&... args)
SetMiscWarning(strMessage); SetMiscWarning(strMessage);
LogPrintf("*** %s\n", strMessage); LogPrintf("*** %s\n", strMessage);
uiInterface.ThreadSafeMessageBox( uiInterface.ThreadSafeMessageBox(
"Error: A fatal internal error occurred, see debug.log for details", Untranslated("Error: A fatal internal error occurred, see debug.log for details"),
"", CClientUIInterface::MSG_ERROR); "", CClientUIInterface::MSG_ERROR);
StartShutdown(); StartShutdown();
} }

View File

@ -151,7 +151,7 @@ static fs::path GetPidFile()
tfm::format(file, "%d\n", getpid()); tfm::format(file, "%d\n", getpid());
return true; return true;
} else { } else {
return InitError(strprintf(_("Unable to create the PID file '%s': %s").translated, GetPidFile().string(), std::strerror(errno))); return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile().string(), std::strerror(errno)));
} }
} }
#endif #endif
@ -1031,9 +1031,8 @@ void PeriodicStats()
*/ */
static bool InitSanityCheck() static bool InitSanityCheck()
{ {
if(!ECC_InitSanityCheck()) { if (!ECC_InitSanityCheck()) {
InitError("Elliptic curve cryptography sanity check failure. Aborting."); return InitError(Untranslated("Elliptic curve cryptography sanity check failure. Aborting."));
return false;
} }
if (!glibc_sanity_test() || !glibcxx_sanity_test()) if (!glibc_sanity_test() || !glibcxx_sanity_test())
@ -1044,8 +1043,7 @@ static bool InitSanityCheck()
} }
if (!Random_SanityCheck()) { if (!Random_SanityCheck()) {
InitError("OS cryptographic RNG sanity check failure. Aborting."); return InitError(Untranslated("OS cryptographic RNG sanity check failure. Aborting."));
return false;
} }
return true; return true;
@ -1230,8 +1228,9 @@ bool AppInitBasicSetup()
HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0); HeapSetInformation(nullptr, HeapEnableTerminationOnCorruption, nullptr, 0);
#endif #endif
if (!SetupNetworking()) if (!SetupNetworking()) {
return InitError("Initializing networking failed"); return InitError(Untranslated("Initializing networking failed."));
}
#ifndef WIN32 #ifndef WIN32
if (!gArgs.GetBoolArg("-sysperms", false)) { if (!gArgs.GetBoolArg("-sysperms", false)) {
@ -1268,7 +1267,7 @@ bool AppInitParameterInteraction()
// on the command line or in this network's section of the config file. // on the command line or in this network's section of the config file.
std::string network = gArgs.GetChainName(); std::string network = gArgs.GetChainName();
for (const auto& arg : gArgs.GetUnsuitableSectionOnlyArgs()) { for (const auto& arg : gArgs.GetUnsuitableSectionOnlyArgs()) {
return InitError(strprintf(_("Config setting for %s only applied on %s network when in [%s] section.").translated, arg, network, network)); return InitError(strprintf(_("Config setting for %s only applied on %s network when in [%s] section."), arg, network, network));
} }
// Warn if unrecognized section name are present in the config file. // Warn if unrecognized section name are present in the config file.
@ -1277,7 +1276,7 @@ bool AppInitParameterInteraction()
} }
if (!fs::is_directory(GetBlocksDir())) { if (!fs::is_directory(GetBlocksDir())) {
return InitError(strprintf(_("Specified blocks directory \"%s\" does not exist.").translated, gArgs.GetArg("-blocksdir", ""))); return InitError(strprintf(_("Specified blocks directory \"%s\" does not exist."), gArgs.GetArg("-blocksdir", "")));
} }
// parse and validate enabled filter types // parse and validate enabled filter types
@ -1289,7 +1288,7 @@ bool AppInitParameterInteraction()
for (const auto& name : names) { for (const auto& name : names) {
BlockFilterType filter_type; BlockFilterType filter_type;
if (!BlockFilterTypeByName(name, filter_type)) { if (!BlockFilterTypeByName(name, filter_type)) {
return InitError(strprintf(_("Unknown -blockfilterindex value %s.").translated, name)); return InitError(strprintf(_("Unknown -blockfilterindex value %s."), name));
} }
g_enabled_filter_types.insert(filter_type); g_enabled_filter_types.insert(filter_type);
} }
@ -1298,7 +1297,7 @@ bool AppInitParameterInteraction()
// Signal NODE_COMPACT_FILTERS if peerblockfilters and basic filters index are both enabled. // Signal NODE_COMPACT_FILTERS if peerblockfilters and basic filters index are both enabled.
if (gArgs.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)) { if (gArgs.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)) {
if (g_enabled_filter_types.count(BlockFilterType::BASIC_FILTER) != 1) { if (g_enabled_filter_types.count(BlockFilterType::BASIC_FILTER) != 1) {
return InitError(_("Cannot set -peerblockfilters without -blockfilterindex.").translated); return InitError(_("Cannot set -peerblockfilters without -blockfilterindex."));
} }
nLocalServices = ServiceFlags(nLocalServices | NODE_COMPACT_FILTERS); nLocalServices = ServiceFlags(nLocalServices | NODE_COMPACT_FILTERS);
@ -1307,25 +1306,25 @@ bool AppInitParameterInteraction()
// if using block pruning, then disallow txindex and require disabling governance validation // if using block pruning, then disallow txindex and require disabling governance validation
if (gArgs.GetArg("-prune", 0)) { if (gArgs.GetArg("-prune", 0)) {
if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX))
return InitError(_("Prune mode is incompatible with -txindex.").translated); return InitError(_("Prune mode is incompatible with -txindex."));
if (!gArgs.GetBoolArg("-disablegovernance", false)) { if (!gArgs.GetBoolArg("-disablegovernance", false)) {
return InitError(_("Prune mode is incompatible with -disablegovernance=false.").translated); return InitError(_("Prune mode is incompatible with -disablegovernance=false."));
} }
if (!g_enabled_filter_types.empty()) { if (!g_enabled_filter_types.empty()) {
return InitError(_("Prune mode is incompatible with -blockfilterindex.").translated); return InitError(_("Prune mode is incompatible with -blockfilterindex."));
} }
} }
if (gArgs.IsArgSet("-devnet")) { if (gArgs.IsArgSet("-devnet")) {
// Require setting of ports when running devnet // Require setting of ports when running devnet
if (gArgs.GetArg("-listen", DEFAULT_LISTEN) && !gArgs.IsArgSet("-port")) { if (gArgs.GetArg("-listen", DEFAULT_LISTEN) && !gArgs.IsArgSet("-port")) {
return InitError(_("-port must be specified when -devnet and -listen are specified").translated); return InitError(_("-port must be specified when -devnet and -listen are specified"));
} }
if (gArgs.GetArg("-server", false) && !gArgs.IsArgSet("-rpcport")) { if (gArgs.GetArg("-server", false) && !gArgs.IsArgSet("-rpcport")) {
return InitError(_("-rpcport must be specified when -devnet and -server are specified").translated); return InitError(_("-rpcport must be specified when -devnet and -server are specified"));
} }
if (gArgs.GetArgs("-devnet").size() > 1) { if (gArgs.GetArgs("-devnet").size() > 1) {
return InitError(_("-devnet can only be specified once").translated); return InitError(_("-devnet can only be specified once"));
} }
} }
@ -1334,7 +1333,7 @@ bool AppInitParameterInteraction()
// -bind and -whitebind can't be set when not listening // -bind and -whitebind can't be set when not listening
size_t nUserBind = gArgs.GetArgs("-bind").size() + gArgs.GetArgs("-whitebind").size(); size_t nUserBind = gArgs.GetArgs("-bind").size() + gArgs.GetArgs("-whitebind").size();
if (nUserBind != 0 && !gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) { if (nUserBind != 0 && !gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) {
return InitError("Cannot set -bind or -whitebind together with -listen=0"); return InitError(Untranslated("Cannot set -bind or -whitebind together with -listen=0"));
} }
// Make sure enough file descriptors are available // Make sure enough file descriptors are available
@ -1352,7 +1351,7 @@ bool AppInitParameterInteraction()
#endif #endif
nMaxConnections = std::max(std::min<int>(nMaxConnections, fd_max - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS), 0); nMaxConnections = std::max(std::min<int>(nMaxConnections, fd_max - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS), 0);
if (nFD < MIN_CORE_FILEDESCRIPTORS) if (nFD < MIN_CORE_FILEDESCRIPTORS)
return InitError(_("Not enough file descriptors available.").translated); return InitError(_("Not enough file descriptors available."));
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections); nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections);
if (nMaxConnections < nUserMaxConnections) if (nMaxConnections < nUserMaxConnections)
@ -1397,7 +1396,7 @@ bool AppInitParameterInteraction()
if (gArgs.IsArgSet("-minimumchainwork")) { if (gArgs.IsArgSet("-minimumchainwork")) {
const std::string minChainWorkStr = gArgs.GetArg("-minimumchainwork", ""); const std::string minChainWorkStr = gArgs.GetArg("-minimumchainwork", "");
if (!IsHexNumber(minChainWorkStr)) { if (!IsHexNumber(minChainWorkStr)) {
return InitError(strprintf("Invalid non-hex (%s) minimum chain work value specified", minChainWorkStr)); return InitError(strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), minChainWorkStr));
} }
nMinimumChainWork = UintToArith256(uint256S(minChainWorkStr)); nMinimumChainWork = UintToArith256(uint256S(minChainWorkStr));
} else { } else {
@ -1412,21 +1411,21 @@ bool AppInitParameterInteraction()
int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
int64_t nMempoolSizeMin = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; int64_t nMempoolSizeMin = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40;
if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin)
return InitError(strprintf(_("-maxmempool must be at least %d MB").translated, std::ceil(nMempoolSizeMin / 1000000.0))); return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0)));
// incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool
// and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting. // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting.
if (gArgs.IsArgSet("-incrementalrelayfee")) if (gArgs.IsArgSet("-incrementalrelayfee"))
{ {
CAmount n = 0; CAmount n = 0;
if (!ParseMoney(gArgs.GetArg("-incrementalrelayfee", ""), n)) if (!ParseMoney(gArgs.GetArg("-incrementalrelayfee", ""), n))
return InitError(AmountErrMsg("incrementalrelayfee", gArgs.GetArg("-incrementalrelayfee", ""))); return InitError(Untranslated(AmountErrMsg("incrementalrelayfee", gArgs.GetArg("-incrementalrelayfee", ""))));
incrementalRelayFee = CFeeRate(n); incrementalRelayFee = CFeeRate(n);
} }
// block pruning; get the amount of disk space (in MiB) to allot for block & undo files // block pruning; get the amount of disk space (in MiB) to allot for block & undo files
int64_t nPruneArg = gArgs.GetArg("-prune", 0); int64_t nPruneArg = gArgs.GetArg("-prune", 0);
if (nPruneArg < 0) { if (nPruneArg < 0) {
return InitError(_("Prune cannot be configured with a negative value.").translated); return InitError(_("Prune cannot be configured with a negative value."));
} }
nPruneTarget = (uint64_t) nPruneArg * 1024 * 1024; nPruneTarget = (uint64_t) nPruneArg * 1024 * 1024;
if (nPruneArg == 1) { // manual pruning: -prune=1 if (nPruneArg == 1) { // manual pruning: -prune=1
@ -1437,11 +1436,11 @@ bool AppInitParameterInteraction()
if (gArgs.GetBoolArg("-regtest", false)) { if (gArgs.GetBoolArg("-regtest", false)) {
// we use 1MB blocks to test this on regtest // we use 1MB blocks to test this on regtest
if (nPruneTarget < 550 * 1024 * 1024) { if (nPruneTarget < 550 * 1024 * 1024) {
return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number.").translated, 550)); return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), 550));
} }
} else { } else {
if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) { if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number.").translated, MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
} }
} }
LogPrintf("Prune configured to target %u MiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024); LogPrintf("Prune configured to target %u MiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);
@ -1455,13 +1454,13 @@ bool AppInitParameterInteraction()
peer_connect_timeout = gArgs.GetArg("-peertimeout", DEFAULT_PEER_CONNECT_TIMEOUT); peer_connect_timeout = gArgs.GetArg("-peertimeout", DEFAULT_PEER_CONNECT_TIMEOUT);
if (peer_connect_timeout <= 0) { if (peer_connect_timeout <= 0) {
return InitError("peertimeout cannot be configured with a negative value."); return InitError(Untranslated("peertimeout cannot be configured with a negative value."));
} }
if (gArgs.IsArgSet("-minrelaytxfee")) { if (gArgs.IsArgSet("-minrelaytxfee")) {
CAmount n = 0; CAmount n = 0;
if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) { if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) {
return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", ""))); return InitError(Untranslated(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", ""))));
} }
// High fee check is done afterward in CWallet::CreateWalletFromFile() // High fee check is done afterward in CWallet::CreateWalletFromFile()
::minRelayTxFee = CFeeRate(n); ::minRelayTxFee = CFeeRate(n);
@ -1477,7 +1476,7 @@ bool AppInitParameterInteraction()
{ {
CAmount n = 0; CAmount n = 0;
if (!ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n)) if (!ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n))
return InitError(AmountErrMsg("blockmintxfee", gArgs.GetArg("-blockmintxfee", ""))); return InitError(Untranslated(AmountErrMsg("blockmintxfee", gArgs.GetArg("-blockmintxfee", ""))));
} }
// Feerate used to define dust. Shouldn't be changed lightly as old // Feerate used to define dust. Shouldn't be changed lightly as old
@ -1486,13 +1485,13 @@ bool AppInitParameterInteraction()
{ {
CAmount n = 0; CAmount n = 0;
if (!ParseMoney(gArgs.GetArg("-dustrelayfee", ""), n)) if (!ParseMoney(gArgs.GetArg("-dustrelayfee", ""), n))
return InitError(AmountErrMsg("dustrelayfee", gArgs.GetArg("-dustrelayfee", ""))); return InitError(Untranslated(AmountErrMsg("dustrelayfee", gArgs.GetArg("-dustrelayfee", ""))));
dustRelayFee = CFeeRate(n); dustRelayFee = CFeeRate(n);
} }
fRequireStandard = !gArgs.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard()); fRequireStandard = !gArgs.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
if (!chainparams.IsTestChain() && !fRequireStandard) { if (!chainparams.IsTestChain() && !fRequireStandard) {
return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString())); return InitError(strprintf(Untranslated("acceptnonstdtxn is not currently supported for %s chain"), chainparams.NetworkIDString()));
} }
nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp); nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp);
@ -1517,7 +1516,7 @@ bool AppInitParameterInteraction()
InitWarning("-llmq-qvvec-sync set but recovery is disabled due to -llmq-data-recovery=0"); InitWarning("-llmq-qvvec-sync set but recovery is disabled due to -llmq-data-recovery=0");
} }
} catch (const std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
return InitError(e.what()); return InitError(Untranslated(e.what()));
} }
if (gArgs.IsArgSet("-maxorphantx")) { if (gArgs.IsArgSet("-maxorphantx")) {
@ -1530,22 +1529,22 @@ bool AppInitParameterInteraction()
if (gArgs.IsArgSet("-masternodeblsprivkey")) { if (gArgs.IsArgSet("-masternodeblsprivkey")) {
if (!gArgs.GetBoolArg("-listen", DEFAULT_LISTEN) && Params().RequireRoutableExternalIP()) { if (!gArgs.GetBoolArg("-listen", DEFAULT_LISTEN) && Params().RequireRoutableExternalIP()) {
return InitError("Masternode must accept connections from outside, set -listen=1"); return InitError(Untranslated("Masternode must accept connections from outside, set -listen=1"));
} }
if (!gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (!gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
return InitError("Masternode must have transaction index enabled, set -txindex=1"); return InitError(Untranslated("Masternode must have transaction index enabled, set -txindex=1"));
} }
if (!gArgs.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) { if (!gArgs.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) {
return InitError("Masternode must have bloom filters enabled, set -peerbloomfilters=1"); return InitError(Untranslated("Masternode must have bloom filters enabled, set -peerbloomfilters=1"));
} }
if (gArgs.GetArg("-prune", 0) > 0) { if (gArgs.GetArg("-prune", 0) > 0) {
return InitError("Masternode must have no pruning enabled, set -prune=0"); return InitError(Untranslated("Masternode must have no pruning enabled, set -prune=0"));
} }
if (gArgs.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS) < DEFAULT_MAX_PEER_CONNECTIONS) { if (gArgs.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS) < DEFAULT_MAX_PEER_CONNECTIONS) {
return InitError(strprintf("Masternode must be able to handle at least %d connections, set -maxconnections=%d", DEFAULT_MAX_PEER_CONNECTIONS, DEFAULT_MAX_PEER_CONNECTIONS)); return InitError(strprintf(Untranslated("Masternode must be able to handle at least %d connections, set -maxconnections=%d"), DEFAULT_MAX_PEER_CONNECTIONS, DEFAULT_MAX_PEER_CONNECTIONS));
} }
if (gArgs.GetBoolArg("-disablegovernance", false)) { if (gArgs.GetBoolArg("-disablegovernance", false)) {
return InitError(_("You can not disable governance validation on a masternode.").translated); return InitError(_("You can not disable governance validation on a masternode."));
} }
} }
@ -1569,10 +1568,10 @@ static bool LockDataDirectory(bool probeOnly)
// Make sure only a single Dash Core process is using the data directory. // Make sure only a single Dash Core process is using the data directory.
fs::path datadir = GetDataDir(); fs::path datadir = GetDataDir();
if (!DirIsWritable(datadir)) { if (!DirIsWritable(datadir)) {
return InitError(strprintf(_("Cannot write to data directory '%s'; check permissions.").translated, datadir.string())); return InitError(strprintf(_("Cannot write to data directory '%s'; check permissions."), datadir.string()));
} }
if (!LockDirectory(datadir, ".lock", probeOnly)) { if (!LockDirectory(datadir, ".lock", probeOnly)) {
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running.").translated, datadir.string(), PACKAGE_NAME)); return InitError(strprintf(_("Cannot obtain a lock on data directory %s. %s is probably already running."), datadir.string(), PACKAGE_NAME));
} }
return true; return true;
} }
@ -1590,7 +1589,7 @@ bool AppInitSanityChecks()
// Sanity check // Sanity check
if (!InitSanityCheck()) if (!InitSanityCheck())
return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down.").translated, PACKAGE_NAME)); return InitError(strprintf(_("Initialization sanity check failed. %s is shutting down."), PACKAGE_NAME));
// Probe the data directory lock to give an early error message, if possible // Probe the data directory lock to give an early error message, if possible
// We cannot hold the data directory lock here, as the forking for daemon() hasn't yet happened, // We cannot hold the data directory lock here, as the forking for daemon() hasn't yet happened,
@ -1628,7 +1627,7 @@ bool AppInitMain(InitInterfaces& interfaces)
} }
} }
if (!LogInstance().StartLogging()) { if (!LogInstance().StartLogging()) {
return InitError(strprintf("Could not open debug log file %s", return InitError(strprintf(Untranslated("Could not open debug log file %s"),
LogInstance().m_file_path.string())); LogInstance().m_file_path.string()));
} }
@ -1690,19 +1689,19 @@ bool AppInitMain(InitInterfaces& interfaces)
} }
for (const auto& address: vSporkAddresses) { for (const auto& address: vSporkAddresses) {
if (!sporkManager.SetSporkAddress(address)) { if (!sporkManager.SetSporkAddress(address)) {
return InitError(_("Invalid spork address specified with -sporkaddr").translated); return InitError(_("Invalid spork address specified with -sporkaddr"));
} }
} }
int minsporkkeys = gArgs.GetArg("-minsporkkeys", Params().MinSporkKeys()); int minsporkkeys = gArgs.GetArg("-minsporkkeys", Params().MinSporkKeys());
if (!sporkManager.SetMinSporkKeys(minsporkkeys)) { if (!sporkManager.SetMinSporkKeys(minsporkkeys)) {
return InitError(_("Invalid minimum number of spork signers specified with -minsporkkeys").translated); return InitError(_("Invalid minimum number of spork signers specified with -minsporkkeys"));
} }
if (gArgs.IsArgSet("-sporkkey")) { // spork priv key if (gArgs.IsArgSet("-sporkkey")) { // spork priv key
if (!sporkManager.SetPrivKey(gArgs.GetArg("-sporkkey", ""))) { if (!sporkManager.SetPrivKey(gArgs.GetArg("-sporkkey", ""))) {
return InitError(_("Unable to sign spork message, wrong key?").translated); return InitError(_("Unable to sign spork message, wrong key?"));
} }
} }
@ -1742,7 +1741,7 @@ bool AppInitMain(InitInterfaces& interfaces)
{ {
uiInterface.InitMessage_connect(SetRPCWarmupStatus); uiInterface.InitMessage_connect(SetRPCWarmupStatus);
if (!AppInitServers()) if (!AppInitServers())
return InitError(_("Unable to start HTTP server. See debug log for details.").translated); return InitError(_("Unable to start HTTP server. See debug log for details."));
} }
// ********************************************************* Step 5: verify wallet database integrity // ********************************************************* Step 5: verify wallet database integrity
@ -1778,12 +1777,12 @@ bool AppInitMain(InitInterfaces& interfaces)
for (const std::string& cmt : gArgs.GetArgs("-uacomment")) { for (const std::string& cmt : gArgs.GetArgs("-uacomment")) {
if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters.").translated, cmt)); return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt));
uacomments.push_back(cmt); uacomments.push_back(cmt);
} }
strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments); strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) { if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
return InitError(strprintf(_("Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.").translated, return InitError(strprintf(_("Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments."),
strSubVersion.size(), MAX_SUBVERSION_LENGTH)); strSubVersion.size(), MAX_SUBVERSION_LENGTH));
} }
@ -1792,7 +1791,7 @@ bool AppInitMain(InitInterfaces& interfaces)
for (const std::string& snet : gArgs.GetArgs("-onlynet")) { for (const std::string& snet : gArgs.GetArgs("-onlynet")) {
enum Network net = ParseNetwork(snet); enum Network net = ParseNetwork(snet);
if (net == NET_UNROUTABLE) if (net == NET_UNROUTABLE)
return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'").translated, snet)); return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet));
nets.insert(net); nets.insert(net);
} }
for (int n = 0; n < NET_MAX; n++) { for (int n = 0; n < NET_MAX; n++) {
@ -1813,12 +1812,12 @@ bool AppInitMain(InitInterfaces& interfaces)
if (proxyArg != "" && proxyArg != "0") { if (proxyArg != "" && proxyArg != "0") {
CService proxyAddr; CService proxyAddr;
if (!Lookup(proxyArg.c_str(), proxyAddr, 9050, fNameLookup)) { if (!Lookup(proxyArg.c_str(), proxyAddr, 9050, fNameLookup)) {
return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'").translated, proxyArg)); return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg));
} }
proxyType addrProxy = proxyType(proxyAddr, proxyRandomize); proxyType addrProxy = proxyType(proxyAddr, proxyRandomize);
if (!addrProxy.IsValid()) if (!addrProxy.IsValid())
return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'").translated, proxyArg)); return InitError(strprintf(_("Invalid -proxy address or hostname: '%s'"), proxyArg));
SetProxy(NET_IPV4, addrProxy); SetProxy(NET_IPV4, addrProxy);
SetProxy(NET_IPV6, addrProxy); SetProxy(NET_IPV6, addrProxy);
@ -1837,11 +1836,11 @@ bool AppInitMain(InitInterfaces& interfaces)
} else { } else {
CService onionProxy; CService onionProxy;
if (!Lookup(onionArg.c_str(), onionProxy, 9050, fNameLookup)) { if (!Lookup(onionArg.c_str(), onionProxy, 9050, fNameLookup)) {
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'").translated, onionArg)); return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
} }
proxyType addrOnion = proxyType(onionProxy, proxyRandomize); proxyType addrOnion = proxyType(onionProxy, proxyRandomize);
if (!addrOnion.IsValid()) if (!addrOnion.IsValid())
return InitError(strprintf(_("Invalid -onion address or hostname: '%s'").translated, onionArg)); return InitError(strprintf(_("Invalid -onion address or hostname: '%s'"), onionArg));
SetProxy(NET_ONION, addrOnion); SetProxy(NET_ONION, addrOnion);
SetReachable(NET_ONION, true); SetReachable(NET_ONION, true);
} }
@ -1857,7 +1856,7 @@ bool AppInitMain(InitInterfaces& interfaces)
if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid())
AddLocal(addrLocal, LOCAL_MANUAL); AddLocal(addrLocal, LOCAL_MANUAL);
else else
return InitError(ResolveErrMsg("externalip", strAddr)); return InitError(Untranslated(ResolveErrMsg("externalip", strAddr)));
} }
// Read asmap file if configured // Read asmap file if configured
@ -1870,12 +1869,12 @@ bool AppInitMain(InitInterfaces& interfaces)
asmap_path = GetDataDir() / asmap_path; asmap_path = GetDataDir() / asmap_path;
} }
if (!fs::exists(asmap_path)) { if (!fs::exists(asmap_path)) {
InitError(strprintf(_("Could not find asmap file %s").translated, asmap_path)); InitError(strprintf(_("Could not find asmap file %s"), asmap_path));
return false; return false;
} }
std::vector<bool> asmap = CAddrMan::DecodeAsmap(asmap_path); std::vector<bool> asmap = CAddrMan::DecodeAsmap(asmap_path);
if (asmap.size() == 0) { if (asmap.size() == 0) {
InitError(strprintf(_("Could not parse asmap file %s").translated, asmap_path)); InitError(strprintf(_("Could not parse asmap file %s"), asmap_path));
return false; return false;
} }
const uint256 asmap_version = SerializeHash(asmap); const uint256 asmap_version = SerializeHash(asmap);
@ -1908,7 +1907,7 @@ bool AppInitMain(InitInterfaces& interfaces)
uiInterface.InitMessage(_("Loading sporks cache...").translated); uiInterface.InitMessage(_("Loading sporks cache...").translated);
CFlatDB<CSporkManager> flatdb6("sporks.dat", "magicSporkCache"); CFlatDB<CSporkManager> flatdb6("sporks.dat", "magicSporkCache");
if (!flatdb6.Load(sporkManager)) { if (!flatdb6.Load(sporkManager)) {
return InitError(_("Failed to load sporks cache from").translated + "\n" + (GetDataDir() / "sporks.dat").string()); return InitError(strprintf(_("Failed to load sporks cache from %s"), (GetDataDir() / "sporks.dat").string()));
} }
// ********************************************************* Step 7b: load block chain // ********************************************************* Step 7b: load block chain
@ -1953,7 +1952,7 @@ bool AppInitMain(InitInterfaces& interfaces)
while (!fLoaded && !ShutdownRequested()) { while (!fLoaded && !ShutdownRequested()) {
bool fReset = fReindex; bool fReset = fReindex;
std::string strLoadError; bilingual_str strLoadError;
uiInterface.InitMessage(_("Loading block index...").translated); uiInterface.InitMessage(_("Loading block index...").translated);
@ -1994,47 +1993,47 @@ bool AppInitMain(InitInterfaces& interfaces)
// From here on out fReindex and fReset mean something different! // From here on out fReindex and fReset mean something different!
if (!LoadBlockIndex(chainparams)) { if (!LoadBlockIndex(chainparams)) {
if (ShutdownRequested()) break; if (ShutdownRequested()) break;
strLoadError = _("Error loading block database").translated; strLoadError = _("Error loading block database");
break; break;
} }
if (!fDisableGovernance && !gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX) if (!fDisableGovernance && !gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)
&& chainparams.NetworkIDString() != CBaseChainParams::REGTEST) { // TODO remove this when pruning is fixed. See https://github.com/dashpay/dash/pull/1817 and https://github.com/dashpay/dash/pull/1743 && chainparams.NetworkIDString() != CBaseChainParams::REGTEST) { // TODO remove this when pruning is fixed. See https://github.com/dashpay/dash/pull/1817 and https://github.com/dashpay/dash/pull/1743
return InitError(_("Transaction index can't be disabled with governance validation enabled. Either start with -disablegovernance command line switch or enable transaction index.").translated); return InitError(_("Transaction index can't be disabled with governance validation enabled. Either start with -disablegovernance command line switch or enable transaction index."));
} }
// If the loaded chain has a wrong genesis, bail out immediately // If the loaded chain has a wrong genesis, bail out immediately
// (we're likely using a testnet datadir, or the other way around). // (we're likely using a testnet datadir, or the other way around).
if (!::BlockIndex().empty() && if (!::BlockIndex().empty() &&
!LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) { !LookupBlockIndex(chainparams.GetConsensus().hashGenesisBlock)) {
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?").translated); return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
} }
if (!chainparams.GetConsensus().hashDevnetGenesisBlock.IsNull() && !::BlockIndex().empty() && ::BlockIndex().count(chainparams.GetConsensus().hashDevnetGenesisBlock) == 0) if (!chainparams.GetConsensus().hashDevnetGenesisBlock.IsNull() && !::BlockIndex().empty() && ::BlockIndex().count(chainparams.GetConsensus().hashDevnetGenesisBlock) == 0)
return InitError(_("Incorrect or no devnet genesis block found. Wrong datadir for devnet specified?").translated); return InitError(_("Incorrect or no devnet genesis block found. Wrong datadir for devnet specified?"));
// Check for changed -addressindex state // Check for changed -addressindex state
if (fAddressIndex != gArgs.GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX)) { if (fAddressIndex != gArgs.GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX)) {
strLoadError = _("You need to rebuild the database using -reindex to change -addressindex").translated; strLoadError = _("You need to rebuild the database using -reindex to change -addressindex");
break; break;
} }
// Check for changed -timestampindex state // Check for changed -timestampindex state
if (fTimestampIndex != gArgs.GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX)) { if (fTimestampIndex != gArgs.GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX)) {
strLoadError = _("You need to rebuild the database using -reindex to change -timestampindex").translated; strLoadError = _("You need to rebuild the database using -reindex to change -timestampindex");
break; break;
} }
// Check for changed -spentindex state // Check for changed -spentindex state
if (fSpentIndex != gArgs.GetBoolArg("-spentindex", DEFAULT_SPENTINDEX)) { if (fSpentIndex != gArgs.GetBoolArg("-spentindex", DEFAULT_SPENTINDEX)) {
strLoadError = _("You need to rebuild the database using -reindex to change -spentindex").translated; strLoadError = _("You need to rebuild the database using -reindex to change -spentindex");
break; break;
} }
// Check for changed -prune state. What we are concerned about is a user who has pruned blocks // Check for changed -prune state. What we are concerned about is a user who has pruned blocks
// in the past, but is now trying to run unpruned. // in the past, but is now trying to run unpruned.
if (fHavePruned && !fPruneMode) { if (fHavePruned && !fPruneMode) {
strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain").translated; strLoadError = _("You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain");
break; break;
} }
@ -2043,7 +2042,7 @@ bool AppInitMain(InitInterfaces& interfaces)
// (otherwise we use the one already on disk). // (otherwise we use the one already on disk).
// This is called again in ThreadImport after the reindex completes. // This is called again in ThreadImport after the reindex completes.
if (!fReindex && !LoadGenesisBlock(chainparams)) { if (!fReindex && !LoadGenesisBlock(chainparams)) {
strLoadError = _("Error initializing block database").translated; strLoadError = _("Error initializing block database");
break; break;
} }
@ -2057,20 +2056,20 @@ bool AppInitMain(InitInterfaces& interfaces)
::ChainstateActive().CoinsErrorCatcher().AddReadErrCallback([]() { ::ChainstateActive().CoinsErrorCatcher().AddReadErrCallback([]() {
uiInterface.ThreadSafeMessageBox( uiInterface.ThreadSafeMessageBox(
_("Error reading from database, shutting down.").translated, _("Error reading from database, shutting down."),
"", CClientUIInterface::MSG_ERROR); "", CClientUIInterface::MSG_ERROR);
}); });
// If necessary, upgrade from older database format. // If necessary, upgrade from older database format.
// This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
if (!::ChainstateActive().CoinsDB().Upgrade()) { if (!::ChainstateActive().CoinsDB().Upgrade()) {
strLoadError = _("Error upgrading chainstate database").translated; strLoadError = _("Error upgrading chainstate database");
break; break;
} }
// ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
if (!::ChainstateActive().ReplayBlocks(chainparams)) { if (!::ChainstateActive().ReplayBlocks(chainparams)) {
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.").translated; strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
break; break;
} }
@ -2080,7 +2079,7 @@ bool AppInitMain(InitInterfaces& interfaces)
// flush evodb // flush evodb
if (!evoDb->CommitRootTransaction()) { if (!evoDb->CommitRootTransaction()) {
strLoadError = _("Failed to commit EvoDB").translated; strLoadError = _("Failed to commit EvoDB");
break; break;
} }
@ -2089,7 +2088,7 @@ bool AppInitMain(InitInterfaces& interfaces)
if (!is_coinsview_empty) { if (!is_coinsview_empty) {
// LoadChainTip initializes the chain based on CoinsTip()'s best block // LoadChainTip initializes the chain based on CoinsTip()'s best block
if (!::ChainstateActive().LoadChainTip(chainparams)) { if (!::ChainstateActive().LoadChainTip(chainparams)) {
strLoadError = _("Error initializing block database").translated; strLoadError = _("Error initializing block database");
break; break;
} }
assert(::ChainActive().Tip() != NULL); assert(::ChainActive().Tip() != NULL);
@ -2097,12 +2096,12 @@ bool AppInitMain(InitInterfaces& interfaces)
if (is_coinsview_empty && !evoDb->IsEmpty()) { if (is_coinsview_empty && !evoDb->IsEmpty()) {
// EvoDB processed some blocks earlier but we have no blocks anymore, something is wrong // EvoDB processed some blocks earlier but we have no blocks anymore, something is wrong
strLoadError = _("Error initializing block database").translated; strLoadError = _("Error initializing block database");
break; break;
} }
if (!deterministicMNManager->UpgradeDBIfNeeded() || !llmq::quorumBlockProcessor->UpgradeDB()) { if (!deterministicMNManager->UpgradeDBIfNeeded() || !llmq::quorumBlockProcessor->UpgradeDB()) {
strLoadError = _("Error upgrading evo database").translated; strLoadError = _("Error upgrading evo database");
break; break;
} }
@ -2118,13 +2117,13 @@ bool AppInitMain(InitInterfaces& interfaces)
if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) { if (tip && tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
strLoadError = _("The block database contains a block which appears to be from the future. " strLoadError = _("The block database contains a block which appears to be from the future. "
"This may be due to your computer's date and time being set incorrectly. " "This may be due to your computer's date and time being set incorrectly. "
"Only rebuild the block database if you are sure that your computer's date and time are correct").translated; "Only rebuild the block database if you are sure that your computer's date and time are correct");
break; break;
} }
if (!CVerifyDB().VerifyDB(chainparams, &::ChainstateActive().CoinsDB(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL), if (!CVerifyDB().VerifyDB(chainparams, &::ChainstateActive().CoinsDB(), gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) {
strLoadError = _("Corrupted block database detected").translated; strLoadError = _("Corrupted block database detected");
break; break;
} }
@ -2134,7 +2133,7 @@ bool AppInitMain(InitInterfaces& interfaces)
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
LogPrintf("%s\n", e.what()); LogPrintf("%s\n", e.what());
strLoadError = _("Error opening block database").translated; strLoadError = _("Error opening block database");
break; break;
} }
@ -2146,8 +2145,8 @@ bool AppInitMain(InitInterfaces& interfaces)
// first suggest a reindex // first suggest a reindex
if (!fReset) { if (!fReset) {
bool fRet = uiInterface.ThreadSafeQuestion( bool fRet = uiInterface.ThreadSafeQuestion(
strLoadError + ".\n\n" + _("Do you want to rebuild the block database now?").translated, strLoadError + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"),
strLoadError + ".\nPlease restart with -reindex or -reindex-chainstate to recover.", strLoadError.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT); "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
if (fRet) { if (fRet) {
fReindex = true; fReindex = true;
@ -2231,7 +2230,7 @@ bool AppInitMain(InitInterfaces& interfaces)
auto binKey = ParseHex(strMasterNodeBLSPrivKey); auto binKey = ParseHex(strMasterNodeBLSPrivKey);
CBLSSecretKey keyOperator(binKey); CBLSSecretKey keyOperator(binKey);
if (!keyOperator.IsValid()) { if (!keyOperator.IsValid()) {
return InitError(_("Invalid masternodeblsprivkey. Please see documentation.").translated); return InitError(_("Invalid masternodeblsprivkey. Please see documentation."));
} }
fMasternodeMode = true; fMasternodeMode = true;
{ {
@ -2284,12 +2283,12 @@ bool AppInitMain(InitInterfaces& interfaces)
CFlatDB<CMasternodeMetaMan> flatdb1(strDBName, "magicMasternodeCache"); CFlatDB<CMasternodeMetaMan> flatdb1(strDBName, "magicMasternodeCache");
if (fLoadCacheFiles) { if (fLoadCacheFiles) {
if(!flatdb1.Load(mmetaman)) { if(!flatdb1.Load(mmetaman)) {
return InitError(_("Failed to load masternode cache from").translated + "\n" + (pathDB / strDBName).string()); return InitError(strprintf(_("Failed to load masternode cache from %s"), (pathDB / strDBName).string()));
} }
} else { } else {
CMasternodeMetaMan mmetamanTmp; CMasternodeMetaMan mmetamanTmp;
if(!flatdb1.Dump(mmetamanTmp)) { if(!flatdb1.Dump(mmetamanTmp)) {
return InitError(_("Failed to clear masternode cache at").translated + "\n" + (pathDB / strDBName).string()); return InitError(strprintf(_("Failed to clear masternode cache at %s"), (pathDB / strDBName).string()));
} }
} }
@ -2298,13 +2297,13 @@ bool AppInitMain(InitInterfaces& interfaces)
CFlatDB<CGovernanceManager> flatdb3(strDBName, "magicGovernanceCache"); CFlatDB<CGovernanceManager> flatdb3(strDBName, "magicGovernanceCache");
if (fLoadCacheFiles && !fDisableGovernance) { if (fLoadCacheFiles && !fDisableGovernance) {
if(!flatdb3.Load(governance)) { if(!flatdb3.Load(governance)) {
return InitError(_("Failed to load governance cache from").translated + "\n" + (pathDB / strDBName).string()); return InitError(strprintf(_("Failed to load governance cache from %s"), (pathDB / strDBName).string()));
} }
governance.InitOnLoad(); governance.InitOnLoad();
} else { } else {
CGovernanceManager governanceTmp; CGovernanceManager governanceTmp;
if(!flatdb3.Dump(governanceTmp)) { if(!flatdb3.Dump(governanceTmp)) {
return InitError(_("Failed to clear governance cache at").translated + "\n" + (pathDB / strDBName).string()); return InitError(strprintf(_("Failed to clear governance cache at %s"), (pathDB / strDBName).string()));
} }
} }
@ -2313,12 +2312,12 @@ bool AppInitMain(InitInterfaces& interfaces)
CFlatDB<CNetFulfilledRequestManager> flatdb4(strDBName, "magicFulfilledCache"); CFlatDB<CNetFulfilledRequestManager> flatdb4(strDBName, "magicFulfilledCache");
if (fLoadCacheFiles) { if (fLoadCacheFiles) {
if(!flatdb4.Load(netfulfilledman)) { if(!flatdb4.Load(netfulfilledman)) {
return InitError(_("Failed to load fulfilled requests cache from").translated + "\n" + (pathDB / strDBName).string()); return InitError(strprintf(_("Failed to load fulfilled requests cache from %s"),(pathDB / strDBName).string()));
} }
} else { } else {
CNetFulfilledRequestManager netfulfilledmanTmp; CNetFulfilledRequestManager netfulfilledmanTmp;
if(!flatdb4.Dump(netfulfilledmanTmp)) { if(!flatdb4.Dump(netfulfilledmanTmp)) {
return InitError(_("Failed to clear fulfilled requests cache at").translated + "\n" + (pathDB / strDBName).string()); return InitError(strprintf(_("Failed to clear fulfilled requests cache at %s"),(pathDB / strDBName).string()));
} }
} }
@ -2347,11 +2346,11 @@ bool AppInitMain(InitInterfaces& interfaces)
// ********************************************************* Step 11: import blocks // ********************************************************* Step 11: import blocks
if (!CheckDiskSpace(GetDataDir())) { if (!CheckDiskSpace(GetDataDir())) {
InitError(strprintf(_("Error: Disk space is low for %s").translated, GetDataDir())); InitError(strprintf(_("Error: Disk space is low for %s"), GetDataDir()));
return false; return false;
} }
if (!CheckDiskSpace(GetBlocksDir())) { if (!CheckDiskSpace(GetBlocksDir())) {
InitError(strprintf(_("Error: Disk space is low for %s").translated, GetBlocksDir())); InitError(strprintf(_("Error: Disk space is low for %s"), GetBlocksDir()));
return false; return false;
} }
@ -2433,21 +2432,21 @@ bool AppInitMain(InitInterfaces& interfaces)
for (const std::string& strBind : gArgs.GetArgs("-bind")) { for (const std::string& strBind : gArgs.GetArgs("-bind")) {
CService addrBind; CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) { if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) {
return InitError(ResolveErrMsg("bind", strBind)); return InitError(Untranslated(ResolveErrMsg("bind", strBind)));
} }
connOptions.vBinds.push_back(addrBind); connOptions.vBinds.push_back(addrBind);
} }
for (const std::string& strBind : gArgs.GetArgs("-whitebind")) { for (const std::string& strBind : gArgs.GetArgs("-whitebind")) {
NetWhitebindPermissions whitebind; NetWhitebindPermissions whitebind;
std::string error; std::string error;
if (!NetWhitebindPermissions::TryParse(strBind, whitebind, error)) return InitError(error); if (!NetWhitebindPermissions::TryParse(strBind, whitebind, error)) return InitError(Untranslated(error));
connOptions.vWhiteBinds.push_back(whitebind); connOptions.vWhiteBinds.push_back(whitebind);
} }
for (const auto& net : gArgs.GetArgs("-whitelist")) { for (const auto& net : gArgs.GetArgs("-whitelist")) {
NetWhitelistPermissions subnet; NetWhitelistPermissions subnet;
std::string error; std::string error;
if (!NetWhitelistPermissions::TryParse(net, subnet, error)) return InitError(error); if (!NetWhitelistPermissions::TryParse(net, subnet, error)) return InitError(Untranslated(error));
connOptions.vWhitelistedRange.push_back(subnet); connOptions.vWhitelistedRange.push_back(subnet);
} }
@ -2478,7 +2477,7 @@ bool AppInitMain(InitInterfaces& interfaces)
connOptions.socketEventsMode = CConnman::SOCKETEVENTS_KQUEUE; connOptions.socketEventsMode = CConnman::SOCKETEVENTS_KQUEUE;
#endif #endif
} else { } else {
return InitError(strprintf(_("Invalid -socketevents ('%s') specified. Only these modes are supported: %s").translated, strSocketEventsMode, GetSupportedSocketEventsStr())); return InitError(strprintf(_("Invalid -socketevents ('%s') specified. Only these modes are supported: %s"), strSocketEventsMode, GetSupportedSocketEventsStr()));
} }
if (!g_connman->Start(scheduler, connOptions)) { if (!g_connman->Start(scheduler, connOptions)) {

View File

@ -345,7 +345,7 @@ public:
int64_t getAdjustedTime() override { return GetAdjustedTime(); } int64_t getAdjustedTime() override { return GetAdjustedTime(); }
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); } void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
void initWarning(const std::string& message) override { InitWarning(message); } void initWarning(const std::string& message) override { InitWarning(message); }
void initError(const std::string& message) override { InitError(message); } void initError(const bilingual_str& message) override { InitError(message); }
void loadWallet(std::unique_ptr<Wallet> wallet) override { ::uiInterface.LoadWallet(wallet); } void loadWallet(std::unique_ptr<Wallet> wallet) override { ::uiInterface.LoadWallet(wallet); }
void showProgress(const std::string& title, int progress, bool resume_possible) override void showProgress(const std::string& title, int progress, bool resume_possible) override
{ {

View File

@ -23,6 +23,7 @@ class CFeeRate;
class CBlockIndex; class CBlockIndex;
class Coin; class Coin;
class uint256; class uint256;
struct bilingual_str;
struct CBlockLocator; struct CBlockLocator;
struct FeeCalculation; struct FeeCalculation;
enum class MemPoolRemovalReason; enum class MemPoolRemovalReason;
@ -216,7 +217,7 @@ public:
virtual void initWarning(const std::string& message) = 0; virtual void initWarning(const std::string& message) = 0;
//! Send init error. //! Send init error.
virtual void initError(const std::string& message) = 0; virtual void initError(const bilingual_str& message) = 0;
//! Send wallet load notification to the GUI. //! Send wallet load notification to the GUI.
virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0; virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0;

View File

@ -33,6 +33,7 @@
#include <txmempool.h> #include <txmempool.h>
#include <ui_interface.h> #include <ui_interface.h>
#include <util/system.h> #include <util/system.h>
#include <util/translation.h>
#include <validation.h> #include <validation.h>
#include <warnings.h> #include <warnings.h>
@ -177,7 +178,7 @@ public:
MasternodeSyncImpl m_masternodeSync; MasternodeSyncImpl m_masternodeSync;
CoinJoinOptionsImpl m_coinjoin; CoinJoinOptionsImpl m_coinjoin;
void initError(const std::string& message) override { InitError(message); } void initError(const std::string& message) override { InitError(Untranslated(message)); }
bool parseParameters(int argc, const char* const argv[], std::string& error) override bool parseParameters(int argc, const char* const argv[], std::string& error) override
{ {
return gArgs.ParseParameters(argc, argv, error); return gArgs.ParseParameters(argc, argv, error);

View File

@ -294,11 +294,11 @@ public:
//! Register handler for message box messages. //! Register handler for message box messages.
using MessageBoxFn = using MessageBoxFn =
std::function<bool(const std::string& message, const std::string& caption, unsigned int style)>; std::function<bool(const bilingual_str& message, const std::string& caption, unsigned int style)>;
virtual std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) = 0; virtual std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) = 0;
//! Register handler for question messages. //! Register handler for question messages.
using QuestionFn = std::function<bool(const std::string& message, using QuestionFn = std::function<bool(const bilingual_str& message,
const std::string& non_interactive_message, const std::string& non_interactive_message,
const std::string& caption, const std::string& caption,
unsigned int style)>; unsigned int style)>;

View File

@ -2612,9 +2612,8 @@ void CConnman::ThreadMessageHandler()
bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, NetPermissionFlags permissions) bool CConnman::BindListenPort(const CService& addrBind, bilingual_str& strError, NetPermissionFlags permissions)
{ {
strError = "";
int nOne = 1; int nOne = 1;
// Create socket for listening for incoming connections // Create socket for listening for incoming connections
@ -2622,16 +2621,16 @@ bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, N
socklen_t len = sizeof(sockaddr); socklen_t len = sizeof(sockaddr);
if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len)) if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
{ {
strError = strprintf("Error: Bind address family for %s not supported", addrBind.ToString()); strError = strprintf(Untranslated("Error: Bind address family for %s not supported"), addrBind.ToString());
LogPrintf("%s\n", strError); LogPrintf("%s\n", strError.original);
return false; return false;
} }
SOCKET hListenSocket = CreateSocket(addrBind); SOCKET hListenSocket = CreateSocket(addrBind);
if (hListenSocket == INVALID_SOCKET) if (hListenSocket == INVALID_SOCKET)
{ {
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError())); strError = strprintf(Untranslated("Error: Couldn't open socket for incoming connections (socket returned error %s)"), NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError); LogPrintf("%s\n", strError.original);
return false; return false;
} }
@ -2655,10 +2654,10 @@ bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, N
{ {
int nErr = WSAGetLastError(); int nErr = WSAGetLastError();
if (nErr == WSAEADDRINUSE) if (nErr == WSAEADDRINUSE)
strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running.").translated, addrBind.ToString(), PACKAGE_NAME); strError = strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind.ToString(), PACKAGE_NAME);
else else
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)").translated, addrBind.ToString(), NetworkErrorString(nErr)); strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind.ToString(), NetworkErrorString(nErr));
LogPrintf("%s\n", strError); LogPrintf("%s\n", strError.original);
CloseSocket(hListenSocket); CloseSocket(hListenSocket);
return false; return false;
} }
@ -2667,8 +2666,8 @@ bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, N
// Listen for incoming connections // Listen for incoming connections
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
{ {
strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)").translated, NetworkErrorString(WSAGetLastError())); strError = strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError); LogPrintf("%s\n", strError.original);
CloseSocket(hListenSocket); CloseSocket(hListenSocket);
return false; return false;
} }
@ -2678,8 +2677,8 @@ bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, N
struct kevent event; struct kevent event;
EV_SET(&event, hListenSocket, EVFILT_READ, EV_ADD, 0, 0, nullptr); EV_SET(&event, hListenSocket, EVFILT_READ, EV_ADD, 0, 0, nullptr);
if (kevent(kqueuefd, &event, 1, nullptr, 0, nullptr) != 0) { if (kevent(kqueuefd, &event, 1, nullptr, 0, nullptr) != 0) {
strError = strprintf(_("Error: failed to add socket to kqueuefd (kevent returned error %s)").translated, NetworkErrorString(WSAGetLastError())); strError = strprintf(_("Error: failed to add socket to kqueuefd (kevent returned error %s)"), NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError); LogPrintf("%s\n", strError.original);
CloseSocket(hListenSocket); CloseSocket(hListenSocket);
return false; return false;
} }
@ -2692,8 +2691,8 @@ bool CConnman::BindListenPort(const CService& addrBind, std::string& strError, N
event.data.fd = hListenSocket; event.data.fd = hListenSocket;
event.events = EPOLLIN; event.events = EPOLLIN;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, hListenSocket, &event) != 0) { if (epoll_ctl(epollfd, EPOLL_CTL_ADD, hListenSocket, &event) != 0) {
strError = strprintf(_("Error: failed to add socket to epollfd (epoll_ctl returned error %s)").translated, NetworkErrorString(WSAGetLastError())); strError = strprintf(_("Error: failed to add socket to epollfd (epoll_ctl returned error %s)"), NetworkErrorString(WSAGetLastError()));
LogPrintf("%s\n", strError); LogPrintf("%s\n", strError.original);
CloseSocket(hListenSocket); CloseSocket(hListenSocket);
return false; return false;
} }
@ -2795,7 +2794,7 @@ NodeId CConnman::GetNewNodeId()
bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) { bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions) {
if (!(flags & BF_EXPLICIT) && !IsReachable(addr)) if (!(flags & BF_EXPLICIT) && !IsReachable(addr))
return false; return false;
std::string strError; bilingual_str strError;
if (!BindListenPort(addr, strError, permissions)) { if (!BindListenPort(addr, strError, permissions)) {
if ((flags & BF_REPORT_ERROR) && clientInterface) { if ((flags & BF_REPORT_ERROR) && clientInterface) {
clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR); clientInterface->ThreadSafeMessageBox(strError, "", CClientUIInterface::MSG_ERROR);
@ -2862,7 +2861,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) { if (fListen && !InitBinds(connOptions.vBinds, connOptions.vWhiteBinds)) {
if (clientInterface) { if (clientInterface) {
clientInterface->ThreadSafeMessageBox( clientInterface->ThreadSafeMessageBox(
_("Failed to listen on any port. Use -listen=0 if you want this.").translated, _("Failed to listen on any port. Use -listen=0 if you want this."),
"", CClientUIInterface::MSG_ERROR); "", CClientUIInterface::MSG_ERROR);
} }
return false; return false;
@ -2969,7 +2968,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) { if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
if (clientInterface) { if (clientInterface) {
clientInterface->ThreadSafeMessageBox( clientInterface->ThreadSafeMessageBox(
_("Cannot provide specific connections and have addrman find outgoing connections at the same.").translated, _("Cannot provide specific connections and have addrman find outgoing connections at the same."),
"", CClientUIInterface::MSG_ERROR); "", CClientUIInterface::MSG_ERROR);
} }
return false; return false;

View File

@ -22,9 +22,9 @@
#include <saltedhasher.h> #include <saltedhasher.h>
#include <streams.h> #include <streams.h>
#include <sync.h> #include <sync.h>
#include <threadinterrupt.h>
#include <uint256.h> #include <uint256.h>
#include <util/system.h> #include <util/system.h>
#include <threadinterrupt.h>
#include <consensus/params.h> #include <consensus/params.h>
#include <atomic> #include <atomic>
@ -48,6 +48,7 @@
class CScheduler; class CScheduler;
class CNode; class CNode;
class BanMan; class BanMan;
struct bilingual_str;
/** Default for -whitelistrelay. */ /** Default for -whitelistrelay. */
static const bool DEFAULT_WHITELISTRELAY = true; static const bool DEFAULT_WHITELISTRELAY = true;
@ -483,7 +484,7 @@ private:
NetPermissionFlags m_permissions; NetPermissionFlags m_permissions;
}; };
bool BindListenPort(const CService& bindAddr, std::string& strError, NetPermissionFlags permissions); bool BindListenPort(const CService& bindAddr, bilingual_str& strError, NetPermissionFlags permissions);
bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions); bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions);
bool InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds); bool InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds);
void ThreadOpenAddedConnections(); void ThreadOpenAddedConnections();

View File

@ -6,8 +6,9 @@
#include <noui.h> #include <noui.h>
#include <logging.h>
#include <ui_interface.h> #include <ui_interface.h>
#include <util/system.h> #include <util/translation.h>
#include <string> #include <string>
@ -18,7 +19,7 @@ boost::signals2::connection noui_ThreadSafeMessageBoxConn;
boost::signals2::connection noui_ThreadSafeQuestionConn; boost::signals2::connection noui_ThreadSafeQuestionConn;
boost::signals2::connection noui_InitMessageConn; boost::signals2::connection noui_InitMessageConn;
bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) bool noui_ThreadSafeMessageBox(const bilingual_str& message, const std::string& caption, unsigned int style)
{ {
bool fSecure = style & CClientUIInterface::SECURE; bool fSecure = style & CClientUIInterface::SECURE;
style &= ~CClientUIInterface::SECURE; style &= ~CClientUIInterface::SECURE;
@ -43,15 +44,15 @@ bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& ca
} }
if (!fSecure) { if (!fSecure) {
LogPrintf("%s%s\n", strCaption, message); LogPrintf("%s%s\n", strCaption, message.original);
} }
tfm::format(std::cerr, "%s%s\n", strCaption, message); tfm::format(std::cerr, "%s%s\n", strCaption, message.original);
return false; return false;
} }
bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) bool noui_ThreadSafeQuestion(const bilingual_str& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
{ {
return noui_ThreadSafeMessageBox(message, caption, style); return noui_ThreadSafeMessageBox(Untranslated(message), caption, style);
} }
void noui_InitMessage(const std::string& message) void noui_InitMessage(const std::string& message)
@ -66,13 +67,13 @@ void noui_connect()
noui_InitMessageConn = uiInterface.InitMessage_connect(noui_InitMessage); noui_InitMessageConn = uiInterface.InitMessage_connect(noui_InitMessage);
} }
bool noui_ThreadSafeMessageBoxRedirect(const std::string& message, const std::string& caption, unsigned int style) bool noui_ThreadSafeMessageBoxRedirect(const bilingual_str& message, const std::string& caption, unsigned int style)
{ {
LogPrintf("%s: %s\n", caption, message); LogPrintf("%s: %s\n", caption, message.original);
return false; return false;
} }
bool noui_ThreadSafeQuestionRedirect(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style) bool noui_ThreadSafeQuestionRedirect(const bilingual_str& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
{ {
LogPrintf("%s: %s\n", caption, message); LogPrintf("%s: %s\n", caption, message);
return false; return false;

View File

@ -7,10 +7,12 @@
#include <string> #include <string>
struct bilingual_str;
/** Non-GUI handler, which logs and prints messages. */ /** Non-GUI handler, which logs and prints messages. */
bool noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style); bool noui_ThreadSafeMessageBox(const bilingual_str& message, const std::string& caption, unsigned int style);
/** Non-GUI handler, which logs and prints questions. */ /** Non-GUI handler, which logs and prints questions. */
bool noui_ThreadSafeQuestion(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style); bool noui_ThreadSafeQuestion(const bilingual_str& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style);
/** Non-GUI handler, which only logs a message. */ /** Non-GUI handler, which only logs a message. */
void noui_InitMessage(const std::string& message); void noui_InitMessage(const std::string& message);

View File

@ -38,6 +38,7 @@
#include <qt/masternodelist.h> #include <qt/masternodelist.h>
#include <ui_interface.h> #include <ui_interface.h>
#include <util/system.h> #include <util/system.h>
#include <util/translation.h>
#include <QAction> #include <QAction>
#include <QApplication> #include <QApplication>
@ -1494,7 +1495,7 @@ void BitcoinGUI::setAdditionalDataSyncProgress(double nSyncProgress)
progressBar->setToolTip(tooltip); progressBar->setToolTip(tooltip);
} }
void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret) void BitcoinGUI::message(const QString& title, QString message, unsigned int style, bool* ret, const QString& detailed_message)
{ {
// Default title. On macOS, the window title is ignored (as required by the macOS Guidelines). // Default title. On macOS, the window title is ignored (as required by the macOS Guidelines).
QString strTitle{PACKAGE_NAME}; QString strTitle{PACKAGE_NAME};
@ -1548,6 +1549,7 @@ void BitcoinGUI::message(const QString& title, QString message, unsigned int sty
showNormalIfMinimized(); showNormalIfMinimized();
QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this); QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this);
mBox.setTextFormat(Qt::PlainText); mBox.setTextFormat(Qt::PlainText);
mBox.setDetailedText(detailed_message);
int r = mBox.exec(); int r = mBox.exec();
if (ret != nullptr) if (ret != nullptr)
*ret = r == QMessageBox::Ok; *ret = r == QMessageBox::Ok;
@ -1925,20 +1927,27 @@ void BitcoinGUI::showModalOverlay()
modalOverlay->toggleVisibility(); modalOverlay->toggleVisibility();
} }
static bool ThreadSafeMessageBox(BitcoinGUI* gui, const std::string& message, const std::string& caption, unsigned int style) static bool ThreadSafeMessageBox(BitcoinGUI* gui, const bilingual_str& message, const std::string& caption, unsigned int style)
{ {
bool modal = (style & CClientUIInterface::MODAL); bool modal = (style & CClientUIInterface::MODAL);
// The SECURE flag has no effect in the Qt GUI. // The SECURE flag has no effect in the Qt GUI.
// bool secure = (style & CClientUIInterface::SECURE); // bool secure = (style & CClientUIInterface::SECURE);
style &= ~CClientUIInterface::SECURE; style &= ~CClientUIInterface::SECURE;
bool ret = false; bool ret = false;
QString detailed_message; // This is original message, in English, for googling and referencing.
if (message.original != message.translated) {
detailed_message = BitcoinGUI::tr("Original message:") + "\n" + QString::fromStdString(message.original);
}
// In case of modal message, use blocking connection to wait for user to click a button // In case of modal message, use blocking connection to wait for user to click a button
bool invoked = QMetaObject::invokeMethod(gui, "message", bool invoked = QMetaObject::invokeMethod(gui, "message",
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection, modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(caption)), Q_ARG(QString, QString::fromStdString(caption)),
Q_ARG(QString, QString::fromStdString(message)), Q_ARG(QString, QString::fromStdString(message.translated)),
Q_ARG(unsigned int, style), Q_ARG(unsigned int, style),
Q_ARG(bool*, &ret)); Q_ARG(bool*, &ret),
Q_ARG(QString, detailed_message));
assert(invoked); assert(invoked);
return ret; return ret;
} }

View File

@ -257,13 +257,14 @@ public Q_SLOTS:
void setAdditionalDataSyncProgress(double nSyncProgress); void setAdditionalDataSyncProgress(double nSyncProgress);
/** Notify the user of an event from the core network or transaction handling code. /** Notify the user of an event from the core network or transaction handling code.
@param[in] title the message box / notification title @param[in] title the message box / notification title
@param[in] message the displayed text @param[in] message the displayed text
@param[in] style modality and style definitions (icon and used buttons - buttons only for message boxes) @param[in] style modality and style definitions (icon and used buttons - buttons only for message boxes)
@see CClientUIInterface::MessageBoxFlags @see CClientUIInterface::MessageBoxFlags
@param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only) @param[in] ret pointer to a bool that will be modified to whether Ok was clicked (modal only)
@param[in] detailed_message the text to be displayed in the details area
*/ */
void message(const QString& title, QString message, unsigned int style, bool* ret = nullptr); void message(const QString& title, QString message, unsigned int style, bool* ret = nullptr, const QString& detailed_message = QString());
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
void setCurrentWallet(WalletModel* wallet_model); void setCurrentWallet(WalletModel* wallet_model);

View File

@ -101,8 +101,8 @@ void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
if (!fMatch) if (!fMatch)
{ {
fDone = true; fDone = true;
std::string strMessage = strprintf(_("Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly.").translated, PACKAGE_NAME); bilingual_str strMessage = strprintf(_("Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly."), PACKAGE_NAME);
SetMiscWarning(strMessage); SetMiscWarning(strMessage.translated);
uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING);
} }
} }

View File

@ -4,6 +4,8 @@
#include <ui_interface.h> #include <ui_interface.h>
#include <util/translation.h>
#include <boost/signals2/last_value.hpp> #include <boost/signals2/last_value.hpp>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
@ -48,8 +50,8 @@ ADD_SIGNALS_IMPL_WRAPPER(NotifyMasternodeListChanged);
ADD_SIGNALS_IMPL_WRAPPER(NotifyAdditionalDataSyncProgressChanged); ADD_SIGNALS_IMPL_WRAPPER(NotifyAdditionalDataSyncProgressChanged);
ADD_SIGNALS_IMPL_WRAPPER(BannedListChanged); ADD_SIGNALS_IMPL_WRAPPER(BannedListChanged);
bool CClientUIInterface::ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style) { return g_ui_signals.ThreadSafeMessageBox(message, caption, style); } bool CClientUIInterface::ThreadSafeMessageBox(const bilingual_str& message, const std::string& caption, unsigned int style) { return g_ui_signals.ThreadSafeMessageBox(message, caption, style); }
bool CClientUIInterface::ThreadSafeQuestion(const std::string& message, const std::string& non_interactive_message, const std::string& caption, unsigned int style) { return g_ui_signals.ThreadSafeQuestion(message, non_interactive_message, caption, style); } bool CClientUIInterface::ThreadSafeQuestion(const bilingual_str& message, const std::string& non_interactive_message, const std::string& caption, unsigned int style) { return g_ui_signals.ThreadSafeQuestion(message, non_interactive_message, caption, style); }
void CClientUIInterface::InitMessage(const std::string& message) { return g_ui_signals.InitMessage(message); } void CClientUIInterface::InitMessage(const std::string& message) { return g_ui_signals.InitMessage(message); }
void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); } void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); }
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); } void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
@ -63,8 +65,7 @@ void CClientUIInterface::NotifyMasternodeListChanged(const CDeterministicMNList&
void CClientUIInterface::NotifyAdditionalDataSyncProgressChanged(double nSyncProgress) { return g_ui_signals.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); } void CClientUIInterface::NotifyAdditionalDataSyncProgressChanged(double nSyncProgress) { return g_ui_signals.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); }
void CClientUIInterface::BannedListChanged() { return g_ui_signals.BannedListChanged(); } void CClientUIInterface::BannedListChanged() { return g_ui_signals.BannedListChanged(); }
bool InitError(const bilingual_str& str)
bool InitError(const std::string& str)
{ {
uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR); uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
return false; return false;
@ -72,5 +73,5 @@ bool InitError(const std::string& str)
void InitWarning(const std::string& str) void InitWarning(const std::string& str)
{ {
uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING); uiInterface.ThreadSafeMessageBox(Untranslated(str), "", CClientUIInterface::MSG_WARNING);
} }

View File

@ -11,7 +11,10 @@
#include <string> #include <string>
class CBlockIndex; class CBlockIndex;
struct bilingual_str;
class CDeterministicMNList; class CDeterministicMNList;
namespace boost { namespace boost {
namespace signals2 { namespace signals2 {
class connection; class connection;
@ -87,10 +90,10 @@ public:
boost::signals2::connection signal_name##_connect(std::function<signal_name##Sig> fn); boost::signals2::connection signal_name##_connect(std::function<signal_name##Sig> fn);
/** Show message box. */ /** Show message box. */
ADD_SIGNALS_DECL_WRAPPER(ThreadSafeMessageBox, bool, const std::string& message, const std::string& caption, unsigned int style); ADD_SIGNALS_DECL_WRAPPER(ThreadSafeMessageBox, bool, const bilingual_str& message, const std::string& caption, unsigned int style);
/** If possible, ask the user a question. If not, falls back to ThreadSafeMessageBox(noninteractive_message, caption, style) and returns false. */ /** If possible, ask the user a question. If not, falls back to ThreadSafeMessageBox(noninteractive_message, caption, style) and returns false. */
ADD_SIGNALS_DECL_WRAPPER(ThreadSafeQuestion, bool, const std::string& message, const std::string& noninteractive_message, const std::string& caption, unsigned int style); ADD_SIGNALS_DECL_WRAPPER(ThreadSafeQuestion, bool, const bilingual_str& message, const std::string& noninteractive_message, const std::string& caption, unsigned int style);
/** Progress message during initialization. */ /** Progress message during initialization. */
ADD_SIGNALS_DECL_WRAPPER(InitMessage, void, const std::string& message); ADD_SIGNALS_DECL_WRAPPER(InitMessage, void, const std::string& message);
@ -135,10 +138,11 @@ public:
}; };
/** Show warning message **/ /** Show warning message **/
// TODO: InitWarning() should take a bilingual_str parameter.
void InitWarning(const std::string& str); void InitWarning(const std::string& str);
/** Show error message **/ /** Show error message **/
bool InitError(const std::string& str); bool InitError(const bilingual_str& str);
extern CClientUIInterface uiInterface; extern CClientUIInterface uiInterface;

View File

@ -27,11 +27,11 @@ inline bilingual_str operator+(const bilingual_str& lhs, const bilingual_str& rh
} }
/** Mark a bilingual_str as untranslated */ /** Mark a bilingual_str as untranslated */
inline static bilingual_str Untranslated(std::string original) { return {original, original}; } inline bilingual_str Untranslated(std::string original) { return {original, original}; }
/** Unary operator to return the original */ /** Unary operator to return the original */
inline static std::string OpOriginal(const bilingual_str& b) { return b.original; } inline std::string OpOriginal(const bilingual_str& b) { return b.original; }
/** Unary operator to return the translation */ /** Unary operator to return the translation */
inline static std::string OpTranslated(const bilingual_str& b) { return b.translated; } inline std::string OpTranslated(const bilingual_str& b) { return b.translated; }
namespace tinyformat { namespace tinyformat {
template <typename... Args> template <typename... Args>

View File

@ -1574,14 +1574,15 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
} }
/** Abort with a message */ /** Abort with a message */
// TODO: AbortNode() should take bilingual_str userMessage parameter.
static bool AbortNode(const std::string& strMessage, const std::string& userMessage = "", unsigned int prefix = 0) static bool AbortNode(const std::string& strMessage, const std::string& userMessage = "", unsigned int prefix = 0)
{ {
SetMiscWarning(strMessage); SetMiscWarning(strMessage);
LogPrintf("*** %s\n", strMessage); LogPrintf("*** %s\n", strMessage);
if (!userMessage.empty()) { if (!userMessage.empty()) {
uiInterface.ThreadSafeMessageBox(userMessage, "", CClientUIInterface::MSG_ERROR | prefix); uiInterface.ThreadSafeMessageBox(Untranslated(userMessage), "", CClientUIInterface::MSG_ERROR | prefix);
} else { } else {
uiInterface.ThreadSafeMessageBox(_("Error: A fatal internal error occurred, see debug.log for details").translated, "", CClientUIInterface::MSG_ERROR | CClientUIInterface::MSG_NOPREFIX); uiInterface.ThreadSafeMessageBox(_("Error: A fatal internal error occurred, see debug.log for details"), "", CClientUIInterface::MSG_ERROR | CClientUIInterface::MSG_NOPREFIX);
} }
StartShutdown(); StartShutdown();
return false; return false;

View File

@ -102,7 +102,7 @@ bool WalletInit::ParameterInteraction() const
return true; return true;
} else if (gArgs.IsArgSet("-masternodeblsprivkey")) { } else if (gArgs.IsArgSet("-masternodeblsprivkey")) {
return InitError(_("You can not start a masternode with wallet enabled.").translated); return InitError(_("You can not start a masternode with wallet enabled."));
} }
const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1;
@ -120,7 +120,7 @@ bool WalletInit::ParameterInteraction() const
// -zapwallettxes implies a rescan // -zapwallettxes implies a rescan
if (zapwallettxes) { if (zapwallettxes) {
if (is_multiwallet) { if (is_multiwallet) {
return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes")); return InitError(strprintf(Untranslated("%s is only allowed with a single wallet file"), "-zapwallettxes"));
} }
if (gArgs.SoftSetBoolArg("-rescan", true)) { if (gArgs.SoftSetBoolArg("-rescan", true)) {
LogPrintf("%s: parameter interaction: -zapwallettxes enabled -> setting -rescan=1\n", __func__); LogPrintf("%s: parameter interaction: -zapwallettxes enabled -> setting -rescan=1\n", __func__);
@ -136,14 +136,14 @@ bool WalletInit::ParameterInteraction() const
if (is_multiwallet) { if (is_multiwallet) {
if (gArgs.GetBoolArg("-upgradewallet", false)) { if (gArgs.GetBoolArg("-upgradewallet", false)) {
return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet")); return InitError(strprintf(_("%s is only allowed with a single wallet file"), "-upgradewallet"));
} }
} }
if (gArgs.GetBoolArg("-sysperms", false)) if (gArgs.GetBoolArg("-sysperms", false))
return InitError("-sysperms is not allowed in combination with enabled wallet functionality"); return InitError(Untranslated("-sysperms is not allowed in combination with enabled wallet functionality"));
if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false)) if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false))
return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.").translated); return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again."));
if (gArgs.IsArgSet("-walletbackupsdir")) { if (gArgs.IsArgSet("-walletbackupsdir")) {
if (!fs::is_directory(gArgs.GetArg("-walletbackupsdir", ""))) { if (!fs::is_directory(gArgs.GetArg("-walletbackupsdir", ""))) {
@ -226,7 +226,7 @@ bool WalletInit::ParameterInteraction() const
// end PrivateSend -> CoinJoin migration // end PrivateSend -> CoinJoin migration
if (gArgs.GetArg("-coinjoindenomshardcap", DEFAULT_COINJOIN_DENOMS_HARDCAP) < gArgs.GetArg("-coinjoindenomsgoal", DEFAULT_COINJOIN_DENOMS_GOAL)) { if (gArgs.GetArg("-coinjoindenomshardcap", DEFAULT_COINJOIN_DENOMS_HARDCAP) < gArgs.GetArg("-coinjoindenomsgoal", DEFAULT_COINJOIN_DENOMS_GOAL)) {
return InitError(strprintf(_("%s can't be lower than %s").translated, "-coinjoindenomshardcap", "-coinjoindenomsgoal")); return InitError(strprintf(_("%s can't be lower than %s"), "-coinjoindenomshardcap", "-coinjoindenomsgoal"));
} }
return true; return true;

View File

@ -23,14 +23,14 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
// The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory // The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error); fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
if (error || !fs::exists(wallet_dir)) { if (error || !fs::exists(wallet_dir)) {
chain.initError(strprintf(_("Specified -walletdir \"%s\" does not exist").translated, wallet_dir.string())); chain.initError(strprintf(_("Specified -walletdir \"%s\" does not exist"), wallet_dir.string()));
return false; return false;
} else if (!fs::is_directory(wallet_dir)) { } else if (!fs::is_directory(wallet_dir)) {
chain.initError(strprintf(_("Specified -walletdir \"%s\" is not a directory").translated, wallet_dir.string())); chain.initError(strprintf(_("Specified -walletdir \"%s\" is not a directory"), wallet_dir.string()));
return false; return false;
// The canonical path transforms relative paths into absolute ones, so we check the non-canonical version // The canonical path transforms relative paths into absolute ones, so we check the non-canonical version
} else if (!wallet_dir.is_absolute()) { } else if (!wallet_dir.is_absolute()) {
chain.initError(strprintf(_("Specified -walletdir \"%s\" is a relative path").translated, wallet_dir.string())); chain.initError(strprintf(_("Specified -walletdir \"%s\" is a relative path"), wallet_dir.string()));
return false; return false;
} }
gArgs.ForceSetArg("-walletdir", canonical_wallet_dir.string()); gArgs.ForceSetArg("-walletdir", canonical_wallet_dir.string());
@ -47,7 +47,7 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
WalletLocation location(wallet_file); WalletLocation location(wallet_file);
if (!wallet_paths.insert(location.GetPath()).second) { if (!wallet_paths.insert(location.GetPath()).second) {
chain.initError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified.").translated, wallet_file)); chain.initError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), wallet_file));
return false; return false;
} }
@ -56,7 +56,7 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
bool verify_success = CWallet::Verify(chain, location, error_string, warnings); bool verify_success = CWallet::Verify(chain, location, error_string, warnings);
if (!warnings.empty()) chain.initWarning(Join(warnings, "\n", OpTranslated)); if (!warnings.empty()) chain.initWarning(Join(warnings, "\n", OpTranslated));
if (!verify_success) { if (!verify_success) {
chain.initError(error_string.translated); chain.initError(error_string);
return false; return false;
} }
} }
@ -72,7 +72,7 @@ bool LoadWallets(interfaces::Chain& chain, const std::vector<std::string>& walle
std::shared_ptr<CWallet> pwallet = CWallet::CreateWalletFromFile(chain, WalletLocation(walletFile), error_string, warnings); std::shared_ptr<CWallet> pwallet = CWallet::CreateWalletFromFile(chain, WalletLocation(walletFile), error_string, warnings);
if (!warnings.empty()) chain.initWarning(Join(warnings, "\n", OpTranslated)); if (!warnings.empty()) chain.initWarning(Join(warnings, "\n", OpTranslated));
if (!pwallet) { if (!pwallet) {
chain.initError(error_string.translated); chain.initError(error_string);
return false; return false;
} }
} }