diff --git a/ci/dash/lint-tidy.sh b/ci/dash/lint-tidy.sh index c4d9ab5ed431b..15054e04f1c58 100755 --- a/ci/dash/lint-tidy.sh +++ b/ci/dash/lint-tidy.sh @@ -48,6 +48,7 @@ iwyu_tool.py \ "src/util/strencodings.cpp" \ "src/util/syserror.cpp" \ "src/util/url.cpp" \ + "src/zmq" \ -p . "${MAKEJOBS}" \ -- -Xiwyu --cxx17ns -Xiwyu --mapping_file="${BASE_ROOT_DIR}/contrib/devtools/iwyu/bitcoin.core.imp" \ 2>&1 | tee "/tmp/iwyu_ci.out" diff --git a/ci/lint/04_install.sh b/ci/lint/04_install.sh index 0453e91674881..b6f67f5cf4684 100755 --- a/ci/lint/04_install.sh +++ b/ci/lint/04_install.sh @@ -33,7 +33,7 @@ if [ -z "${SKIP_PYTHON_INSTALL}" ]; then python3 --version fi -${CI_RETRY_EXE} pip3 install codespell==2.1.0 +${CI_RETRY_EXE} pip3 install codespell==2.2.1 ${CI_RETRY_EXE} pip3 install flake8==4.0.1 ${CI_RETRY_EXE} pip3 install lief==0.13.1 ${CI_RETRY_EXE} pip3 install mypy==0.981 diff --git a/ci/lint/06_script.sh b/ci/lint/06_script.sh index 2912edd2dd426..93e6aeaeac932 100755 --- a/ci/lint/06_script.sh +++ b/ci/lint/06_script.sh @@ -38,6 +38,8 @@ if [ "$CIRRUS_REPO_FULL_NAME" = "dashpay/dash" ] && [ "$CIRRUS_PR" = "" ] ; then git log HEAD~10 -1 --format='%H' > ./contrib/verify-commits/trusted-sha512-root-commit git log HEAD~10 -1 --format='%H' > ./contrib/verify-commits/trusted-git-root mapfile -t KEYS < contrib/verify-commits/trusted-keys + git config user.email "ci@ci.ci" + git config user.name "ci" ${CI_RETRY_EXE} gpg --keyserver hkps://keys.openpgp.org --recv-keys "${KEYS[@]}" && ./contrib/verify-commits/verify-commits.py; fi diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh index 40d70b0394f86..bf14526ccad33 100755 --- a/ci/test/04_install.sh +++ b/ci/test/04_install.sh @@ -10,12 +10,6 @@ if [[ $QEMU_USER_CMD == qemu-s390* ]]; then export LC_ALL=C fi -if [ "$CI_OS_NAME" == "macos" ]; then - sudo -H pip3 install --upgrade pip - # shellcheck disable=SC2086 - IN_GETOPT_BIN="/usr/local/opt/gnu-getopt/bin/getopt" ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES -fi - # Create folders that are mounted into the docker mkdir -p "${CCACHE_DIR}" mkdir -p "${PREVIOUS_RELEASES_DIR}" @@ -89,9 +83,16 @@ if [[ $DOCKER_NAME_TAG == *centos* ]]; then elif [ "$CI_USE_APT_INSTALL" != "no" ]; then ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get update ${CI_RETRY_EXE} CI_EXEC_ROOT apt-get install --no-install-recommends --no-upgrade -y "$PACKAGES" "$DOCKER_PACKAGES" - if [ -n "$PIP_PACKAGES" ]; then +fi + +if [ -n "$PIP_PACKAGES" ]; then + if [ "$CI_OS_NAME" == "macos" ]; then + sudo -H pip3 install --upgrade pip + # shellcheck disable=SC2086 + IN_GETOPT_BIN="/usr/local/opt/gnu-getopt/bin/getopt" ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES + else # shellcheck disable=SC2086 - ${CI_RETRY_EXE} pip3 install --user $PIP_PACKAGES + ${CI_RETRY_EXE} CI_EXEC pip3 install --user $PIP_PACKAGES fi fi diff --git a/doc/release-notes-empty-template.md b/doc/release-notes-empty-template.md index 9a2d1a30c38b6..b129c6c599fc4 100644 --- a/doc/release-notes-empty-template.md +++ b/doc/release-notes-empty-template.md @@ -19,7 +19,7 @@ Please report bugs using the issue tracker at GitHub: If you are running an older version, shut it down. Wait until it has completely shut down (which might take a few minutes in some cases), then run the -installer (on Windows) or just copy over `/Applications/Dash-Qt` (on Mac) or +installer (on Windows) or just copy over `/Applications/Dash-Qt` (on macOS) or `dashd`/`dash-qt` (on Linux). ## Downgrade warning diff --git a/src/Makefile.test.include b/src/Makefile.test.include index a6cc2ce793181..dd6dda7178c39 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -219,6 +219,7 @@ BITCOIN_TESTS += \ wallet/test/availablecoins_tests.cpp \ wallet/test/init_tests.cpp \ wallet/test/ismine_tests.cpp \ + wallet/test/rpc_util_tests.cpp \ wallet/test/scriptpubkeyman_tests.cpp FUZZ_SUITE_LD_COMMON +=\ @@ -231,7 +232,8 @@ endif FUZZ_WALLET_SRC = \ wallet/test/fuzz/coincontrol.cpp \ - wallet/test/fuzz/coinselection.cpp + wallet/test/fuzz/coinselection.cpp \ + wallet/test/fuzz/parse_iso8601.cpp if USE_SQLITE FUZZ_WALLET_SRC += \ @@ -331,7 +333,6 @@ test_fuzz_fuzz_SOURCES = \ test/fuzz/node_eviction.cpp \ test/fuzz/p2p_transport_serialization.cpp \ test/fuzz/parse_hd_keypath.cpp \ - test/fuzz/parse_iso8601.cpp \ test/fuzz/parse_numbers.cpp \ test/fuzz/parse_script.cpp \ test/fuzz/parse_univalue.cpp \ diff --git a/src/bench/nanobench.h b/src/bench/nanobench.h index 4808b866fef4e..127240d3c7ea2 100644 --- a/src/bench/nanobench.h +++ b/src/bench/nanobench.h @@ -898,7 +898,7 @@ class Bench { * @brief Retrieves all benchmark results collected by the bench object so far. * * Each call to run() generates a Result that is stored within the Bench instance. This is mostly for advanced users who want to - * see all the nitty gritty detials. + * see all the nitty gritty details. * * @return All results collected so far. */ diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index e620c005cd147..982d8ab635328 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -222,7 +222,7 @@ static bool AppInit(NodeContext& node, int argc, char* argv[]) if (token) { // Success exit(EXIT_SUCCESS); } else { // fRet = false or token read error (premature exit). - tfm::format(std::cerr, "Error during initializaton - check debug.log for details\n"); + tfm::format(std::cerr, "Error during initialization - check debug.log for details\n"); exit(EXIT_FAILURE); } } diff --git a/src/index/blockfilterindex.h b/src/index/blockfilterindex.h index e9316c5ca3373..21c425985f17f 100644 --- a/src/index/blockfilterindex.h +++ b/src/index/blockfilterindex.h @@ -12,6 +12,8 @@ #include #include +static const char* const DEFAULT_BLOCKFILTERINDEX = "0"; + /** Interval between compact filter checkpoints. See BIP 157. */ static constexpr int CFCHECKPT_INTERVAL = 1000; diff --git a/src/index/coinstatsindex.h b/src/index/coinstatsindex.h index 40b19ca9315c2..b7ad12b760824 100644 --- a/src/index/coinstatsindex.h +++ b/src/index/coinstatsindex.h @@ -11,6 +11,8 @@ #include #include +static constexpr bool DEFAULT_COINSTATSINDEX{false}; + /** * CoinStatsIndex maintains statistics on the UTXO set. */ diff --git a/src/index/txindex.h b/src/index/txindex.h index bad60e03fb8a3..032fdd73d8a35 100644 --- a/src/index/txindex.h +++ b/src/index/txindex.h @@ -7,6 +7,8 @@ #include +static constexpr bool DEFAULT_TXINDEX{true}; + /** * TxIndex is used to look up transactions included in the blockchain by hash. * The index is written to a LevelDB database and records the filesystem diff --git a/src/node/caches.cpp b/src/node/caches.cpp index f168332ee657b..a39ad7aeb661c 100644 --- a/src/node/caches.cpp +++ b/src/node/caches.cpp @@ -4,9 +4,9 @@ #include +#include #include #include -#include namespace node { CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes) diff --git a/src/node/miner.cpp b/src/node/miner.cpp index d99aeb8aee74d..e00d905fc6de1 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -431,13 +431,9 @@ static int UpdatePackagesForAdded(const CTxMemPool& mempool, modtxiter mit = mapModifiedTx.find(desc); if (mit == mapModifiedTx.end()) { CTxMemPoolModifiedEntry modEntry(desc); - modEntry.nSizeWithAncestors -= it->GetTxSize(); - modEntry.nModFeesWithAncestors -= it->GetModifiedFee(); - modEntry.nSigOpCountWithAncestors -= it->GetSigOpCount(); - mapModifiedTx.insert(modEntry); - } else { - mapModifiedTx.modify(mit, update_for_parent_inclusion(it)); + mit = mapModifiedTx.insert(modEntry).first; } + mapModifiedTx.modify(mit, update_for_parent_inclusion(it)); } } return nDescendantsUpdated; diff --git a/src/rpc/fees.cpp b/src/rpc/fees.cpp index 00940a5832798..8a4030f9a15f3 100644 --- a/src/rpc/fees.cpp +++ b/src/rpc/fees.cpp @@ -65,7 +65,6 @@ static RPCHelpMan estimatesmartfee() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR}); - RPCTypeCheckArgument(request.params[0], UniValue::VNUM); CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context); @@ -157,7 +156,6 @@ static RPCHelpMan estimaterawfee() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true); - RPCTypeCheckArgument(request.params[0], UniValue::VNUM); CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context); diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index ea184dd89ea23..adaf7eee581ae 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -629,8 +629,7 @@ static RPCHelpMan gettxspendingprevout() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { - RPCTypeCheckArgument(request.params[0], UniValue::VARR); - const UniValue& output_params = request.params[0]; + const UniValue& output_params = request.params[0].get_array(); if (output_params.empty()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, outputs are missing"); } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index c4b49e2a4a1ca..0ad0d236b287f 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -525,8 +525,7 @@ UniValue CRPCTable::execute(const JSONRPCRequest &request) const static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler) { - try - { + try { RPCCommandExecution execution(request.strMethod); // Execute, convert arguments to array if necessary if (request.params.isObject()) { @@ -534,9 +533,9 @@ static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& req } else { return command.actor(request, result, last_handler); } - } - catch (const std::exception& e) - { + } catch (const UniValue::type_error& e) { + throw JSONRPCError(RPC_TYPE_ERROR, e.what()); + } catch (const std::exception& e) { throw JSONRPCError(RPC_MISC_ERROR, e.what()); } } diff --git a/src/sync.h b/src/sync.h index 3a4220c40c356..12b5853901826 100644 --- a/src/sync.h +++ b/src/sync.h @@ -115,7 +115,7 @@ class LOCKABLE AnnotatedMixin : public PARENT return PARENT::try_lock(); } - using UniqueLock = std::unique_lock; + using unique_lock = std::unique_lock; #ifdef __clang__ //! For negative capabilities in the Clang Thread Safety Analysis. //! A negative requirement uses the EXCLUSIVE_LOCKS_REQUIRED attribute, in conjunction @@ -172,11 +172,13 @@ inline void AssertLockNotHeldInline(const char* name, const char* file, int line inline void AssertLockNotHeldInline(const char* name, const char* file, int line, SharedMutex* cs) LOCKS_EXCLUDED(cs) { AssertLockNotHeldInternal(name, file, line, cs); } #define AssertLockNotHeld(cs) AssertLockNotHeldInline(#cs, __FILE__, __LINE__, &cs) -/** Wrapper around std::unique_lock style lock for Mutex. */ -template -class SCOPED_LOCKABLE UniqueLock : public Base +/** Wrapper around std::unique_lock style lock for MutexType. */ +template +class SCOPED_LOCKABLE UniqueLock : public MutexType::unique_lock { private: + using Base = typename MutexType::unique_lock; + void Enter(const char* pszName, const char* pszFile, int nLine) { EnterCritical(pszName, pszFile, nLine, Base::mutex()); @@ -198,7 +200,7 @@ class SCOPED_LOCKABLE UniqueLock : public Base } public: - UniqueLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock) + UniqueLock(MutexType& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock) { if (fTry) TryEnter(pszName, pszFile, nLine); @@ -206,7 +208,7 @@ class SCOPED_LOCKABLE UniqueLock : public Base Enter(pszName, pszFile, nLine); } - UniqueLock(Mutex* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn) + UniqueLock(MutexType* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn) { if (!pmutexIn) return; @@ -320,8 +322,6 @@ class SCOPED_LOCKABLE SharedLock : public Base #define REVERSE_LOCK(g) typename std::decay::type::reverse_lock UNIQUE_NAME(revlock)(g, #g, __FILE__, __LINE__) -template -using DebugLock = UniqueLock::type>::type>; template using ReadLock = SharedLock::type>::type>; @@ -330,28 +330,21 @@ using ReadLock = SharedLock +inline MutexType& MaybeCheckNotHeld(MutexType& m) LOCKS_EXCLUDED(m) LOCK_RETURNED(m) { return m; } +template +inline MutexType* MaybeCheckNotHeld(MutexType* m) LOCKS_EXCLUDED(m) LOCK_RETURNED(m) { return m; } -#define LOCK(cs) DebugLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) +#define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) #define READ_LOCK(cs) ReadLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) #define LOCK2(cs1, cs2) \ - DebugLock criticalblock1(MaybeCheckNotHeld(cs1), #cs1, __FILE__, __LINE__); \ - DebugLock criticalblock2(MaybeCheckNotHeld(cs2), #cs2, __FILE__, __LINE__) -#define TRY_LOCK(cs, name) DebugLock name(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__, true) + UniqueLock criticalblock1(MaybeCheckNotHeld(cs1), #cs1, __FILE__, __LINE__); \ + UniqueLock criticalblock2(MaybeCheckNotHeld(cs2), #cs2, __FILE__, __LINE__) +#define TRY_LOCK(cs, name) UniqueLock name(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__, true) #define TRY_READ_LOCK(cs, name) ReadLock name(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__, true) -#define WAIT_LOCK(cs, name) DebugLock name(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) +#define WAIT_LOCK(cs, name) UniqueLock name(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) #define ENTER_CRITICAL_SECTION(cs) \ { \ diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index d772d0954f94e..e0ccec8af35c2 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -323,8 +323,8 @@ CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::option int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional& min, const std::optional& max) noexcept { // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime. - static const int64_t time_min{ParseISO8601DateTime("2000-01-01T00:00:01Z")}; - static const int64_t time_max{ParseISO8601DateTime("2100-12-31T23:59:59Z")}; + static const int64_t time_min{946684801}; // 2000-01-01T00:00:01Z + static const int64_t time_max{4133980799}; // 2100-12-31T23:59:59Z return fuzzed_data_provider.ConsumeIntegralInRange(min.value_or(time_min), max.value_or(time_max)); } diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 6d5c7be2c019c..787834c2f713d 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -292,16 +292,12 @@ BOOST_AUTO_TEST_CASE(util_TrimString) BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), ""); } -BOOST_AUTO_TEST_CASE(util_FormatParseISO8601DateTime) +BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime) { BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890963199), "32767-12-31T23:59:59Z"); BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890876800), "32767-12-31T00:00:00Z"); BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z"); BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z"); - - BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z"), 0); - BOOST_CHECK_EQUAL(ParseISO8601DateTime("1960-01-01T00:00:00Z"), 0); - BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z"), 1317425777); } BOOST_AUTO_TEST_CASE(util_FormatISO8601Date) diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index e3c7fb38dfe4c..270cde9a352dc 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -339,7 +339,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup) //! Test LoadBlockIndex behavior when multiple chainstates are in use. //! -//! - First, verfiy that setBlockIndexCandidates is as expected when using a single, +//! - First, verify that setBlockIndexCandidates is as expected when using a single, //! fully-validating chainstate. //! //! - Then mark a region of the chain BLOCK_ASSUMED_VALID and introduce a second chainstate diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index d895b26af988b..004135ef97335 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -20,6 +20,11 @@ class UniValue { public: enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; + class type_error : public std::runtime_error + { + using std::runtime_error::runtime_error; + }; + UniValue() { typ = VNULL; } UniValue(UniValue::VType type, std::string str = {}) : typ{type}, val{std::move(str)} {} template >, diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 29660ceedc466..c3d19caae04fe 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -210,7 +210,7 @@ const UniValue& UniValue::operator[](size_t index) const void UniValue::checkType(const VType& expected) const { if (typ != expected) { - throw std::runtime_error{"JSON value of type " + std::string{uvTypeName(typ)} + " is not of expected type " + + throw type_error{"JSON value of type " + std::string{uvTypeName(typ)} + " is not of expected type " + std::string{uvTypeName(expected)}}; } } diff --git a/src/util/time.cpp b/src/util/time.cpp index 548b1b015c896..bab8759b90bd6 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -12,8 +12,6 @@ #include #include -#include - #include #include #include @@ -89,20 +87,6 @@ std::string FormatISO8601Time(int64_t nTime) return strprintf("%02i:%02i:%02iZ", hms.hours().count(), hms.minutes().count(), hms.seconds().count()); } -int64_t ParseISO8601DateTime(const std::string& str) -{ - static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0); - static const std::locale loc(std::locale::classic(), - new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ")); - std::istringstream iss(str); - iss.imbue(loc); - boost::posix_time::ptime ptime(boost::date_time::not_a_date_time); - iss >> ptime; - if (ptime.is_not_a_date_time() || epoch > ptime) - return 0; - return (ptime - epoch).total_seconds(); -} - struct timespec MillisToTimespec(int64_t nTimeout) { struct timespec timeout; diff --git a/src/util/time.h b/src/util/time.h index c1929ab7a9de7..99e1fc77e9f26 100644 --- a/src/util/time.h +++ b/src/util/time.h @@ -143,7 +143,6 @@ T GetTime() std::string FormatISO8601DateTime(int64_t nTime); std::string FormatISO8601Date(int64_t nTime); std::string FormatISO8601Time(int64_t nTime); -int64_t ParseISO8601DateTime(const std::string& str); /** * Convert milliseconds to a struct timeval for e.g. select. diff --git a/src/validation.h b/src/validation.h index 21a57c25ecf2c..290f721280c99 100644 --- a/src/validation.h +++ b/src/validation.h @@ -78,9 +78,7 @@ static const unsigned int MAX_HEADERS_COMPRESSED_RESULT = 8000; static const int64_t DEFAULT_MAX_TIP_AGE = 6 * 60 * 60; // ~144 blocks behind -> 2 x fork detection time, was 24 * 60 * 60 in bitcoin static const bool DEFAULT_CHECKPOINTS_ENABLED = true; -static const bool DEFAULT_TXINDEX = true; -static constexpr bool DEFAULT_COINSTATSINDEX{false}; -static const char* const DEFAULT_BLOCKFILTERINDEX = "0"; + /** Default for -persistmempool */ static const bool DEFAULT_PERSIST_MEMPOOL = true; /** Default for -syncmempool */ diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp index 92856570665be..692aba0fcac69 100644 --- a/src/wallet/rpc/coins.cpp +++ b/src/wallet/rpc/coins.cpp @@ -300,8 +300,6 @@ RPCHelpMan lockunspent() LOCK(pwallet->cs_wallet); - RPCTypeCheckArgument(request.params[0], UniValue::VBOOL); - bool fUnlock = request.params[0].get_bool(); const bool persistent{request.params[2].isNull() ? false : request.params[2].get_bool()}; @@ -314,9 +312,7 @@ RPCHelpMan lockunspent() return true; } - RPCTypeCheckArgument(request.params[1], UniValue::VARR); - - const UniValue& output_params = request.params[1]; + const UniValue& output_params = request.params[1].get_array(); // Create and validate the COutPoints first. @@ -571,19 +567,16 @@ RPCHelpMan listunspent() int nMinDepth = 1; if (!request.params[0].isNull()) { - RPCTypeCheckArgument(request.params[0], UniValue::VNUM); nMinDepth = request.params[0].getInt(); } int nMaxDepth = 9999999; if (!request.params[1].isNull()) { - RPCTypeCheckArgument(request.params[1], UniValue::VNUM); nMaxDepth = request.params[1].getInt(); } std::set destinations; if (!request.params[2].isNull()) { - RPCTypeCheckArgument(request.params[2], UniValue::VARR); UniValue inputs = request.params[2].get_array(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; @@ -599,7 +592,6 @@ RPCHelpMan listunspent() bool include_unsafe = true; if (!request.params[3].isNull()) { - RPCTypeCheckArgument(request.params[3], UniValue::VBOOL); include_unsafe = request.params[3].get_bool(); } diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp index 5feea820add2d..baf4914abc6da 100644 --- a/src/wallet/rpc/spend.cpp +++ b/src/wallet/rpc/spend.cpp @@ -248,7 +248,7 @@ RPCHelpMan sendmany() {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, std::string() + "The fee estimate mode, must be one of (case insensitive):\n" " \"" + FeeModes("\"\n\"") + "\""}, {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/B."}, - {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra infomration about the transaction."}, + {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra information about the transaction."}, }, { RPCResult{"if verbose is not set or set to false", @@ -372,7 +372,6 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out, coinControl.fAllowWatchOnly = options.get_bool(); } else { - RPCTypeCheckArgument(options, UniValue::VOBJ); RPCTypeCheckObj(options, { {"add_inputs", UniValueType(UniValue::VBOOL)}, diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp index 6ccd1d1471357..a5d75b8108ac1 100644 --- a/src/wallet/rpc/util.cpp +++ b/src/wallet/rpc/util.cpp @@ -12,10 +12,26 @@ #include +#include + namespace wallet { static const std::string WALLET_ENDPOINT_BASE = "/wallet/"; const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"}; +int64_t ParseISO8601DateTime(const std::string& str) +{ + static const boost::posix_time::ptime epoch = boost::posix_time::from_time_t(0); + static const std::locale loc(std::locale::classic(), + new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%SZ")); + std::istringstream iss(str); + iss.imbue(loc); + boost::posix_time::ptime ptime(boost::date_time::not_a_date_time); + iss >> ptime; + if (ptime.is_not_a_date_time() || epoch > ptime) + return 0; + return (ptime - epoch).total_seconds(); +} + bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) { bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); bool avoid_reuse = param.isNull() ? can_avoid_reuse : param.get_bool(); diff --git a/src/wallet/rpc/util.h b/src/wallet/rpc/util.h index 1b679cc3c0163..dce9fd66e5d4b 100644 --- a/src/wallet/rpc/util.h +++ b/src/wallet/rpc/util.h @@ -42,6 +42,7 @@ bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& wal std::string LabelFromValue(const UniValue& value); void HandleWalletError(const std::shared_ptr wallet, DatabaseStatus& status, bilingual_str& error); +int64_t ParseISO8601DateTime(const std::string& str); } // namespace wallet #endif // BITCOIN_WALLET_RPC_UTIL_H diff --git a/src/wallet/test/fuzz/coinselection.cpp b/src/wallet/test/fuzz/coinselection.cpp index e76064573ac92..cb9ca59f4702d 100644 --- a/src/wallet/test/fuzz/coinselection.cpp +++ b/src/wallet/test/fuzz/coinselection.cpp @@ -31,7 +31,7 @@ static void GroupCoins(FuzzedDataProvider& fuzzed_data_provider, const std::vect bool valid_outputgroup{false}; for (auto& coin : coins) { output_group.Insert(coin, /*ancestors=*/0, /*descendants=*/0, positive_only); - // If positive_only was specified, nothing may have been inserted, leading to an empty outpout group + // If positive_only was specified, nothing may have been inserted, leading to an empty output group // that would be invalid for the BnB algorithm valid_outputgroup = !positive_only || output_group.GetSelectionAmount() > 0; if (valid_outputgroup && fuzzed_data_provider.ConsumeBool()) { diff --git a/src/test/fuzz/parse_iso8601.cpp b/src/wallet/test/fuzz/parse_iso8601.cpp similarity index 83% rename from src/test/fuzz/parse_iso8601.cpp rename to src/wallet/test/fuzz/parse_iso8601.cpp index 0fef9a9a1d349..5be248c2fb0af 100644 --- a/src/test/fuzz/parse_iso8601.cpp +++ b/src/wallet/test/fuzz/parse_iso8601.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -20,7 +21,7 @@ FUZZ_TARGET(parse_iso8601) const std::string iso8601_datetime = FormatISO8601DateTime(random_time); (void)FormatISO8601Date(random_time); - const int64_t parsed_time_1 = ParseISO8601DateTime(iso8601_datetime); + const int64_t parsed_time_1 = wallet::ParseISO8601DateTime(iso8601_datetime); if (random_time >= 0) { assert(parsed_time_1 >= 0); if (iso8601_datetime.length() == 20) { @@ -28,6 +29,6 @@ FUZZ_TARGET(parse_iso8601) } } - const int64_t parsed_time_2 = ParseISO8601DateTime(random_string); + const int64_t parsed_time_2 = wallet::ParseISO8601DateTime(random_string); assert(parsed_time_2 >= 0); } diff --git a/src/wallet/test/rpc_util_tests.cpp b/src/wallet/test/rpc_util_tests.cpp new file mode 100644 index 0000000000000..32f6f5ab465e8 --- /dev/null +++ b/src/wallet/test/rpc_util_tests.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +namespace wallet { + +BOOST_AUTO_TEST_SUITE(wallet_util_tests) + +BOOST_AUTO_TEST_CASE(util_ParseISO8601DateTime) +{ + BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z"), 0); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("1960-01-01T00:00:00Z"), 0); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:01Z"), 946684801); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z"), 1317425777); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2100-12-31T23:59:59Z"), 4133980799); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // namespace wallet diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index a2de0adf5ecf4..9267cba306f99 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1948,10 +1948,10 @@ void CWallet::ResendWalletTransactions() // Do this infrequently and randomly to avoid giving away // that these are our transactions. - if (GetTime() < nNextResend || !fBroadcastTransactions) return; - bool fFirst = (nNextResend == 0); + if (GetTime() < m_next_resend || !fBroadcastTransactions) return; + bool fFirst = (m_next_resend == 0); // resend 1-3 hours from now, ~2 hours on average. - nNextResend = GetTime() + (1 * 60 * 60) + GetRand(2 * 60 * 60); + m_next_resend = GetTime() + (1 * 60 * 60) + GetRand(2 * 60 * 60); if (fFirst) return; int submitted_tx_count = 0; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index bf427dd1b16ab..f8222540f82fc 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -274,7 +274,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati //! the current wallet version: clients below this version are not able to load the wallet int nWalletVersion GUARDED_BY(cs_wallet){FEATURE_BASE}; - int64_t nNextResend = 0; + /** The next scheduled rebroadcast of wallet transactions. */ + std::atomic m_next_resend{}; /** Whether this wallet will submit newly created transactions to the node's mempool and * prompt rebroadcasts (see ResendWalletTransactions()). */ bool fBroadcastTransactions = false; diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 6abee40248593..2f115b93d001f 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H #define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H - +#include #include #include diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index 06e21f8cefef3..f44fb33f776d8 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -4,14 +4,24 @@ #include +#include #include #include +#include #include +#include +#include #include #include #include +#include +#include +#include +#include +#include + CZMQNotificationInterface::CZMQNotificationInterface() : pcontext(nullptr) { } diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index e0de1074f4d33..150fa9769cce6 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -5,10 +5,14 @@ #ifndef BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H #define BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H +#include #include + +#include #include #include +class CBlock; class CBlockIndex; class CZMQAbstractNotifier; diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 82e0a5660a2f8..83d43e4742129 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -6,9 +6,22 @@ #include #include +#include +#include +#include #include #include +#include +#include +#include +#include #include +#include +#include +#include +#include + +#include #include #include @@ -16,15 +29,20 @@ #include #include -#include -#include - +#include #include #include +#include +#include #include #include #include #include +#include + +namespace Consensus { +struct Params; +} using node::ReadBlockFromDisk; diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index 2f1803add73f5..e96c208ddfeb0 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -7,16 +7,19 @@ #include +#include +#include + class CBlockIndex; class CDeterministicMNList; class CGovernanceVote; +class CTransaction; namespace Governance { class Object; } //namespace Governance - class CZMQAbstractPublishNotifier : public CZMQAbstractNotifier { private: diff --git a/src/zmq/zmqrpc.cpp b/src/zmq/zmqrpc.cpp index 7ae3cf0c1e657..372e69f0a0fd4 100644 --- a/src/zmq/zmqrpc.cpp +++ b/src/zmq/zmqrpc.cpp @@ -11,6 +11,11 @@ #include +#include +#include + +class JSONRPCRequest; + namespace { static RPCHelpMan getzmqnotifications() diff --git a/test/README.md b/test/README.md index 548d360afe323..7ab5c82cfcbfe 100644 --- a/test/README.md +++ b/test/README.md @@ -300,8 +300,8 @@ gdb /home/example/dashd Note: gdb attach step may require ptrace_scope to be modified, or `sudo` preceding the `gdb`. See this link for considerations: https://www.kernel.org/doc/Documentation/security/Yama.txt -Often while debugging rpc calls from functional tests, the test might reach timeout before -process can return a response. Use `--timeout-factor 0` to disable all rpc timeouts for that partcular +Often while debugging RPC calls in functional tests, the test might time out before the +process can return a response. Use `--timeout-factor 0` to disable all RPC timeouts for that particular functional test. Ex: `test/functional/wallet_hd.py --timeout-factor 0`. ##### Profiling diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py index 1f9bf2c605711..f958df9fbbc67 100755 --- a/test/functional/mining_prioritisetransaction.py +++ b/test/functional/mining_prioritisetransaction.py @@ -120,7 +120,7 @@ def run_test(self): txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000' # Test `prioritisetransaction` invalid `fee_delta` - assert_raises_rpc_error(-1, "JSON value of type string is not of expected type number", self.nodes[0].prioritisetransaction, txid=txid, fee_delta='foo') + assert_raises_rpc_error(-3, "JSON value of type string is not of expected type number", self.nodes[0].prioritisetransaction, txid=txid, fee_delta='foo') self.test_diamond() diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 0f1381d473858..87b588fdd025d 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -265,12 +265,12 @@ def _test_getchaintxstats(self): assert_raises_rpc_error(-1, 'getchaintxstats', self.nodes[0].getchaintxstats, 0, '', 0) # Test `getchaintxstats` invalid `nblocks` - assert_raises_rpc_error(-1, "JSON value of type string is not of expected type number", self.nodes[0].getchaintxstats, '') + assert_raises_rpc_error(-3, "JSON value of type string is not of expected type number", self.nodes[0].getchaintxstats, '') assert_raises_rpc_error(-8, "Invalid block count: should be between 0 and the block's height - 1", self.nodes[0].getchaintxstats, -1) assert_raises_rpc_error(-8, "Invalid block count: should be between 0 and the block's height - 1", self.nodes[0].getchaintxstats, self.nodes[0].getblockcount()) # Test `getchaintxstats` invalid `blockhash` - assert_raises_rpc_error(-1, "JSON value of type number is not of expected type string", self.nodes[0].getchaintxstats, blockhash=0) + assert_raises_rpc_error(-3, "JSON value of type number is not of expected type string", self.nodes[0].getchaintxstats, blockhash=0) assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 1, for '0')", self.nodes[0].getchaintxstats, blockhash='0') assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getchaintxstats, blockhash='ZZZ0000000000000000000000000000000000000000000000000000000000000') assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0000000000000000000000000000000000000000000000000000000000000000') @@ -563,7 +563,7 @@ def assert_vin_does_not_contain_prevout(verbosity): datadir = get_datadir_path(self.options.tmpdir, 0) self.log.info("Test that getblock with invalid verbosity type returns proper error message") - assert_raises_rpc_error(-1, "JSON value of type string is not of expected type number", node.getblock, blockhash, "2") + assert_raises_rpc_error(-3, "JSON value of type string is not of expected type number", node.getblock, blockhash, "2") def move_block_file(old, new): old_path = os.path.join(datadir, self.chain, 'blocks', old) diff --git a/test/functional/rpc_help.py b/test/functional/rpc_help.py index 7c244e829550b..30573822f2602 100755 --- a/test/functional/rpc_help.py +++ b/test/functional/rpc_help.py @@ -94,7 +94,7 @@ def test_categories(self): assert_raises_rpc_error(-1, 'help', node.help, 'foo', 'bar', 'foobar') # invalid argument - assert_raises_rpc_error(-1, "JSON value of type number is not of expected type string", node.help, 0) + assert_raises_rpc_error(-3, "JSON value of type number is not of expected type string", node.help, 0) # help of unknown command assert_equal(node.help('foo'), 'help: unknown command: foo') diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index 338a3eb91fcc5..7854db8a09fb3 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -128,14 +128,14 @@ def getrawtransaction_tests(self): # 6. invalid parameters - supply txid and invalid boolean values (strings) for verbose for value in ["True", "False"]: - assert_raises_rpc_error(-1, "not of expected type bool", self.nodes[n].getrawtransaction, txid=txId, verbose=value) - assert_raises_rpc_error(-1, "not of expected type bool", self.nodes[n].getrawtransactionmulti, transactions={"0":[txId]}, verbose=value) + assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txid=txId, verbose=value) + assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransactionmulti, transactions={"0":[txId]}, verbose=value) # 7. invalid parameters - supply txid and empty array - assert_raises_rpc_error(-1, "not of expected type bool", self.nodes[n].getrawtransaction, txId, []) + assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txId, []) # 8. invalid parameters - supply txid and empty dict - assert_raises_rpc_error(-1, "not of expected type bool", self.nodes[n].getrawtransaction, txId, {}) + assert_raises_rpc_error(-3, "not of expected type bool", self.nodes[n].getrawtransaction, txId, {}) # Make a tx by sending, then generate 2 blocks; block1 has the tx in it tx = self.wallet.send_self_transfer(from_node=self.nodes[2])['txid'] @@ -157,7 +157,7 @@ def getrawtransaction_tests(self): # We should not get the tx if we provide an unrelated block assert_raises_rpc_error(-5, "No such transaction found", self.nodes[n].getrawtransaction, txid=tx, blockhash=block2) # An invalid block hash should raise the correct errors - assert_raises_rpc_error(-1, "JSON value of type bool is not of expected type string", self.nodes[n].getrawtransaction, txid=tx, blockhash=True) + assert_raises_rpc_error(-3, "JSON value of type bool is not of expected type string", self.nodes[n].getrawtransaction, txid=tx, blockhash=True) assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 6, for 'foobar')", self.nodes[n].getrawtransaction, txid=tx, blockhash="foobar") assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 8, for 'abcd1234')", self.nodes[n].getrawtransaction, txid=tx, blockhash="abcd1234") foo = "ZZZ0000000000000000000000000000000000000000000000000000000000000" @@ -187,8 +187,8 @@ def createrawtransaction_tests(self): # Test `createrawtransaction` invalid `inputs` assert_raises_rpc_error(-3, "JSON value of type string is not of expected type array", self.nodes[0].createrawtransaction, 'foo', {}) - assert_raises_rpc_error(-1, "JSON value of type string is not of expected type object", self.nodes[0].createrawtransaction, ['foo'], {}) - assert_raises_rpc_error(-1, "JSON value of type null is not of expected type string", self.nodes[0].createrawtransaction, [{}], {}) + assert_raises_rpc_error(-3, "JSON value of type string is not of expected type object", self.nodes[0].createrawtransaction, ['foo'], {}) + assert_raises_rpc_error(-3, "JSON value of type null is not of expected type string", self.nodes[0].createrawtransaction, [{}], {}) assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {}) txid = "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844" assert_raises_rpc_error(-8, f"txid must be hexadecimal string (not '{txid}')", self.nodes[0].createrawtransaction, [{'txid': txid}], {}) @@ -213,7 +213,7 @@ def createrawtransaction_tests(self): # Test `createrawtransaction` invalid `outputs` address = getnewdestination()[2] - assert_raises_rpc_error(-1, "JSON value of type string is not of expected type array", self.nodes[0].createrawtransaction, [], 'foo') + assert_raises_rpc_error(-3, "JSON value of type string is not of expected type array", self.nodes[0].createrawtransaction, [], 'foo') self.nodes[0].createrawtransaction(inputs=[], outputs={}) # Should not throw for backwards compatibility self.nodes[0].createrawtransaction(inputs=[], outputs=[]) assert_raises_rpc_error(-8, "Data must be hexadecimal string", self.nodes[0].createrawtransaction, [], {'data': 'foo'}) diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index c478a6e164217..91a34f0c4d59d 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -453,7 +453,7 @@ def run_test(self): assert_raises_rpc_error(-3, "Invalid amount", self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4") # This will raise an exception since generate does not accept a string - assert_raises_rpc_error(-1, "not of expected type number", self.generate, self.nodes[0], "2") + assert_raises_rpc_error(-3, "not of expected type number", self.generate, self.nodes[0], "2") if not self.options.descriptors: diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py index 665529f72662f..ef981056a5bc8 100755 --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -184,8 +184,8 @@ def run_test(self): # Sethdseed parameter validity assert_raises_rpc_error(-1, 'sethdseed', self.nodes[0].sethdseed, False, new_seed, 0) assert_raises_rpc_error(-5, "Invalid private key", wallet_no_seed.sethdseed, False, "not_wif") - assert_raises_rpc_error(-1, "JSON value of type string is not of expected type bool", wallet_no_seed.sethdseed, "Not_bool") - assert_raises_rpc_error(-1, "JSON value of type bool is not of expected type string", wallet_no_seed.sethdseed, False, True) + assert_raises_rpc_error(-3, "JSON value of type string is not of expected type bool", wallet_no_seed.sethdseed, "Not_bool") + assert_raises_rpc_error(-3, "JSON value of type bool is not of expected type string", wallet_no_seed.sethdseed, False, True) assert_raises_rpc_error(-5, "Already have this key", wallet_no_seed.sethdseed, False, non_hd_key) self.log.info('Test sethdseed restoring with keys outside of the initial keypool') diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index 3902129aa0884..541751768d632 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -353,7 +353,7 @@ def wallet_file(name): self.log.info("Test dynamic wallet unloading") # Test `unloadwallet` errors - assert_raises_rpc_error(-1, "JSON value of type null is not of expected type string", self.nodes[0].unloadwallet) + assert_raises_rpc_error(-3, "JSON value of type null is not of expected type string", self.nodes[0].unloadwallet) assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", self.nodes[0].unloadwallet, "dummy") assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", node.get_wallet_rpc("dummy").unloadwallet) assert_raises_rpc_error(-8, "RPC endpoint wallet and wallet_name parameter specify different wallets", w1.unloadwallet, "w2"), diff --git a/test/lint/lint-locale-dependence.py b/test/lint/lint-locale-dependence.py index 405c346e6971e..2a8266d524dc2 100755 --- a/test/lint/lint-locale-dependence.py +++ b/test/lint/lint-locale-dependence.py @@ -254,7 +254,7 @@ def main(): exit_code = 1 if exit_code == 1: - print("Unnecessary locale depedence can cause bugs that are very tricky to isolate and fix. Please avoid using locale dependent functions if possible.\n") + print("Unnecessary locale dependence can cause bugs that are very tricky to isolate and fix. Please avoid using locale-dependent functions if possible.\n") print(f"Advice not applicable in this specific case? Add an exception by updating the ignore list in {sys.argv[0]}") sys.exit(exit_code) diff --git a/test/lint/spelling.ignore-words.txt b/test/lint/spelling.ignore-words.txt index 8fa0c366f664a..5751545dc7825 100644 --- a/test/lint/spelling.ignore-words.txt +++ b/test/lint/spelling.ignore-words.txt @@ -1,14 +1,14 @@ asend ba blockin +bu cachable -creat +clen crypted fo fpr hights -hist -inout +inflight invokable lief mor @@ -16,8 +16,11 @@ nd nin ser setban +siz +stap stoll unparseable unser useable +warmup wit