From 3daeb28c12db08513da007ac3992cc75f0be8d68 Mon Sep 17 00:00:00 2001 From: Pasta Date: Fri, 22 Oct 2021 00:16:44 -0400 Subject: [PATCH 1/5] Merge #14734: fix an undefined behavior in uint::SetHex 0f459d868d85053f1cc066ea9099793f88cbd655 fix an undefined behavior in uint::SetHex (Kaz Wesley) Pull request description: Decrementing psz beyond the beginning of the string is UB, even though the out-of-bounds pointer is never dereferenced. I don't think any clang sanitizer covers this, so I don't see any way a test could catch the original behavior. ACKs for top commit: promag: utACK 0f459d8. l2a5b1: utACK 0f459d868d85053f1cc066ea9099793f88cbd655 Tree-SHA512: 388223254ea6e955f643d2ebdf74d15a3d494e9f0597d9f05987ebb708d7a1cc06ce64bd25d447d75b5f5561bdae9630dcf25adb7bd75f7a382298b95d127162 # Conflicts: # src/uint256.cpp --- src/uint256.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/uint256.cpp b/src/uint256.cpp index 2872901a6523..7fdaf34b722b 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -41,16 +41,15 @@ void base_blob::SetHex(const char* psz) psz += 2; // hex string to uint - const char* pbegin = psz; - while (::HexDigit(*psz) != -1) - psz++; - psz--; + size_t digits = 0; + while (::HexDigit(psz[digits]) != -1) + digits++; unsigned char* p1 = (unsigned char*)m_data; unsigned char* pend = p1 + WIDTH; - while (psz >= pbegin && p1 < pend) { - *p1 = ::HexDigit(*psz--); - if (psz >= pbegin) { - *p1 |= ((unsigned char)::HexDigit(*psz--) << 4); + while (digits > 0 && p1 < pend) { + *p1 = ::HexDigit(psz[--digits]); + if (digits > 0) { + *p1 |= ((unsigned char)::HexDigit(psz[--digits]) << 4); p1++; } } From 56251ec35da0715fae77568040dc68bec064ced0 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 5 Jul 2019 17:21:42 +0200 Subject: [PATCH 2/5] Merge #15457: Check std::system for -[alert|block|wallet]notify f874e14cd3c84cd412bd3fb42b3ee1706ca6a267 [build]: check std::system for -[alert|block|wallet]notify (Sjors Provoost) cc3ad56ff2bc2583fe68c4a9e0b41072a47c0b07 [build] MSVC: set HAVE_SYSTEM for desktop apps (Sjors Provoost) c1c91bb78d7267f01ee3a3c156c218b46a92cd39 [build] detect std::system or ::wsystem (Sjors Provoost) Pull request description: Platforms such as iOs and Universal Windows Platform do not support launching a process through system(). ACKs for top commit: laanwj: code review ACK f874e14cd3c84cd412bd3fb42b3ee1706ca6a267 Tree-SHA512: 16bb4a8fa1896046ccb22a46c8985e1aa45f5b11ecf5539eb2299e9a58f1a5b085c0c12cb6939c7493d93abce7e84fadcbfc73374c887db63da6d00c08aa476d # Conflicts: # build_msvc/bitcoin_config.h # src/init.cpp # src/wallet/init.cpp --- configure.ac | 23 +++++++++++++++++++++++ src/init.cpp | 8 ++++++++ src/util/system.cpp | 2 ++ src/util/system.h | 2 ++ src/validation.cpp | 2 ++ src/wallet/init.cpp | 2 ++ src/wallet/wallet.cpp | 2 ++ 7 files changed, 41 insertions(+) diff --git a/configure.ac b/configure.ac index 7a373f8e28eb..ad7707bdf0f0 100644 --- a/configure.ac +++ b/configure.ac @@ -1091,6 +1091,29 @@ if test x$use_reduce_exports = xyes; then [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi +AC_MSG_CHECKING([for std::system]) +AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( + [[ #include ]], + [[ int nErr = std::system(""); ]] + )], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STD__SYSTEM, 1, Define to 1 if you have the `std::system' function.)], + [ AC_MSG_RESULT(no) ] +) + +AC_MSG_CHECKING([for ::_wsystem]) +AC_LINK_IFELSE( + [ AC_LANG_PROGRAM( + [[ ]], + [[ int nErr = ::_wsystem(""); ]] + )], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_WSYSTEM, 1, Define to 1 if you have the `::wsystem' function.)], + [ AC_MSG_RESULT(no) ] +) + +# Define to 1 if std::system or ::wsystem (Windows) is available +AC_DEFINE([HAVE_SYSTEM], [HAVE_STD__SYSTEM || HAVE_WSYSTEM], [std::system or ::wsystem]) + LEVELDB_CPPFLAGS= LIBLEVELDB= LIBMEMENV= diff --git a/src/init.cpp b/src/init.cpp index d837a483e5e1..baefdb49ac03 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -492,10 +492,14 @@ void SetupServerArgs() // Set all of the args and their help // When adding new options to the categories, please keep and ensure alphabetical ordering. gArgs.AddArg("-?", "Print this help message and exit", false, OptionsCategory::OPTIONS); +#if defined(HAVE_SYSTEM) gArgs.AddArg("-alertnotify=", "Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)", false, OptionsCategory::OPTIONS); +#endif gArgs.AddArg("-assumevalid=", strprintf("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)", defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnetChainParams->GetConsensus().defaultAssumeValid.GetHex()), false, OptionsCategory::OPTIONS); gArgs.AddArg("-blocksdir=", "Specify directory to hold blocks subdirectory for *.dat files (default: )", false, OptionsCategory::OPTIONS); +#if defined(HAVE_SYSTEM) gArgs.AddArg("-blocknotify=", "Execute command when the best block changes (%s in cmd is replaced by block hash)", false, OptionsCategory::OPTIONS); +#endif gArgs.AddArg("-blockreconstructionextratxn=", strprintf("Extra transactions to keep in memory for compact block reconstructions (default: %u)", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN), false, OptionsCategory::OPTIONS); gArgs.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Transactions from the wallet or RPC are not affected. (default: %u)", DEFAULT_BLOCKSONLY), false, OptionsCategory::OPTIONS); gArgs.AddArg("-conf=", strprintf("Specify configuration file. Relative paths will be prefixed by datadir location. (default: %s)", BITCOIN_CONF_FILENAME), false, OptionsCategory::OPTIONS); @@ -784,6 +788,7 @@ std::string LicenseInfo() "\n"; } +#if defined(HAVE_SYSTEM) static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex) { if (initialSync || !pBlockIndex) @@ -796,6 +801,7 @@ static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex t.detach(); // thread runs free } } +#endif static bool fHaveGenesis = false; static Mutex g_genesis_wait_mutex; @@ -2388,8 +2394,10 @@ bool AppInitMain(InitInterfaces& interfaces) fHaveGenesis = true; } +#if defined(HAVE_SYSTEM) if (gArgs.IsArgSet("-blocknotify")) uiInterface.NotifyBlockTip_connect(BlockNotifyCallback); +#endif std::vector vImportFiles; for (const std::string& strFile : gArgs.GetArgs("-loadblock")) { diff --git a/src/util/system.cpp b/src/util/system.cpp index 551c41ea868f..1f77de8b53b5 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -1205,6 +1205,7 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate) } #endif +#if defined(HAVE_SYSTEM) void runCommand(const std::string& strCommand) { if (strCommand.empty()) return; @@ -1216,6 +1217,7 @@ void runCommand(const std::string& strCommand) if (nErr) LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr); } +#endif void RenameThreadPool(ctpl::thread_pool& tp, const char* baseName) { diff --git a/src/util/system.h b/src/util/system.h index de58651f0fa1..eefbceae5354 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -112,7 +112,9 @@ fs::path GetConfigFile(const std::string& confPath); #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif +#if defined(HAVE_SYSTEM) void runCommand(const std::string& strCommand); +#endif /** * Most paths passed as configuration arguments are treated as relative to diff --git a/src/validation.cpp b/src/validation.cpp index 6d281e53b513..7f6cad90ce81 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1278,6 +1278,7 @@ CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); +#if defined(HAVE_SYSTEM) std::string strCmd = gArgs.GetArg("-alertnotify", ""); if (strCmd.empty()) return; @@ -1291,6 +1292,7 @@ static void AlertNotify(const std::string& strMessage) std::thread t(runCommand, strCmd); t.detach(); // thread runs free +#endif } static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main) diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 23e6ec48f46b..96e0b36b4d8b 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -62,7 +62,9 @@ void WalletInit::AddWalletOptions() const gArgs.AddArg("-walletbackupsdir=", "Specify full path to directory for automatic wallet backups (must exist)", false, OptionsCategory::WALLET); gArgs.AddArg("-walletbroadcast", strprintf("Make the wallet broadcast transactions (default: %u)", DEFAULT_WALLETBROADCAST), false, OptionsCategory::WALLET); gArgs.AddArg("-walletdir=", "Specify directory to hold wallets (default: /wallets if it exists, otherwise )", false, OptionsCategory::WALLET); +#if defined(HAVE_SYSTEM) gArgs.AddArg("-walletnotify=", "Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)", false, OptionsCategory::WALLET); +#endif gArgs.AddArg("-zapwallettxes=", "Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup" " (1 = keep tx meta data e.g. payment request information, 2 = drop tx meta data)", false, OptionsCategory::WALLET); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 80d7d6642b52..b1fe4987d7d5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1125,6 +1125,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) // Notify UI of new or updated transaction NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); +#if defined(HAVE_SYSTEM) // notify an external script when a wallet transaction comes in or is updated std::string strCmd = gArgs.GetArg("-walletnotify", ""); @@ -1134,6 +1135,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) std::thread t(runCommand, strCmd); t.detach(); // thread runs free } +#endif fAnonymizableTallyCached = false; fAnonymizableTallyCachedNonDenom = false; From 79e5eb8a63b69444e49ec003b048fb484f96fa4d Mon Sep 17 00:00:00 2001 From: fanquake Date: Sun, 7 Jul 2019 10:35:15 +0800 Subject: [PATCH 3/5] Merge #16344: build: use #if HAVE_SYSTEM instead of defined(HAVE_SYSTEM) 976b034b13d28877aee641833d5ee28a8cc5d83f [build]: use #if HAVE_SYSTEM instead of defined(HAVE_SYSTEM) (Sjors Provoost) Pull request description: It seems that `AC_DEFINE([HAVE_SYSTEM], [HAVE_STD__SYSTEM || HAVE_WSYSTEM]` causes `HAVE_SYSTEM` to always be defined, so we need to use `#if HAVE_SYSTEM` instead of `#if defined(HAVE_SYSTEM)`. Followup for #15457, can be tested with #12557. ACKs for top commit: dongcarl: ACK https://github.com/bitcoin/bitcoin/pull/16344/commits/976b034b13d28877aee641833d5ee28a8cc5d83f. promag: ACK 976b034b13d28877aee641833d5ee28a8cc5d83f. fanquake: ACK 976b034b13d28877aee641833d5ee28a8cc5d83f Tree-SHA512: b8cdd04c2ec399fd15638aef5d75ea0886ec1572d3cf4fcea27c193e1e6390344315908262cad8981a9b0a905ab9520619ce2ffe9a717f4ee6bfa8b028ebbdc6 # Conflicts: # src/init.cpp --- src/init.cpp | 8 ++++---- src/util/system.cpp | 2 +- src/util/system.h | 2 +- src/validation.cpp | 2 +- src/wallet/init.cpp | 2 +- src/wallet/wallet.cpp | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index baefdb49ac03..225fae676968 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -492,12 +492,12 @@ void SetupServerArgs() // Set all of the args and their help // When adding new options to the categories, please keep and ensure alphabetical ordering. gArgs.AddArg("-?", "Print this help message and exit", false, OptionsCategory::OPTIONS); -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM gArgs.AddArg("-alertnotify=", "Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message)", false, OptionsCategory::OPTIONS); #endif gArgs.AddArg("-assumevalid=", strprintf("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)", defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(), testnetChainParams->GetConsensus().defaultAssumeValid.GetHex()), false, OptionsCategory::OPTIONS); gArgs.AddArg("-blocksdir=", "Specify directory to hold blocks subdirectory for *.dat files (default: )", false, OptionsCategory::OPTIONS); -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM gArgs.AddArg("-blocknotify=", "Execute command when the best block changes (%s in cmd is replaced by block hash)", false, OptionsCategory::OPTIONS); #endif gArgs.AddArg("-blockreconstructionextratxn=", strprintf("Extra transactions to keep in memory for compact block reconstructions (default: %u)", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN), false, OptionsCategory::OPTIONS); @@ -788,7 +788,7 @@ std::string LicenseInfo() "\n"; } -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM static void BlockNotifyCallback(bool initialSync, const CBlockIndex *pBlockIndex) { if (initialSync || !pBlockIndex) @@ -2394,7 +2394,7 @@ bool AppInitMain(InitInterfaces& interfaces) fHaveGenesis = true; } -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM if (gArgs.IsArgSet("-blocknotify")) uiInterface.NotifyBlockTip_connect(BlockNotifyCallback); #endif diff --git a/src/util/system.cpp b/src/util/system.cpp index 1f77de8b53b5..f6839c19aebe 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -1205,7 +1205,7 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate) } #endif -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM void runCommand(const std::string& strCommand) { if (strCommand.empty()) return; diff --git a/src/util/system.h b/src/util/system.h index eefbceae5354..99472605f34c 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -112,7 +112,7 @@ fs::path GetConfigFile(const std::string& confPath); #ifdef WIN32 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM void runCommand(const std::string& strCommand); #endif diff --git a/src/validation.cpp b/src/validation.cpp index 7f6cad90ce81..76eeabb7c3dd 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1278,7 +1278,7 @@ CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr; static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM std::string strCmd = gArgs.GetArg("-alertnotify", ""); if (strCmd.empty()) return; diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 96e0b36b4d8b..a84a02031287 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -62,7 +62,7 @@ void WalletInit::AddWalletOptions() const gArgs.AddArg("-walletbackupsdir=", "Specify full path to directory for automatic wallet backups (must exist)", false, OptionsCategory::WALLET); gArgs.AddArg("-walletbroadcast", strprintf("Make the wallet broadcast transactions (default: %u)", DEFAULT_WALLETBROADCAST), false, OptionsCategory::WALLET); gArgs.AddArg("-walletdir=", "Specify directory to hold wallets (default: /wallets if it exists, otherwise )", false, OptionsCategory::WALLET); -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM gArgs.AddArg("-walletnotify=", "Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)", false, OptionsCategory::WALLET); #endif gArgs.AddArg("-zapwallettxes=", "Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b1fe4987d7d5..5e022e095519 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1125,7 +1125,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose) // Notify UI of new or updated transaction NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); -#if defined(HAVE_SYSTEM) +#if HAVE_SYSTEM // notify an external script when a wallet transaction comes in or is updated std::string strCmd = gArgs.GetArg("-walletnotify", ""); From 6d6b585affb9c3dca2865daa881785a646331653 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 8 Jul 2019 13:19:39 +0200 Subject: [PATCH 4/5] Merge #16352: build: prune dbus from depends e8fabd9253400a7c3fe45b34bc572eb00ff5522d build: prune dbus from depends (fanquake) Pull request description: Since #8210 (59d063d07660d6e8d53ed8aa1eb8b0747ea6767c), we've been passing `-dbus-runtime` when configuring Qt. ``` qtbase-opensource-src-5.9.7 $ ./configure -h | grep -i dbus -no-dbus ............. Do not build the Qt D-Bus module -dbus-linked ......... Build Qt D-Bus and link to libdbus-1 [auto] -dbus-runtime ........ Build Qt D-Bus and dynamically load libdbus-1 [no] ``` This means we don't actually seem to be using the `D-Bus` we build in depends. This was pointed out by theuni at the time, [here](https://github.com/bitcoin/bitcoin/pull/7993#issuecomment-223114395) and [here](https://github.com/bitcoin/bitcoin/pull/8210#issuecomment-226930545), but was never followed up. dongcarl also bought it up as part of #16150. I've tested building and running `bitcoin-qt` using depends on Debian. Needs further testing. ACKs for top commit: laanwj: code review ACK e8fabd9253400a7c3fe45b34bc572eb00ff5522d Tree-SHA512: 164e6e52b6f97c04aef42bd185e2a157bc1a42103840f9404c5a795749f45a8c2c35f35873395a3a56398b3cd5955496b90d9c885d929b434c9bc871695abe20 # Conflicts: # depends/packages/dbus.mk # depends/packages/packages.mk # doc/dependencies.md --- depends/packages/dbus.mk | 23 ----------------------- depends/packages/packages.mk | 2 +- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 depends/packages/dbus.mk diff --git a/depends/packages/dbus.mk b/depends/packages/dbus.mk deleted file mode 100644 index bbe03754099f..000000000000 --- a/depends/packages/dbus.mk +++ /dev/null @@ -1,23 +0,0 @@ -package=dbus -$(package)_version=1.10.18 -$(package)_download_path=https://dbus.freedesktop.org/releases/dbus -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=6049ddd5f3f3e2618f615f1faeda0a115104423a7996b7aa73e2f36e38cc514a -$(package)_dependencies=expat - -define $(package)_set_vars - $(package)_config_opts=--disable-tests --disable-doxygen-docs --disable-xml-docs --disable-static --without-x -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C dbus libdbus-1.la -endef - -define $(package)_stage_cmds - $(MAKE) -C dbus DESTDIR=$($(package)_staging_dir) install-libLTLIBRARIES install-dbusincludeHEADERS install-nodist_dbusarchincludeHEADERS && \ - $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA -endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index bcabf33b15a3..ae3018b61ad9 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -3,7 +3,7 @@ packages:=boost openssl libevent zeromq gmp bls-dash backtrace cmake immer qt_native_packages = native_protobuf qt_packages = qrencode protobuf zlib -qt_linux_packages:=qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig +qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig qt_darwin_packages=qt qt_mingw32_packages=qt From fe14f50bebe2c26629360614d2c056c071d7c151 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 23 Jul 2019 18:40:40 -0400 Subject: [PATCH 5/5] Merge #16366: init: Use InitError for all errors in bitcoind/qt fa6f402bde146f92ed131e0c9c8e15a55e723307 Call node->initError instead of InitError from GUI code (Russell Yanofsky) fad2502240a1c440ef03ac3f880475702e418275 init: Use InitError for all errors in bitcoind/qt (MarcoFalke) Pull request description: Using the same InitError for startup error in the daemon and the gui makes it possible to run the tests with the gui again: ```sh BITCOIND=bitcoin-qt ./test/functional/test_runner.py feature_includeconf feature_config_args ACKs for top commit: hebasto: ACK fa6f402bde146f92ed131e0c9c8e15a55e723307 ryanofsky: utACK fa6f402bde146f92ed131e0c9c8e15a55e723307. Only changes since last review are removing more includes and adding Node::initError method to avoid accessing node `InitError` function and global variables from GUI code. Tree-SHA512: bd19e08dcea4019dfe40356bc5c63cb583cefed54b6c9dcfb82f1b5b00308d8e2b363549afcaea5e93bf83864dbe0917400c3b70f43a8a5bdff45c9cd34cc294 --- src/dashd.cpp | 30 ++++++++++---------------- src/interfaces/node.cpp | 1 + src/interfaces/node.h | 3 +++ src/qt/bitcoingui.cpp | 3 --- src/qt/dash.cpp | 13 ++++++----- src/qt/dash.h | 1 - test/functional/feature_config_args.py | 12 +++++------ test/functional/feature_includeconf.py | 6 +++--- 8 files changed, 32 insertions(+), 37 deletions(-) diff --git a/src/dashd.cpp b/src/dashd.cpp index db0846c6002b..579c98060329 100644 --- a/src/dashd.cpp +++ b/src/dashd.cpp @@ -12,21 +12,20 @@ #include #include #include -#include #include #include +#include #include #include +#include +#include #include #include #include -#include #include #include #include -#include - const std::function G_TRANSLATION_FUN = nullptr; /* Introduction text for doxygen: */ @@ -74,8 +73,7 @@ static bool AppInit(int argc, char* argv[]) SetupServerArgs(); std::string error; if (!gArgs.ParseParameters(argc, argv, error)) { - fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str()); - return false; + return InitError(strprintf("Error parsing command line arguments: %s\n", error)); } if (gArgs.IsArgSet("-printcrashinfo")) { @@ -106,12 +104,10 @@ static bool AppInit(int argc, char* argv[]) bool datadirFromCmdLine = gArgs.IsArgSet("-datadir"); if (datadirFromCmdLine && !fs::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str()); - return false; + return InitError(strprintf("Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""))); } if (!gArgs.ReadConfigFiles(error, true)) { - fprintf(stderr, "Error reading configuration file: %s\n", error.c_str()); - return false; + return InitError(strprintf("Error reading configuration file: %s\n", error)); } if (!datadirFromCmdLine && !fs::is_directory(GetDataDir(false))) { @@ -122,15 +118,13 @@ static bool AppInit(int argc, char* argv[]) try { SelectParams(gArgs.GetChainName()); } catch (const std::exception& e) { - fprintf(stderr, "Error: %s\n", e.what()); - return false; + return InitError(strprintf("%s\n", e.what())); } // Error out when loose non-argument tokens are encountered on command line for (int i = 1; i < argc; i++) { if (!IsSwitchChar(argv[i][0])) { - fprintf(stderr, "Error: Command line contains unexpected token '%s', see dashd -h for a list of options.\n", argv[i]); - return false; + return InitError(strprintf("Command line contains unexpected token '%s', see bitcoind -h for a list of options.\n", argv[i])); } } @@ -161,19 +155,17 @@ static bool AppInit(int argc, char* argv[]) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif - fprintf(stdout, "Dash Core server starting\n"); + tfm::format(std::cout, PACKAGE_NAME "daemon starting\n"); // Daemonize if (daemon(1, 0)) { // don't chdir (1), do close FDs (0) - fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno)); - return false; + return InitError(strprintf("daemon() failed: %s\n", strerror(errno))); } #if defined(MAC_OSX) #pragma GCC diagnostic pop #endif #else - fprintf(stderr, "Error: -daemon is not supported on this operating system\n"); - return false; + return InitError("-daemon is not supported on this operating system\n"); #endif // HAVE_DECL_DAEMON } // Lock data directory after daemonization diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 4da114d66595..8219a4c80c54 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -159,6 +159,7 @@ class NodeImpl : public Node { public: NodeImpl() { m_interfaces.chain = MakeChain(); } + void initError(const std::string& message) override { InitError(message); } EVOImpl m_evo; LLMQImpl m_llmq; diff --git a/src/interfaces/node.h b/src/interfaces/node.h index 40f68e30521c..b393d6fdbf42 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -93,6 +93,9 @@ class Node public: virtual ~Node() {} + //! Send init error. + virtual void initError(const std::string& message) = 0; + //! Set command line arguments. virtual bool parseParameters(int argc, const char* const argv[], std::string& error) = 0; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index bb982547a303..8ce244246fca 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -37,9 +37,6 @@ #include #include -#include -#include - #include #include #include diff --git a/src/qt/dash.cpp b/src/qt/dash.cpp index 01471ea04e70..78dc70097712 100644 --- a/src/qt/dash.cpp +++ b/src/qt/dash.cpp @@ -11,8 +11,8 @@ #include #include -#include #include +#include #include #include #include @@ -41,9 +41,6 @@ #include #include -#include - -#include #include #include @@ -486,8 +483,11 @@ int GuiMain(int argc, char* argv[]) SetupUIArgs(); std::string error; if (!node->parseParameters(argc, argv, error)) { + node->initError(strprintf("Error parsing command line arguments: %s\n", error)); + // Create a message box, because the gui has neither been created nor has subscribed to core signals QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), - QObject::tr("Error parsing command line arguments: %1.").arg(QString::fromStdString(error))); + // message can not be translated because translations have not been initialized + QString::fromStdString("Error parsing command line arguments: %1.").arg(QString::fromStdString(error))); return EXIT_FAILURE; } @@ -530,11 +530,13 @@ int GuiMain(int argc, char* argv[]) /// - Do not call GetDataDir(true) before this step finishes if (!fs::is_directory(GetDataDir(false))) { + node->initError(strprintf("Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""))); QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", "")))); return EXIT_FAILURE; } if (!node->readConfigFiles(error)) { + node->initError(strprintf("Error reading configuration file: %s\n", error)); QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error))); return EXIT_FAILURE; @@ -550,6 +552,7 @@ int GuiMain(int argc, char* argv[]) try { node->selectParams(gArgs.GetChainName()); } catch(std::exception &e) { + node->initError(strprintf("%s\n", e.what())); QMessageBox::critical(nullptr, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); return EXIT_FAILURE; } diff --git a/src/qt/dash.h b/src/qt/dash.h index 276b0e794df2..c48a2ac1b565 100644 --- a/src/qt/dash.h +++ b/src/qt/dash.h @@ -11,7 +11,6 @@ #include #include -#include class BitcoinGUI; class ClientModel; diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index 2c2904aa29fc..ec454cecbb6b 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -22,7 +22,7 @@ def test_config_file_parser(self): conf.write('includeconf={}\n'.format(inc_conf_file_path)) self.nodes[0].assert_start_raises_init_error( - expected_msg='Error parsing command line arguments: Invalid parameter -dash_cli', + expected_msg='Error: Error parsing command line arguments: Invalid parameter -dash_cli', extra_args=['-dash_cli=1'], ) with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: @@ -33,7 +33,7 @@ def test_config_file_parser(self): with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('-dash=1\n') - self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -') + self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -') with open(inc_conf_file_path, 'w', encoding='utf8') as conf: conf.write("wallet=foo\n") @@ -41,19 +41,19 @@ def test_config_file_parser(self): with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('nono\n') - self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead') + self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead') with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('server=1\nrpcuser=someuser\nrpcpassword=some#pass') - self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided') + self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided') with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('server=1\nrpcuser=someuser\nmain.rpcpassword=some#pass') - self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided') + self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided') with open(inc_conf_file_path, 'w', encoding='utf-8') as conf: conf.write('server=1\nrpcuser=someuser\n[main]\nrpcpassword=some#pass') - self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 4, using # in rpcpassword can be ambiguous and should be avoided') + self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 4, using # in rpcpassword can be ambiguous and should be avoided') inc_conf_file2_path = os.path.join(self.nodes[0].datadir, 'include2.conf') with open(os.path.join(self.nodes[0].datadir, 'dash.conf'), 'a', encoding='utf-8') as conf: diff --git a/test/functional/feature_includeconf.py b/test/functional/feature_includeconf.py index e497d4211467..ab93b1373465 100755 --- a/test/functional/feature_includeconf.py +++ b/test/functional/feature_includeconf.py @@ -43,7 +43,7 @@ def run_test(self): self.log.info("-includeconf cannot be used as command-line arg") self.stop_node(0) - self.nodes[0].assert_start_raises_init_error(extra_args=["-includeconf=relative2.conf"], expected_msg="Error parsing command line arguments: -includeconf cannot be used from commandline; -includeconf=relative2.conf") + self.nodes[0].assert_start_raises_init_error(extra_args=["-includeconf=relative2.conf"], expected_msg="Error: Error parsing command line arguments: -includeconf cannot be used from commandline; -includeconf=relative2.conf") self.log.info("-includeconf cannot be used recursively. subversion should end with 'main; relative)/'") with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "a", encoding="utf8") as f: @@ -59,11 +59,11 @@ def run_test(self): # Commented out as long as we ignore invalid arguments in configuration files #with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f: # f.write("foo=bar\n") - #self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Invalid configuration value foo") + #self.nodes[0].assert_start_raises_init_error(expected_msg="Error: Error reading configuration file: Invalid configuration value foo") self.log.info("-includeconf cannot be invalid path") os.remove(os.path.join(self.options.tmpdir, "node0", "relative.conf")) - self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Failed to include configuration file relative.conf") + self.nodes[0].assert_start_raises_init_error(expected_msg="Error: Error reading configuration file: Failed to include configuration file relative.conf") self.log.info("multiple -includeconf args can be used from the base config file. subversion should end with 'main; relative; relative2)/'") with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f: