diff --git a/.travis.yml b/.travis.yml index bd5f2d796809..a376d39be9f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -249,7 +249,7 @@ after_success: name: 'x86_64 Linux [GOAL: install] [bionic] [uses qt5 dev package instead of depends Qt to speed up build and avoid timeout] [unsigned char]' env: >- FILE_ENV="./ci/test/00_setup_env_amd64_qt5.sh" - +# x86_64 Linux (xenial, no depends, only system libs, sanitizers: thread (TSan)) - stage: test name: 'x86_64 Linux [GOAL: install] [trusty] [no functional tests, no depends, only system libs]' env: >- @@ -259,7 +259,7 @@ after_success: name: 'x86_64 Linux [GOAL: install] [xenial] [no depends, only system libs, sanitizers: thread (TSan), no wallet]' env: >- FILE_ENV="./ci/test/00_setup_env_amd64_tsan.sh" - +# x86_64 Linux (no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer) - stage: test name: 'x86_64 Linux [GOAL: install] [bionic] [no depends, only system libs, sanitizers: address/leak (ASan + LSan) + undefined (UBSan) + integer]' env: >- @@ -269,7 +269,6 @@ after_success: name: 'x86_64 Linux [GOAL: install] [bionic] [no wallet]' env: >- FILE_ENV="./ci/test/00_setup_env_amd64_fuzz.sh" - - stage: test env: >- FILE_ENV="./ci/test/00_setup_env_amd64_nowallet.sh" diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 88d9157101d0..e83523d2fc70 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -78,7 +78,7 @@ bench_bench_dash_SOURCES += bench/coin_selection.cpp bench_bench_dash_SOURCES += bench/wallet_balance.cpp endif -bench_bench_dash_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS) $(GMP_LIBS) +bench_bench_dash_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(BLS_LIBS) $(GMP_LIBS) bench_bench_dash_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 098bf2d9145c..510d8f4bd022 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -673,7 +673,15 @@ CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno test/fuzz/*.gcda test/fuzz/*.gcno t CLEANFILES += $(CLEAN_BITCOIN_TEST) +if TARGET_WINDOWS dash_test: $(TEST_BINARY) +else +if ENABLE_BENCH +dash_test: $(TEST_BINARY) $(BENCH_BINARY) +else +dash_test: $(TEST_BINARY) +endif +endif dash_test_check: $(TEST_BINARY) FORCE $(MAKE) check-TESTS TESTS=$^ @@ -688,6 +696,14 @@ if BUILD_BITCOIN_TX endif @echo "Running test/util/rpcauth-test.py..." $(PYTHON) $(top_builddir)/test/util/rpcauth-test.py +if TARGET_WINDOWS +else +if ENABLE_BENCH +# Disabled because benchmarks are too heavy in Dash +# @echo "Running bench/bench_dash" +# $(BENCH_BINARY) +endif +endif $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check if !ENABLE_FUZZ diff --git a/src/init.cpp b/src/init.cpp index a1a8ce2693d0..6528ba0ecaec 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -140,7 +140,6 @@ static const char* DEFAULT_ASMAP_FILENAME="ip_asn.map"; /** * The PID file facilities. */ -#ifndef WIN32 static const char* BITCOIN_PID_FILENAME = "dashd.pid"; static fs::path GetPidFile() @@ -152,13 +151,16 @@ static fs::path GetPidFile() { fsbridge::ofstream file{GetPidFile()}; if (file) { +#ifdef WIN32 + tfm::format(file, "%d\n", GetCurrentProcessId()); +#else tfm::format(file, "%d\n", getpid()); +#endif return true; } else { return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile().string(), std::strerror(errno))); } } -#endif ////////////////////////////////////////////////////////////////////////////// // @@ -360,15 +362,13 @@ void PrepareShutdown(NodeContext& node) activeMasternodeInfo.blsPubKeyOperator.reset(); } -#ifndef WIN32 try { if (!fs::remove(GetPidFile())) { LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__); } } catch (const fs::filesystem_error& e) { - LogPrintf("%s: Unable to remove PID file: %s\n", __func__, e.what()); + LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); } -#endif node.chain_clients.clear(); UnregisterAllValidationInterfaces(); GetMainSignals().UnregisterBackgroundSignalScheduler(); @@ -501,11 +501,7 @@ void SetupServerArgs() gArgs.AddArg("-par=", strprintf("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)", -GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); gArgs.AddArg("-persistmempool", strprintf("Whether to save the mempool on shutdown and load on restart (default: %u)", DEFAULT_PERSIST_MEMPOOL), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); -#ifndef WIN32 gArgs.AddArg("-pid=", strprintf("Specify pid file. Relative paths will be prefixed by a net-specific datadir location. (default: %s)", BITCOIN_PID_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); -#else - hidden_args.emplace_back("-pid"); -#endif gArgs.AddArg("-prune=", strprintf("Reduce storage requirements by enabling pruning (deleting) of old blocks. This allows the pruneblockchain RPC to be called to delete specific blocks, and enables automatic pruning of old blocks if a target size in MiB is provided. This mode is incompatible with -txindex, -rescan and -disablegovernance=false. " "Warning: Reverting this setting requires re-downloading the entire blockchain. " "(default: 0 = disable pruning blocks, 1 = allow manual pruning via RPC, >%u = automatically prune block files to stay under the specified target size in MiB)", MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); @@ -1615,12 +1611,10 @@ bool AppInitMain(NodeContext& node) { const CChainParams& chainparams = Params(); // ********************************************************* Step 4a: application initialization -#ifndef WIN32 if (!CreatePidFile()) { // Detailed error printed inside CreatePidFile(). return false; } -#endif if (LogInstance().m_print_to_file) { if (gArgs.GetBoolArg("-shrinkdebugfile", LogInstance().DefaultShrinkDebugFile())) { // Do this first since it both loads a bunch of debug.log into memory, diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 36cd3c40340f..34fab92a67ec 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -187,16 +187,22 @@ void OverviewPage::setBalance(const interfaces::WalletBalances& balances) { int unit = walletModel->getOptionsModel()->getDisplayUnit(); m_balances = balances; - ui->labelBalance->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.balance, false, BitcoinUnits::separatorAlways)); - ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.unconfirmed_balance, false, BitcoinUnits::separatorAlways)); - ui->labelImmature->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.immature_balance, false, BitcoinUnits::separatorAlways)); - ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.anonymized_balance, false, BitcoinUnits::separatorAlways)); - ui->labelTotal->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, false, BitcoinUnits::separatorAlways)); - ui->labelWatchAvailable->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.watch_only_balance, false, BitcoinUnits::separatorAlways)); - ui->labelWatchPending->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.unconfirmed_watch_only_balance, false, BitcoinUnits::separatorAlways)); - ui->labelWatchImmature->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways)); - ui->labelWatchTotal->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways)); - + if (walletModel->privateKeysDisabled()) { + ui->labelBalance->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.watch_only_balance, false, BitcoinUnits::separatorAlways)); + ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.unconfirmed_watch_only_balance, false, BitcoinUnits::separatorAlways)); + ui->labelImmature->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways)); + ui->labelTotal->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways)); + } else { + ui->labelBalance->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.balance, false, BitcoinUnits::separatorAlways)); + ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.unconfirmed_balance, false, BitcoinUnits::separatorAlways)); + ui->labelImmature->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.immature_balance, false, BitcoinUnits::separatorAlways)); + ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.anonymized_balance, false, BitcoinUnits::separatorAlways)); + ui->labelTotal->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, false, BitcoinUnits::separatorAlways)); + ui->labelWatchAvailable->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.watch_only_balance, false, BitcoinUnits::separatorAlways)); + ui->labelWatchPending->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.unconfirmed_watch_only_balance, false, BitcoinUnits::separatorAlways)); + ui->labelWatchImmature->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways)); + ui->labelWatchTotal->setText(BitcoinUnits::floorHtmlWithUnit(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, false, BitcoinUnits::separatorAlways)); + } // only show immature (newly mined) balance if it's non-zero, so as not to complicate things // for the non-mining users bool fDebugUI = gArgs.GetBoolArg("-debug-ui", false); @@ -206,7 +212,7 @@ void OverviewPage::setBalance(const interfaces::WalletBalances& balances) // for symmetry reasons also show immature label when the watch-only one is shown ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature); ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature); - ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watch-only immature balance + ui->labelWatchImmature->setVisible(!walletModel->privateKeysDisabled() && showWatchOnlyImmature); // show watch-only immature balance updateCoinJoinProgress(); @@ -265,8 +271,11 @@ void OverviewPage::setWalletModel(WalletModel *model) connect(model, &WalletModel::balanceChanged, this, &OverviewPage::setBalance); connect(model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &OverviewPage::updateDisplayUnit); - updateWatchOnlyLabels(wallet.haveWatchOnly() || gArgs.GetBoolArg("-debug-ui", false)); - connect(model, &WalletModel::notifyWatchonlyChanged, this, &OverviewPage::updateWatchOnlyLabels); + + updateWatchOnlyLabels((wallet.haveWatchOnly() && !model->privateKeysDisabled()) || gArgs.GetBoolArg("-debug-ui", false)); + connect(model, &WalletModel::notifyWatchonlyChanged, [this](bool showWatchOnly) { + updateWatchOnlyLabels(showWatchOnly && !walletModel->privateKeysDisabled()); + }); // explicitly update PS frame and transaction list to reflect actual settings updateAdvancedCJUI(model->getOptionsModel()->getShowAdvancedCJUI()); diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 031b5273bacb..fbdfea6b3d3a 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -83,8 +83,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "sendmany", 6, "use_is" }, { "sendmany", 7, "use_cj" }, { "sendmany", 8, "conf_target" }, - { "deriveaddresses", 1, "begin" }, - { "deriveaddresses", 2, "end" }, + { "deriveaddresses", 1, "range" }, { "scantxoutset", 1, "scanobjects" }, { "addmultisigaddress", 0, "nrequired" }, { "addmultisigaddress", 1, "keys" }, diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index b190927c8719..55af382f05dc 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1289,7 +1289,7 @@ static const CRPCCommand commands[] = { "control", "logging", &logging, {"include", "exclude"}}, { "util", "validateaddress", &validateaddress, {"address"} }, { "util", "createmultisig", &createmultisig, {"nrequired","keys"} }, - { "util", "deriveaddresses", &deriveaddresses, {"descriptor", "begin", "end"} }, + { "util", "deriveaddresses", &deriveaddresses, {"descriptor", "range"} }, { "util", "getdescriptorinfo", &getdescriptorinfo, {"descriptor"} }, { "util", "verifymessage", &verifymessage, {"address","signature","message"} }, { "util", "signmessagewithprivkey", &signmessagewithprivkey, {"privkey","message"} }, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 335d644b1b0f..df7e8c66eaac 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -117,14 +117,13 @@ static UniValue getrawtransaction(const JSONRPCRequest& request) RPCHelpMan{ "getrawtransaction", "\nReturn the raw transaction data.\n" - "\nBy default this function only works for mempool transactions. When called with a blockhash\n" "argument, getrawtransaction will return the transaction if the specified block is available and\n" "the transaction is found in that block. When called without a blockhash argument, getrawtransaction\n" "will return the transaction if it is in the mempool, or if -txindex is enabled and the transaction\n" "is in a block in the blockchain.\n" - "\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n" - "Or use gettransaction for wallet transactions.\n" + "\nHint: Use gettransaction for wallet transactions.\n" + "\nIf verbose is 'true', returns an Object with information about 'txid'.\n" "If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n", { diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 96003b735ded..f9b4a2a9608c 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -22,7 +22,7 @@ #include static CCriticalSection cs_rpcWarmup; -static std::atomic fRPCRunning{false}; +static std::atomic g_rpc_running{false}; static bool fRPCInWarmup GUARDED_BY(cs_rpcWarmup) = true; static std::string rpcWarmupStatus GUARDED_BY(cs_rpcWarmup) = "RPC server started"; /* Timer-creating functions */ @@ -316,7 +316,7 @@ bool CRPCTable::removeCommand(const std::string& name, const CRPCCommand* pcmd) void StartRPC() { LogPrint(BCLog::RPC, "Starting RPC\n"); - fRPCRunning = true; + g_rpc_running = true; g_rpcSignals.Started(); } @@ -324,7 +324,7 @@ void InterruptRPC() { LogPrint(BCLog::RPC, "Interrupting RPC\n"); // Interrupt e.g. running longpolls - fRPCRunning = false; + g_rpc_running = false; } void StopRPC() @@ -337,7 +337,7 @@ void StopRPC() bool IsRPCRunning() { - return fRPCRunning; + return g_rpc_running; } void SetRPCWarmupStatus(const std::string& newStatus) diff --git a/test/functional/p2p_invalid_messages.py b/test/functional/p2p_invalid_messages.py index b656b00e681b..5cffdc080275 100755 --- a/test/functional/p2p_invalid_messages.py +++ b/test/functional/p2p_invalid_messages.py @@ -4,6 +4,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test node responses to invalid network messages.""" import asyncio +import os import struct import sys @@ -65,7 +66,10 @@ def run_test(self): msg_at_size = msg_unrecognized(str_data="b" * valid_data_limit) assert len(msg_at_size.serialize()) == msg_limit - with node.assert_memory_usage_stable(increase_allowed=0.5): + increase_allowed = 0.5 + if [s for s in os.environ.get("BITCOIN_CONFIG", "").split(" ") if "--with-sanitizers" in s and "address" in s]: + increase_allowed = 3.5 + with node.assert_memory_usage_stable(increase_allowed=increase_allowed): self.log.info( "Sending a bunch of large, junk messages to test " "memory exhaustion. May take a bit...") diff --git a/test/sanitizer_suppressions/lsan b/test/sanitizer_suppressions/lsan new file mode 100644 index 000000000000..6d903229d411 --- /dev/null +++ b/test/sanitizer_suppressions/lsan @@ -0,0 +1,10 @@ +# Suppress warnings about addCoin(...) leak in the CoinSelection benchmark +leak:addCoin +leak:bench_dash + +# Suppress warnings triggered in dependencies +leak:libcrypto +leak:libqminimal +leak:libQt5Core +leak:libQt5Gui +leak:libQt5Widgets