diff options
41 files changed, 511 insertions, 229 deletions
diff --git a/.travis.yml b/.travis.yml index 7b5231afcc..7f8bc638ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ env: - WINEDEBUG=fixme-all matrix: # ARM - - HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf python3-pip" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + - HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf python3-pip shellcheck" DEP_OPTS="NO_QT=1" CHECK_DOC=1 GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" # Win32 - HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-i686 wine1.6" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" # Win64 diff --git a/contrib/devtools/lint-includes.sh b/contrib/devtools/lint-includes.sh index baca2f8a1f..f54be46b52 100755 --- a/contrib/devtools/lint-includes.sh +++ b/contrib/devtools/lint-includes.sh @@ -19,17 +19,6 @@ for HEADER_FILE in $(filter_suffix h); do echo EXIT_CODE=1 fi - CPP_FILE=${HEADER_FILE/%\.h/.cpp} - if [[ ! -e $CPP_FILE ]]; then - continue - fi - DUPLICATE_INCLUDES_IN_HEADER_AND_CPP_FILES=$(grep -hE "^#include " <(sort -u < "${HEADER_FILE}") <(sort -u < "${CPP_FILE}") | grep -E "^#include " | sort | uniq -d) - if [[ ${DUPLICATE_INCLUDES_IN_HEADER_AND_CPP_FILES} != "" ]]; then - echo "Include(s) from ${HEADER_FILE} duplicated in ${CPP_FILE}:" - echo "${DUPLICATE_INCLUDES_IN_HEADER_AND_CPP_FILES}" - echo - EXIT_CODE=1 - fi done for CPP_FILE in $(filter_suffix cpp); do DUPLICATE_INCLUDES_IN_CPP_FILE=$(grep -E "^#include " < "${CPP_FILE}" | sort | uniq -d) diff --git a/contrib/devtools/lint-shell.sh b/contrib/devtools/lint-shell.sh new file mode 100755 index 0000000000..5f5fa9a925 --- /dev/null +++ b/contrib/devtools/lint-shell.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# +# Copyright (c) 2018 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# Check for shellcheck warnings in shell scripts. + +# Disabled warnings: +# SC2001: See if you can use ${variable//search/replace} instead. +# SC2004: $/${} is unnecessary on arithmetic variables. +# SC2005: Useless echo? Instead of 'echo $(cmd)', just use 'cmd'. +# SC2006: Use $(..) instead of legacy `..`. +# SC2016: Expressions don't expand in single quotes, use double quotes for that. +# SC2028: echo won't expand escape sequences. Consider printf. +# SC2046: Quote this to prevent word splitting. +# SC2048: Use "$@" (with quotes) to prevent whitespace problems. +# SC2066: Since you double quoted this, it will not word split, and the loop will only run once. +# SC2086: Double quote to prevent globbing and word splitting. +# SC2116: Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'. +# SC2148: Tips depend on target shell and yours is unknown. Add a shebang. +# SC2162: read without -r will mangle backslashes. +# SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined. +# SC2166: Prefer [ p ] || [ q ] as [ p -o q ] is not well defined. +# SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. +shellcheck -e SC2001,SC2004,SC2005,SC2006,SC2016,SC2028,SC2046,SC2048,SC2066,SC2086,SC2116,SC2148,SC2162,SC2166,SC2181 \ + $(git ls-files -- "*.sh" | grep -vE 'src/(secp256k1|univalue)/') diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 980eed44f3..6b5311d3e3 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -569,8 +569,7 @@ Source code organization - *Rationale*: Shorter and simpler header files are easier to read, and reduce compile time - Every `.cpp` and `.h` file should `#include` every header file it directly uses classes, functions or other - definitions from, even if those headers are already included indirectly through other headers. One exception - is that a `.cpp` file does not need to re-include the includes already included in its corresponding `.h` file. + definitions from, even if those headers are already included indirectly through other headers. - *Rationale*: Excluding headers because they are already indirectly included results in compilation failures when those indirect dependencies change. Furthermore, it obscures what the real code diff --git a/doc/release-notes-pr12892.md b/doc/release-notes-pr12892.md new file mode 100644 index 0000000000..894bf19dee --- /dev/null +++ b/doc/release-notes-pr12892.md @@ -0,0 +1,32 @@ +'label' API for wallet +---------------------- + +A new 'label' API has been introduced for the wallet. This is intended as a +replacement for the deprecated 'account' API. + +The label RPC methods mirror the account functionality, with the following functional differences: + +- Labels can be set on any address, not just receiving addresses. This functionality was previously only available through the GUI. +- Labels can be deleted by reassigning all addresses using the `setlabel` RPC method. +- There isn't support for sending transactions _from_ a label, or for determining which label a transaction was sent from. +- Labels do not have a balance. + +Here are the changes to RPC methods: + +| Deprecated Method | New Method | Notes | +| :---------------------- | :-------------------- | :-----------| +| `getaccount` | `getaddressinfo` | `getaddressinfo` returns a json object with address information instead of just the name of the account as a string. | +| `getaccountaddress` | `getlabeladdress` | `getlabeladdress` throws an error by default if the label does not already exist, but provides a `force` option for compatibility with existing applications. | +| `getaddressesbyaccount` | `getaddressesbylabel` | `getaddressesbylabel` returns a json object with the addresses as keys, instead of a list of strings. | +| `getreceivedbyaccount` | `getreceivedbylabel` | _no change in behavior_ | +| `listaccounts` | `listlabels` | `listlabels` does not return a balance or accept `minconf` and `watchonly` arguments. | +| `listreceivedbyaccount` | `listreceivedbylabel` | Both methods return new `label` fields, along with `account` fields for backward compatibility. | +| `move` | n/a | _no replacement_ | +| `sendfrom` | n/a | _no replacement_ | +| `setaccount` | `setlabel` | Both methods now: <ul><li>allow assigning labels to any address, instead of raising an error if the address is not receiving address.<li>delete the previous label associated with an address when the final address using that label is reassigned to a different label, instead of making an implicit `getaccountaddress` call to ensure the previous label still has a receiving address. | + +| Changed Method | Notes | +| :--------------------- | :------ | +| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. | +| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. | +| `listunspent` | Returns new `label` fields, along with `account` fields for backward compatibility. | diff --git a/doc/release-notes.md b/doc/release-notes.md index 0a72f3fe4a..9e9c891de9 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -63,16 +63,6 @@ RPC changes - The `createrawtransaction` RPC will now accept an array or dictionary (kept for compatibility) for the `outputs` parameter. This means the order of transaction outputs can be specified by the client. - The `fundrawtransaction` RPC will reject the previously deprecated `reserveChangeKey` option. -- Wallet `getnewaddress` and `addmultisigaddress` RPC `account` named - parameters have been renamed to `label` with no change in behavior. -- Wallet `getlabeladdress`, `getreceivedbylabel`, `listreceivedbylabel`, and - `setlabel` RPCs have been added to replace `getaccountaddress`, - `getreceivedbyaccount`, `listreceivedbyaccount`, and `setaccount` RPCs, - which are now deprecated. There is no change in behavior between the - new RPCs and deprecated RPCs. -- Wallet `listreceivedbylabel`, `listreceivedbyaccount` and `listunspent` RPCs - add `label` fields to returned JSON objects that previously only had - `account` fields. - `sendmany` now shuffles outputs to improve privacy, so any previously expected behavior with regards to output ordering can no longer be relied upon. - The new RPC `testmempoolaccept` can be used to test acceptance of a transaction to the mempool without adding it. diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 4aa811b86b..83d9719df2 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -139,6 +139,10 @@ bool AppInit(int argc, char* argv[]) if (gArgs.GetBoolArg("-daemon", false)) { #if HAVE_DECL_DAEMON +#if defined(MAC_OSX) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif fprintf(stdout, "Bitcoin server starting\n"); // Daemonize @@ -146,6 +150,9 @@ bool AppInit(int argc, char* argv[]) fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno)); return false; } +#if defined(MAC_OSX) +#pragma GCC diagnostic pop +#endif #else fprintf(stderr, "Error: -daemon is not supported on this operating system\n"); return false; diff --git a/src/netaddress.h b/src/netaddress.h index b3d1407f72..38f8709257 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -141,7 +141,7 @@ class CSubNet class CService : public CNetAddr { protected: - unsigned short port; // host order + uint16_t port; // host order public: CService(); @@ -168,13 +168,7 @@ class CService : public CNetAddr template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(ip); - - // TODO: introduce native support for BE serialization in serialize.h - unsigned short portN = htons(port); - READWRITE(Span<unsigned char>((unsigned char*)&portN, 2)); - if (ser_action.ForRead()) { - port = ntohs(portN); - } + READWRITE(WrapBigEndian(port)); } }; diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 30c8124c58..cae9dace4c 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -24,6 +24,8 @@ const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1"; +static const QString GetDefaultProxyAddress(); + OptionsModel::OptionsModel(interfaces::Node& node, QObject *parent, bool resetSettings) : QAbstractListModel(parent), m_node(node) { @@ -121,7 +123,7 @@ void OptionsModel::Init(bool resetSettings) if (!settings.contains("fUseProxy")) settings.setValue("fUseProxy", false); if (!settings.contains("addrProxy")) - settings.setValue("addrProxy", QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST, DEFAULT_GUI_PROXY_PORT)); + settings.setValue("addrProxy", GetDefaultProxyAddress()); // Only try to set -proxy, if user has enabled fUseProxy if (settings.value("fUseProxy").toBool() && !m_node.softSetArg("-proxy", settings.value("addrProxy").toString().toStdString())) addOverriddenOption("-proxy"); @@ -131,7 +133,7 @@ void OptionsModel::Init(bool resetSettings) if (!settings.contains("fUseSeparateProxyTor")) settings.setValue("fUseSeparateProxyTor", false); if (!settings.contains("addrSeparateProxyTor")) - settings.setValue("addrSeparateProxyTor", QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST, DEFAULT_GUI_PROXY_PORT)); + settings.setValue("addrSeparateProxyTor", GetDefaultProxyAddress()); // Only try to set -onion, if user has enabled fUseSeparateProxyTor if (settings.value("fUseSeparateProxyTor").toBool() && !m_node.softSetArg("-onion", settings.value("addrSeparateProxyTor").toString().toStdString())) addOverriddenOption("-onion"); @@ -223,6 +225,11 @@ static void SetProxySetting(QSettings &settings, const QString &name, const Prox settings.setValue(name, ip_port.ip + ":" + ip_port.port); } +static const QString GetDefaultProxyAddress() +{ + return QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST).arg(DEFAULT_GUI_PROXY_PORT); +} + // read QSettings values and return them QVariant OptionsModel::data(const QModelIndex & index, int role) const { @@ -485,4 +492,16 @@ void OptionsModel::checkAndMigrate() settings.setValue(strSettingsVersionKey, CLIENT_VERSION); } + + // Overwrite the 'addrProxy' setting in case it has been set to an illegal + // default value (see issue #12623; PR #12650). + if (settings.contains("addrProxy") && settings.value("addrProxy").toString().endsWith("%2")) { + settings.setValue("addrProxy", GetDefaultProxyAddress()); + } + + // Overwrite the 'addrSeparateProxyTor' setting in case it has been set to an illegal + // default value (see issue #12623; PR #12650). + if (settings.contains("addrSeparateProxyTor") && settings.value("addrSeparateProxyTor").toString().endsWith("%2")) { + settings.setValue("addrSeparateProxyTor", GetDefaultProxyAddress()); + } } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 01f932dbb4..34c41b3b6b 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -51,6 +51,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listreceivedbylabel", 0, "minconf" }, { "listreceivedbylabel", 1, "include_empty" }, { "listreceivedbylabel", 2, "include_watchonly" }, + { "getlabeladdress", 1, "force" }, { "getbalance", 1, "minconf" }, { "getbalance", 2, "include_watchonly" }, { "getblockhash", 0, "height" }, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index f0493de3bd..cc616ce5e6 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -774,9 +774,6 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival if (is_temp_keystore && (scriptPubKey.IsPayToScriptHash() || scriptPubKey.IsPayToWitnessScriptHash())) { RPCTypeCheckObj(prevOut, { - {"txid", UniValueType(UniValue::VSTR)}, - {"vout", UniValueType(UniValue::VNUM)}, - {"scriptPubKey", UniValueType(UniValue::VSTR)}, {"redeemScript", UniValueType(UniValue::VSTR)}, }); UniValue v = find_value(prevOut, "redeemScript"); diff --git a/src/serialize.h b/src/serialize.h index 57e434faf1..e54c7483d2 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -79,6 +79,11 @@ template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj) obj = htole16(obj); s.write((char*)&obj, 2); } +template<typename Stream> inline void ser_writedata16be(Stream &s, uint16_t obj) +{ + obj = htobe16(obj); + s.write((char*)&obj, 2); +} template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj) { obj = htole32(obj); @@ -101,6 +106,12 @@ template<typename Stream> inline uint16_t ser_readdata16(Stream &s) s.read((char*)&obj, 2); return le16toh(obj); } +template<typename Stream> inline uint16_t ser_readdata16be(Stream &s) +{ + uint16_t obj; + s.read((char*)&obj, 2); + return be16toh(obj); +} template<typename Stream> inline uint32_t ser_readdata32(Stream &s) { uint32_t obj; @@ -416,6 +427,40 @@ public: } }; +/** Serialization wrapper class for big-endian integers. + * + * Use this wrapper around integer types that are stored in memory in native + * byte order, but serialized in big endian notation. This is only intended + * to implement serializers that are compatible with existing formats, and + * its use is not recommended for new data structures. + * + * Only 16-bit types are supported for now. + */ +template<typename I> +class BigEndian +{ +protected: + I& m_val; +public: + explicit BigEndian(I& val) : m_val(val) + { + static_assert(std::is_unsigned<I>::value, "BigEndian type must be unsigned integer"); + static_assert(sizeof(I) == 2 && std::numeric_limits<I>::min() == 0 && std::numeric_limits<I>::max() == std::numeric_limits<uint16_t>::max(), "Unsupported BigEndian size"); + } + + template<typename Stream> + void Serialize(Stream& s) const + { + ser_writedata16be(s, m_val); + } + + template<typename Stream> + void Unserialize(Stream& s) + { + m_val = ser_readdata16be(s); + } +}; + class CCompactSize { protected: @@ -466,6 +511,9 @@ public: template<VarIntMode Mode=VarIntMode::DEFAULT, typename I> CVarInt<Mode, I> WrapVarInt(I& n) { return CVarInt<Mode, I>{n}; } +template<typename I> +BigEndian<I> WrapBigEndian(I& n) { return BigEndian<I>(n); } + /** * Forward declarations */ diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index 6b188a06b4..ee3650d148 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -98,14 +98,14 @@ BOOST_AUTO_TEST_CASE(addrman_simple) CNetAddr source = ResolveIP("252.2.2.2"); // Test: Does Addrman respond correctly when empty. - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); CAddrInfo addr_null = addrman.Select(); BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0"); // Test: Does Addrman::Add work as expected. CService addr1 = ResolveService("250.1.1.1", 8333); BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source)); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); CAddrInfo addr_ret1 = addrman.Select(); BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333"); @@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Expected dup IP should not be added. CService addr1_dup = ResolveService("250.1.1.1", 8333); BOOST_CHECK(!addrman.Add(CAddress(addr1_dup, NODE_NONE), source)); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); // Test: New table has one addr and we add a diff addr we should @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(addrman_simple) // Test: AddrMan::Clear() should empty the new table. addrman.Clear(); - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); CAddrInfo addr_null2 = addrman.Select(); BOOST_CHECK_EQUAL(addr_null2.ToString(), "[::]:0"); @@ -146,23 +146,23 @@ BOOST_AUTO_TEST_CASE(addrman_ports) CNetAddr source = ResolveIP("252.2.2.2"); - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); // Test 7; Addr with same IP but diff port does not replace existing addr. CService addr1 = ResolveService("250.1.1.1", 8333); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); CService addr1_port = ResolveService("250.1.1.1", 8334); addrman.Add(CAddress(addr1_port, NODE_NONE), source); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); CAddrInfo addr_ret2 = addrman.Select(); BOOST_CHECK_EQUAL(addr_ret2.ToString(), "250.1.1.1:8333"); // Test: Add same IP but diff port to tried table, it doesn't get added. // Perhaps this is not ideal behavior but it is the current behavior. addrman.Good(CAddress(addr1_port, NODE_NONE)); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); bool newOnly = true; CAddrInfo addr_ret3 = addrman.Select(newOnly); BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333"); @@ -178,7 +178,7 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test: Select from new with 1 addr in new. CService addr1 = ResolveService("250.1.1.1", 8333); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); bool newOnly = true; CAddrInfo addr_ret1 = addrman.Select(newOnly); @@ -186,14 +186,14 @@ BOOST_AUTO_TEST_CASE(addrman_select) // Test: move addr to tried, select from new expected nothing returned. addrman.Good(CAddress(addr1, NODE_NONE)); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); CAddrInfo addr_ret2 = addrman.Select(newOnly); BOOST_CHECK_EQUAL(addr_ret2.ToString(), "[::]:0"); CAddrInfo addr_ret3 = addrman.Select(); BOOST_CHECK_EQUAL(addr_ret3.ToString(), "250.1.1.1:8333"); - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); // Add three addresses to new table. @@ -218,14 +218,14 @@ BOOST_AUTO_TEST_CASE(addrman_select) addrman.Good(CAddress(addr7, NODE_NONE)); // Test: 6 addrs + 1 addr from last test = 7. - BOOST_CHECK_EQUAL(addrman.size(), 7); + BOOST_CHECK_EQUAL(addrman.size(), 7U); // Test: Select pulls from new and tried regardless of port number. std::set<uint16_t> ports; for (int i = 0; i < 20; ++i) { ports.insert(addrman.Select().GetPort()); } - BOOST_CHECK_EQUAL(ports.size(), 3); + BOOST_CHECK_EQUAL(ports.size(), 3U); } BOOST_AUTO_TEST_CASE(addrman_new_collisions) @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) CNetAddr source = ResolveIP("252.2.2.2"); - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); for (unsigned int i = 1; i < 18; i++) { CService addr = ResolveService("250.1.1." + std::to_string(i)); @@ -247,11 +247,11 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions) //Test: new table collision! CService addr1 = ResolveService("250.1.1.18"); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK_EQUAL(addrman.size(), 17); + BOOST_CHECK_EQUAL(addrman.size(), 17U); CService addr2 = ResolveService("250.1.1.19"); addrman.Add(CAddress(addr2, NODE_NONE), source); - BOOST_CHECK_EQUAL(addrman.size(), 18); + BOOST_CHECK_EQUAL(addrman.size(), 18U); } BOOST_AUTO_TEST_CASE(addrman_tried_collisions) @@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) CNetAddr source = ResolveIP("252.2.2.2"); - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); for (unsigned int i = 1; i < 80; i++) { CService addr = ResolveService("250.1.1." + std::to_string(i)); @@ -274,18 +274,18 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions) //Test: tried table collision! CService addr1 = ResolveService("250.1.1.80"); addrman.Add(CAddress(addr1, NODE_NONE), source); - BOOST_CHECK_EQUAL(addrman.size(), 79); + BOOST_CHECK_EQUAL(addrman.size(), 79U); CService addr2 = ResolveService("250.1.1.81"); addrman.Add(CAddress(addr2, NODE_NONE), source); - BOOST_CHECK_EQUAL(addrman.size(), 80); + BOOST_CHECK_EQUAL(addrman.size(), 80U); } BOOST_AUTO_TEST_CASE(addrman_find) { CAddrManTest addrman; - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); CAddress addr2 = CAddress(ResolveService("250.1.2.1", 9999), NODE_NONE); @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(addrman_create) { CAddrManTest addrman; - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = ResolveIP("250.1.2.1"); @@ -338,7 +338,7 @@ BOOST_AUTO_TEST_CASE(addrman_delete) { CAddrManTest addrman; - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); CAddress addr1 = CAddress(ResolveService("250.1.2.1", 8333), NODE_NONE); CNetAddr source1 = ResolveIP("250.1.2.1"); @@ -347,9 +347,9 @@ BOOST_AUTO_TEST_CASE(addrman_delete) addrman.Create(addr1, source1, &nId); // Test: Delete should actually delete the addr. - BOOST_CHECK_EQUAL(addrman.size(), 1); + BOOST_CHECK_EQUAL(addrman.size(), 1U); addrman.Delete(nId); - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); CAddrInfo* info2 = addrman.Find(addr1); BOOST_CHECK(info2 == nullptr); } @@ -360,9 +360,9 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) // Test: Sanity check, GetAddr should never return anything if addrman // is empty. - BOOST_CHECK_EQUAL(addrman.size(), 0); + BOOST_CHECK_EQUAL(addrman.size(), 0U); std::vector<CAddress> vAddr1 = addrman.GetAddr(); - BOOST_CHECK_EQUAL(vAddr1.size(), 0); + BOOST_CHECK_EQUAL(vAddr1.size(), 0U); CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE); addr1.nTime = GetAdjustedTime(); // Set time so isTerrible = false @@ -385,12 +385,12 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) addrman.Add(addr5, source1); // GetAddr returns 23% of addresses, 23% of 5 is 1 rounded down. - BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1); + BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1U); // Test: Ensure GetAddr works with new and tried addresses. addrman.Good(CAddress(addr1, NODE_NONE)); addrman.Good(CAddress(addr2, NODE_NONE)); - BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1); + BOOST_CHECK_EQUAL(addrman.GetAddr().size(), 1U); // Test: Ensure GetAddr still returns 23% when addrman has many addrs. for (unsigned int i = 1; i < (8 * 256); i++) { @@ -409,9 +409,9 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) size_t percent23 = (addrman.size() * 23) / 100; BOOST_CHECK_EQUAL(vAddr.size(), percent23); - BOOST_CHECK_EQUAL(vAddr.size(), 461); + BOOST_CHECK_EQUAL(vAddr.size(), 461U); // (Addrman.size() < number of addresses added) due to address collisions. - BOOST_CHECK_EQUAL(addrman.size(), 2006); + BOOST_CHECK_EQUAL(addrman.size(), 2006U); } @@ -454,7 +454,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) } // Test: IP addresses in the same group (\16 prefix for IPv4) should // never get more than 8 buckets - BOOST_CHECK_EQUAL(buckets.size(), 8); + BOOST_CHECK_EQUAL(buckets.size(), 8U); buckets.clear(); for (int j = 0; j < 255; j++) { @@ -466,7 +466,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_tried_bucket) } // Test: IP addresses in the different groups should map to more than // 8 buckets. - BOOST_CHECK_EQUAL(buckets.size(), 160); + BOOST_CHECK_EQUAL(buckets.size(), 160U); } BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) @@ -506,7 +506,7 @@ BOOST_AUTO_TEST_CASE(caddrinfo_get_new_bucket) } // Test: IP addresses in the same group (\16 prefix for IPv4) should // always map to the same bucket. - BOOST_CHECK_EQUAL(buckets.size(), 1); + BOOST_CHECK_EQUAL(buckets.size(), 1U); buckets.clear(); for (int j = 0; j < 4 * 255; j++) { diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index 24cd88c7a7..67d1229c70 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -64,10 +64,10 @@ BOOST_AUTO_TEST_CASE(arena_tests) BOOST_CHECK(b.stats().used == 128); b.free(a3); BOOST_CHECK(b.stats().used == 0); - BOOST_CHECK_EQUAL(b.stats().chunks_used, 0); + BOOST_CHECK_EQUAL(b.stats().chunks_used, 0U); BOOST_CHECK(b.stats().total == synth_size); BOOST_CHECK(b.stats().free == synth_size); - BOOST_CHECK_EQUAL(b.stats().chunks_free, 1); + BOOST_CHECK_EQUAL(b.stats().chunks_free, 1U); std::vector<void*> addr; BOOST_CHECK(b.alloc(0) == nullptr); // allocating 0 always returns nullptr diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 73c8eb5168..17f3004ef3 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_1) CMerkleBlock merkleBlock(block, filter); BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex()); - BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1); + BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 1U); std::pair<unsigned int, uint256> pair = merkleBlock.vMatchedTxn[0]; BOOST_CHECK(merkleBlock.vMatchedTxn[0].second == uint256S("0x74d681e0e03bafa802c8aa084379aa98d9fcd632ddc2ed9782b586ec87451f20")); diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index 8e0ec5243b..de47216449 100644 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(test_CheckQueue_Memory) control.Add(vChecks); } } - BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0); + BOOST_REQUIRE_EQUAL(MemoryCheck::fake_allocated_memory, 0U); } tg.interrupt_all(); tg.join_all(); diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index de7d8f7b90..a146c69fd2 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -480,8 +480,8 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization) Coin cc1; ss1 >> cc1; BOOST_CHECK_EQUAL(cc1.fCoinBase, false); - BOOST_CHECK_EQUAL(cc1.nHeight, 203998); - BOOST_CHECK_EQUAL(cc1.out.nValue, 60000000000ULL); + BOOST_CHECK_EQUAL(cc1.nHeight, 203998U); + BOOST_CHECK_EQUAL(cc1.out.nValue, CAmount{60000000000}); BOOST_CHECK_EQUAL(HexStr(cc1.out.scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("816115944e077fe7c803cfa57f29b36bf87c1d35")))))); // Good example @@ -489,7 +489,7 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization) Coin cc2; ss2 >> cc2; BOOST_CHECK_EQUAL(cc2.fCoinBase, true); - BOOST_CHECK_EQUAL(cc2.nHeight, 120891); + BOOST_CHECK_EQUAL(cc2.nHeight, 120891U); BOOST_CHECK_EQUAL(cc2.out.nValue, 110397); BOOST_CHECK_EQUAL(HexStr(cc2.out.scriptPubKey), HexStr(GetScriptForDestination(CKeyID(uint160(ParseHex("8c988f1a4a4de2161e0f50aac7f17e7f9555caa4")))))); @@ -498,9 +498,9 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization) Coin cc3; ss3 >> cc3; BOOST_CHECK_EQUAL(cc3.fCoinBase, false); - BOOST_CHECK_EQUAL(cc3.nHeight, 0); + BOOST_CHECK_EQUAL(cc3.nHeight, 0U); BOOST_CHECK_EQUAL(cc3.out.nValue, 0); - BOOST_CHECK_EQUAL(cc3.out.scriptPubKey.size(), 0); + BOOST_CHECK_EQUAL(cc3.out.scriptPubKey.size(), 0U); // scriptPubKey that ends beyond the end of the stream CDataStream ss4(ParseHex("000007"), SER_DISK, CLIENT_VERSION); diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp index cdfc664d56..de0d72614b 100644 --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -527,10 +527,10 @@ BOOST_AUTO_TEST_CASE(chacha20_testvector) BOOST_AUTO_TEST_CASE(countbits_tests) { FastRandomContext ctx; - for (int i = 0; i <= 64; ++i) { + for (unsigned int i = 0; i <= 64; ++i) { if (i == 0) { // Check handling of zero. - BOOST_CHECK_EQUAL(CountBits(0), 0); + BOOST_CHECK_EQUAL(CountBits(0), 0U); } else if (i < 10) { for (uint64_t j = 1 << (i - 1); (j >> i) == 0; ++j) { // Exhaustively test up to 10 bits diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 35f0463e3e..edc41ec42c 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(iterator_ordering) // Check that creating an iterator creates a snapshot std::unique_ptr<CDBIterator> it(const_cast<CDBWrapper&>(dbw).NewIterator()); - for (int x=0x00; x<256; ++x) { + for (unsigned int x=0x00; x<256; ++x) { uint8_t key = x; uint32_t value = x*x; if (x & 1) BOOST_CHECK(dbw.Write(key, value)); @@ -218,7 +218,7 @@ BOOST_AUTO_TEST_CASE(iterator_ordering) for (int seek_start : {0x00, 0x80}) { it->Seek((uint8_t)seek_start); - for (int x=seek_start; x<255; ++x) { + for (unsigned int x=seek_start; x<255; ++x) { uint8_t key; uint32_t value; BOOST_CHECK(it->Valid()); @@ -295,7 +295,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) snprintf(buf, sizeof(buf), "%d", seek_start); StringContentsSerializer seek_key(buf); it->Seek(seek_key); - for (int x=seek_start; x<10; ++x) { + for (unsigned int x=seek_start; x<10; ++x) { for (int y = 0; y < 10; y++) { snprintf(buf, sizeof(buf), "%d", x); std::string exp_key(buf); diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index 0de0a17904..d7d6c9b5a3 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -25,22 +25,22 @@ BOOST_AUTO_TEST_CASE(murmurhash3) // // The magic number 0xFBA4C795 comes from CBloomFilter::Hash() - T(0x00000000, 0x00000000, ""); - T(0x6a396f08, 0xFBA4C795, ""); - T(0x81f16f39, 0xffffffff, ""); - - T(0x514e28b7, 0x00000000, "00"); - T(0xea3f0b17, 0xFBA4C795, "00"); - T(0xfd6cf10d, 0x00000000, "ff"); - - T(0x16c6b7ab, 0x00000000, "0011"); - T(0x8eb51c3d, 0x00000000, "001122"); - T(0xb4471bf8, 0x00000000, "00112233"); - T(0xe2301fa8, 0x00000000, "0011223344"); - T(0xfc2e4a15, 0x00000000, "001122334455"); - T(0xb074502c, 0x00000000, "00112233445566"); - T(0x8034d2a0, 0x00000000, "0011223344556677"); - T(0xb4698def, 0x00000000, "001122334455667788"); + T(0x00000000U, 0x00000000, ""); + T(0x6a396f08U, 0xFBA4C795, ""); + T(0x81f16f39U, 0xffffffff, ""); + + T(0x514e28b7U, 0x00000000, "00"); + T(0xea3f0b17U, 0xFBA4C795, "00"); + T(0xfd6cf10dU, 0x00000000, "ff"); + + T(0x16c6b7abU, 0x00000000, "0011"); + T(0x8eb51c3dU, 0x00000000, "001122"); + T(0xb4471bf8U, 0x00000000, "00112233"); + T(0xe2301fa8U, 0x00000000, "0011223344"); + T(0xfc2e4a15U, 0x00000000, "001122334455"); + T(0xb074502cU, 0x00000000, "00112233445566"); + T(0x8034d2a0U, 0x00000000, "0011223344556677"); + T(0xb4698defU, 0x00000000, "001122334455667788"); #undef T } diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index a833a5cb1e..570c205731 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test) nSum += nSubsidy * 1000; BOOST_CHECK(MoneyRange(nSum)); } - BOOST_CHECK_EQUAL(nSum, 2099999997690000ULL); + BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000}); } bool ReturnFalse() { return false; } diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 19cd3b0963..37615d08b3 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) poolSize = testPool.size(); testPool.removeRecursive(txParent); BOOST_CHECK_EQUAL(testPool.size(), poolSize - 5); - BOOST_CHECK_EQUAL(testPool.size(), 0); + BOOST_CHECK_EQUAL(testPool.size(), 0U); // Add children and grandchildren, but NOT the parent (simulate the parent being in a block) for (int i = 0; i < 3; i++) @@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) poolSize = testPool.size(); testPool.removeRecursive(txParent); BOOST_CHECK_EQUAL(testPool.size(), poolSize - 6); - BOOST_CHECK_EQUAL(testPool.size(), 0); + BOOST_CHECK_EQUAL(testPool.size(), 0U); } template<typename name> @@ -156,7 +156,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx5.vout[0].nValue = 11 * COIN; entry.nTime = 1; pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); - BOOST_CHECK_EQUAL(pool.size(), 5); + BOOST_CHECK_EQUAL(pool.size(), 5U); std::vector<std::string> sortedOrder; sortedOrder.resize(5); @@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx6.vout[0].nValue = 20 * COIN; pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); - BOOST_CHECK_EQUAL(pool.size(), 6); + BOOST_CHECK_EQUAL(pool.size(), 6U); // Check that at this point, tx6 is sorted low sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); CheckSort<descendant_score>(pool, sortedOrder); @@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) BOOST_CHECK(setAncestorsCalculated == setAncestors); pool.addUnchecked(tx7.GetHash(), entry.FromTx(tx7), setAncestors); - BOOST_CHECK_EQUAL(pool.size(), 7); + BOOST_CHECK_EQUAL(pool.size(), 7U); // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ... sortedOrder.erase(sortedOrder.begin()); @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) pool.addUnchecked(tx9.GetHash(), entry.Fee(0LL).Time(3).FromTx(tx9), setAncestors); // tx9 should be sorted low - BOOST_CHECK_EQUAL(pool.size(), 9); + BOOST_CHECK_EQUAL(pool.size(), 9U); sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString()); CheckSort<descendant_score>(pool, sortedOrder); @@ -279,7 +279,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) CheckSort<descendant_score>(pool, sortedOrder); // there should be 10 transactions in the mempool - BOOST_CHECK_EQUAL(pool.size(), 10); + BOOST_CHECK_EQUAL(pool.size(), 10U); // Now try removing tx10 and verify the sort order returns to normal pool.removeRecursive(pool.mapTx.find(tx10.GetHash())->GetTx()); @@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx5.vout[0].nValue = 11 * COIN; pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); - BOOST_CHECK_EQUAL(pool.size(), 5); + BOOST_CHECK_EQUAL(pool.size(), 5U); std::vector<std::string> sortedOrder; sortedOrder.resize(5); @@ -359,7 +359,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) uint64_t tx6Size = GetVirtualTransactionSize(tx6); pool.addUnchecked(tx6.GetHash(), entry.Fee(0LL).FromTx(tx6)); - BOOST_CHECK_EQUAL(pool.size(), 6); + BOOST_CHECK_EQUAL(pool.size(), 6U); // Ties are broken by hash if (tx3.GetHash() < tx6.GetHash()) sortedOrder.push_back(tx6.GetHash().ToString()); @@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1; pool.addUnchecked(tx7.GetHash(), entry.Fee(fee).FromTx(tx7)); - BOOST_CHECK_EQUAL(pool.size(), 7); + BOOST_CHECK_EQUAL(pool.size(), 7U); sortedOrder.insert(sortedOrder.begin()+1, tx7.GetHash().ToString()); CheckSort<ancestor_score>(pool, sortedOrder); diff --git a/src/test/merkleblock_tests.cpp b/src/test/merkleblock_tests.cpp index 37a1a84136..2472ea9950 100644 --- a/src/test/merkleblock_tests.cpp +++ b/src/test/merkleblock_tests.cpp @@ -35,20 +35,20 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_found) BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex()); // vMatchedTxn is only used when bloom filter is specified. - BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0); + BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U); std::vector<uint256> vMatched; std::vector<unsigned int> vIndex; BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex()); - BOOST_CHECK_EQUAL(vMatched.size(), 2); + BOOST_CHECK_EQUAL(vMatched.size(), 2U); // Ordered by occurrence in depth-first tree traversal. BOOST_CHECK_EQUAL(vMatched[0].ToString(), txhash2.ToString()); - BOOST_CHECK_EQUAL(vIndex[0], 1); + BOOST_CHECK_EQUAL(vIndex[0], 1U); BOOST_CHECK_EQUAL(vMatched[1].ToString(), txhash1.ToString()); - BOOST_CHECK_EQUAL(vIndex[1], 8); + BOOST_CHECK_EQUAL(vIndex[1], 8U); } @@ -65,14 +65,14 @@ BOOST_AUTO_TEST_CASE(merkleblock_construct_from_txids_not_found) CMerkleBlock merkleBlock(block, txids2); BOOST_CHECK_EQUAL(merkleBlock.header.GetHash().GetHex(), block.GetHash().GetHex()); - BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0); + BOOST_CHECK_EQUAL(merkleBlock.vMatchedTxn.size(), 0U); std::vector<uint256> vMatched; std::vector<unsigned int> vIndex; BOOST_CHECK_EQUAL(merkleBlock.txn.ExtractMatches(vMatched, vIndex).GetHex(), block.hashMerkleRoot.GetHex()); - BOOST_CHECK_EQUAL(vMatched.size(), 0); - BOOST_CHECK_EQUAL(vIndex.size(), 0); + BOOST_CHECK_EQUAL(vMatched.size(), 0U); + BOOST_CHECK_EQUAL(vIndex.size(), 0U); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index d9f6772c2d..c98566f9ca 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -501,7 +501,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) // it into the template because we still check IsFinalTx in CreateNewBlock, // but relative locked txs will if inconsistently added to mempool. // For now these will still generate a valid template until BIP68 soft fork - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3U); // However if we advance height by 1 and time by 512, all of them should be mined for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++) chainActive.Tip()->GetAncestor(chainActive.Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast @@ -509,7 +509,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) SetMockTime(chainActive.Tip()->GetMedianTimePast() + 1); BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey)); - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 5U); chainActive.Tip()->nHeight--; SetMockTime(0); diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 26b2f5d0d7..9abfd5ebd8 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(get_next_work) pindexLast.nHeight = 32255; pindexLast.nTime = 1262152739; // Block #32255 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00d86a); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00d86aU); } /* Test the constraint on the upper bound for next work */ @@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) pindexLast.nHeight = 2015; pindexLast.nTime = 1233061996; // Block #2015 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00ffff); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00ffffU); } /* Test the constraint on the lower bound for actual time taken */ @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) pindexLast.nHeight = 68543; pindexLast.nTime = 1279297671; // Block #68543 pindexLast.nBits = 0x1c05a3f4; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0168fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1c0168fdU); } /* Test the constraint on the upper bound for actual time taken */ @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) pindexLast.nHeight = 46367; pindexLast.nTime = 1269211443; // Block #46367 pindexLast.nBits = 0x1c387f6f; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fdU); } BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) diff --git a/src/test/random_tests.cpp b/src/test/random_tests.cpp index 623ed239f0..80a294d129 100644 --- a/src/test/random_tests.cpp +++ b/src/test/random_tests.cpp @@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(fastrandom_randbits) for (int bits = 0; bits < 63; ++bits) { for (int j = 0; j < 1000; ++j) { uint64_t rangebits = ctx1.randbits(bits); - BOOST_CHECK_EQUAL(rangebits >> bits, 0); + BOOST_CHECK_EQUAL(rangebits >> bits, 0U); uint64_t range = ((uint64_t)1) << bits | rangebits; uint64_t rand = ctx2.randrange(range); BOOST_CHECK(rand < range); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 8d9f80ada0..242e1fb7ff 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); - BOOST_CHECK_EQUAL(ar.size(), 0); + BOOST_CHECK_EQUAL(ar.size(), 0U); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/24 add 1607731200 true"))); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); @@ -275,7 +275,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(CallRPC(std::string("setban 127.0.0.0/24 remove"))); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); - BOOST_CHECK_EQUAL(ar.size(), 0); + BOOST_CHECK_EQUAL(ar.size(), 0U); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("setban 127.0.0.0/255.255.0.0 add"))); BOOST_CHECK_THROW(r = CallRPC(std::string("setban 127.0.1.1 add")), std::runtime_error); @@ -283,7 +283,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_CHECK_NO_THROW(CallRPC(std::string("clearbanned"))); BOOST_CHECK_NO_THROW(r = CallRPC(std::string("listbanned"))); ar = r.get_array(); - BOOST_CHECK_EQUAL(ar.size(), 0); + BOOST_CHECK_EQUAL(ar.size(), 0U); BOOST_CHECK_THROW(r = CallRPC(std::string("setban test add")), std::runtime_error); //invalid IP diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp index cd30fbeda7..767c5fdbd2 100644 --- a/src/test/script_standard_tests.cpp +++ b/src/test/script_standard_tests.cpp @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) s << ToByteVector(pubkeys[0]) << OP_CHECKSIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_PUBKEY); - BOOST_CHECK_EQUAL(solutions.size(), 1); + BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0])); // TX_PUBKEYHASH @@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH); - BOOST_CHECK_EQUAL(solutions.size(), 1); + BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID())); // TX_SCRIPTHASH @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH); - BOOST_CHECK_EQUAL(solutions.size(), 1); + BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript))); // TX_MULTISIG @@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_MULTISIG); - BOOST_CHECK_EQUAL(solutions.size(), 4); + BOOST_CHECK_EQUAL(solutions.size(), 4U); BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1})); BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0])); BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1])); @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) OP_3 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_MULTISIG); - BOOST_CHECK_EQUAL(solutions.size(), 5); + BOOST_CHECK_EQUAL(solutions.size(), 5U); BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2})); BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0])); BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1])); @@ -90,14 +90,14 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) std::vector<unsigned char>({255}); BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_NULL_DATA); - BOOST_CHECK_EQUAL(solutions.size(), 0); + BOOST_CHECK_EQUAL(solutions.size(), 0U); // TX_WITNESS_V0_KEYHASH s.clear(); s << OP_0 << ToByteVector(pubkeys[0].GetID()); BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_WITNESS_V0_KEYHASH); - BOOST_CHECK_EQUAL(solutions.size(), 1); + BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID())); // TX_WITNESS_V0_SCRIPTHASH @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success) s << OP_0 << ToByteVector(scriptHash); BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK_EQUAL(whichType, TX_WITNESS_V0_SCRIPTHASH); - BOOST_CHECK_EQUAL(solutions.size(), 1); + BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK(solutions[0] == ToByteVector(scriptHash)); // TX_NONSTANDARD @@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations) s << ToByteVector(pubkeys[0]) << OP_CHECKSIG; BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK_EQUAL(whichType, TX_PUBKEY); - BOOST_CHECK_EQUAL(addresses.size(), 1); + BOOST_CHECK_EQUAL(addresses.size(), 1U); BOOST_CHECK_EQUAL(nRequired, 1); BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) && *boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID()); @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations) s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH); - BOOST_CHECK_EQUAL(addresses.size(), 1); + BOOST_CHECK_EQUAL(addresses.size(), 1U); BOOST_CHECK_EQUAL(nRequired, 1); BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) && *boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID()); @@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations) s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL; BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH); - BOOST_CHECK_EQUAL(addresses.size(), 1); + BOOST_CHECK_EQUAL(addresses.size(), 1U); BOOST_CHECK_EQUAL(nRequired, 1); BOOST_CHECK(boost::get<CScriptID>(&addresses[0]) && *boost::get<CScriptID>(&addresses[0]) == CScriptID(redeemScript)); @@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations) OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK_EQUAL(whichType, TX_MULTISIG); - BOOST_CHECK_EQUAL(addresses.size(), 2); + BOOST_CHECK_EQUAL(addresses.size(), 2U); BOOST_CHECK_EQUAL(nRequired, 2); BOOST_CHECK(boost::get<CKeyID>(&addresses[0]) && *boost::get<CKeyID>(&addresses[0]) == pubkeys[0].GetID()); diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 9b8b7bdc56..94164346f3 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -78,18 +78,18 @@ BOOST_AUTO_TEST_CASE(sizes) BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0)); // Sanity-check GetSerializeSize and c++ type matching - BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1); - BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1); - BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1); - BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2); - BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2); - BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4); - BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4); - BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8); - BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8); - BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4); - BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8); - BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1); + BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1U); + BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1U); + BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1U); + BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2U); + BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2U); + BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4U); + BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4U); + BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8U); + BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8U); + BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4U); + BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8U); + BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1U); } BOOST_AUTO_TEST_CASE(floats_conversion) @@ -103,12 +103,12 @@ BOOST_AUTO_TEST_CASE(floats_conversion) BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F); BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F); - BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000); - BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000); - BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000); - BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000); - BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000); - BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444); + BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000U); + BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000U); + BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000U); + BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000U); + BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000U); + BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444U); } BOOST_AUTO_TEST_CASE(doubles_conversion) @@ -299,39 +299,39 @@ BOOST_AUTO_TEST_CASE(insert_delete) { // Test inserting/deleting bytes. CDataStream ss(SER_DISK, 0); - BOOST_CHECK_EQUAL(ss.size(), 0); + BOOST_CHECK_EQUAL(ss.size(), 0U); ss.write("\x00\x01\x02\xff", 4); - BOOST_CHECK_EQUAL(ss.size(), 4); + BOOST_CHECK_EQUAL(ss.size(), 4U); char c = (char)11; // Inserting at beginning/end/middle: ss.insert(ss.begin(), c); - BOOST_CHECK_EQUAL(ss.size(), 5); + BOOST_CHECK_EQUAL(ss.size(), 5U); BOOST_CHECK_EQUAL(ss[0], c); BOOST_CHECK_EQUAL(ss[1], 0); ss.insert(ss.end(), c); - BOOST_CHECK_EQUAL(ss.size(), 6); + BOOST_CHECK_EQUAL(ss.size(), 6U); BOOST_CHECK_EQUAL(ss[4], (char)0xff); BOOST_CHECK_EQUAL(ss[5], c); ss.insert(ss.begin()+2, c); - BOOST_CHECK_EQUAL(ss.size(), 7); + BOOST_CHECK_EQUAL(ss.size(), 7U); BOOST_CHECK_EQUAL(ss[2], c); // Delete at beginning/end/middle ss.erase(ss.begin()); - BOOST_CHECK_EQUAL(ss.size(), 6); + BOOST_CHECK_EQUAL(ss.size(), 6U); BOOST_CHECK_EQUAL(ss[0], 0); ss.erase(ss.begin()+ss.size()-1); - BOOST_CHECK_EQUAL(ss.size(), 5); + BOOST_CHECK_EQUAL(ss.size(), 5U); BOOST_CHECK_EQUAL(ss[4], (char)0xff); ss.erase(ss.begin()+1); - BOOST_CHECK_EQUAL(ss.size(), 4); + BOOST_CHECK_EQUAL(ss.size(), 4U); BOOST_CHECK_EQUAL(ss[0], 0); BOOST_CHECK_EQUAL(ss[1], 1); BOOST_CHECK_EQUAL(ss[2], 2); @@ -340,7 +340,7 @@ BOOST_AUTO_TEST_CASE(insert_delete) // Make sure GetAndClear does the right thing: CSerializeData d; ss.GetAndClear(d); - BOOST_CHECK_EQUAL(ss.size(), 0); + BOOST_CHECK_EQUAL(ss.size(), 0U); } BOOST_AUTO_TEST_CASE(class_methods) diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp index d0aa8659c2..9ece9e70c2 100644 --- a/src/test/torcontrol_tests.cpp +++ b/src/test/torcontrol_tests.cpp @@ -167,10 +167,10 @@ BOOST_AUTO_TEST_CASE(util_ParseTorReplyMapping) // (needed because string comparison reads the null as end-of-string) BOOST_TEST_MESSAGE(std::string("CheckParseTorReplyMapping(Null=\"\\0\")")); auto ret = ParseTorReplyMapping("Null=\"\\0\""); - BOOST_CHECK_EQUAL(ret.size(), 1); + BOOST_CHECK_EQUAL(ret.size(), 1U); auto r_it = ret.begin(); BOOST_CHECK_EQUAL(r_it->first, "Null"); - BOOST_CHECK_EQUAL(r_it->second.size(), 1); + BOOST_CHECK_EQUAL(r_it->second.size(), 1U); BOOST_CHECK_EQUAL(r_it->second[0], '\0'); // A more complex valid grammar. PROTOCOLINFO accepts a VersionLine that diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index 7087c26774..87976a9a07 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -88,7 +88,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash()); // spends[1] should have been removed from the mempool when the // block with spends[0] is accepted: - BOOST_CHECK_EQUAL(mempool.size(), 0); + BOOST_CHECK_EQUAL(mempool.size(), 0U); } // Run CheckInputs (using pcoinsTip) on the given transaction, for all script @@ -205,7 +205,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) // not caching invalidity (if that changes, delete this test case). std::vector<CScriptCheck> scriptchecks; BOOST_CHECK(CheckInputs(spend_tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); - BOOST_CHECK_EQUAL(scriptchecks.size(), 1); + BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); // Test that CheckInputs returns true iff DERSIG-enforcing flags are // not present. Don't add these checks to the cache, so that we can @@ -364,7 +364,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) // input was valid) BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); // Should get 2 script checks back -- caching is on a whole-transaction basis. - BOOST_CHECK_EQUAL(scriptchecks.size(), 2); + BOOST_CHECK_EQUAL(scriptchecks.size(), 2U); } } diff --git a/src/validation.cpp b/src/validation.cpp index 4a6c4066fc..8066e6c7a8 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2064,6 +2064,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl * The caches and indexes are flushed depending on the mode we're called with * if they're too large, if it's been a while since the last write, * or always and in all cases if we're in prune mode and are deleting files. + * + * If FlushStateMode::NONE is used, then FlushStateToDisk(...) won't do anything + * besides checking if we need to prune. */ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &state, FlushStateMode mode, int nManualPruneHeight) { int64_t nMempoolUsage = mempool.DynamicMemoryUsage(); @@ -3454,8 +3457,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CVali return AbortNode(state, std::string("System error: ") + e.what()); } - if (fCheckForPruning) - FlushStateToDisk(chainparams, state, FlushStateMode::NONE); // we just allocated more disk space for block files + FlushStateToDisk(chainparams, state, FlushStateMode::NONE); CheckBlockIndex(chainparams.GetConsensus()); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 29760a7092..56bdc0695c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -189,7 +189,6 @@ UniValue getnewaddress(const JSONRPCRequest& request) return EncodeDestination(dest); } - CTxDestination GetLabelDestination(CWallet* const pwallet, const std::string& label, bool bForceNew=false) { CTxDestination dest; @@ -207,14 +206,16 @@ UniValue getlabeladdress(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() != 1) + if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( - "getlabeladdress \"label\"\n" - "\nReturns the current Bitcoin address for receiving payments to this label.\n" + "getlabeladdress \"label\" ( force ) \n" + "\nReturns the default receiving address for this label. This will reset to a fresh address once there's a transaction that spends to it.\n" "\nArguments:\n" - "1. \"label\" (string, required) The label name for the address. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created and a new address created if there is no label by the given name.\n" + "1. \"label\" (string, required) The label for the address. It can also be set to the empty string \"\" to represent the default label.\n" + "2. \"force\" (bool, optional) Whether the label should be created if it does not yet exist. If False, the RPC will return an error if called with a label that doesn't exist.\n" + " Defaults to false (unless the getaccountaddress method alias is being called, in which case defaults to true for backwards compatibility).\n" "\nResult:\n" - "\"address\" (string) The label bitcoin address\n" + "\"address\" (string) The current receiving address for the label.\n" "\nExamples:\n" + HelpExampleCli("getlabeladdress", "") + HelpExampleCli("getlabeladdress", "\"\"") @@ -226,6 +227,21 @@ UniValue getlabeladdress(const JSONRPCRequest& request) // Parse the label first so we don't generate a key if there's an error std::string label = LabelFromValue(request.params[0]); + bool force = request.strMethod == "getaccountaddress" ? true : false; + if (!request.params[1].isNull()) { + force = request.params[1].get_bool(); + } + + bool label_found = false; + for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) { + if (item.second.name == label) { + label_found = true; + break; + } + } + if (!force && !label_found) { + throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, std::string("No addresses with label " + label)); + } UniValue ret(UniValue::VSTR); @@ -290,13 +306,13 @@ UniValue setlabel(const JSONRPCRequest& request) return NullUniValue; } - if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( "setlabel \"address\" \"label\"\n" "\nSets the label associated with the given address.\n" "\nArguments:\n" "1. \"address\" (string, required) The bitcoin address to be associated with a label.\n" - "2. \"label\" (string, required) The label to assign the address to.\n" + "2. \"label\" (string, required) The label to assign to the address.\n" "\nExamples:\n" + HelpExampleCli("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"") + HelpExampleRpc("setlabel", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"") @@ -309,23 +325,22 @@ UniValue setlabel(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); } - std::string label; - if (!request.params[1].isNull()) - label = LabelFromValue(request.params[1]); + std::string label = LabelFromValue(request.params[1]); - // Only add the label if the address is yours. if (IsMine(*pwallet, dest)) { - // Detect when changing the label of an address that is the 'unused current key' of another label: + // Detect when changing the label of an address that is the receiving address of another label: + // If so, delete the account record for it. Labels, unlike addresses, can be deleted, + // and if we wouldn't do this, the record would stick around forever. if (pwallet->mapAddressBook.count(dest)) { std::string old_label = pwallet->mapAddressBook[dest].name; - if (dest == GetLabelDestination(pwallet, old_label)) { - GetLabelDestination(pwallet, old_label, true); + if (old_label != label && dest == GetLabelDestination(pwallet, old_label)) { + pwallet->DeleteLabel(old_label); } } pwallet->SetAddressBook(dest, label, "receive"); + } else { + pwallet->SetAddressBook(dest, label, "send"); } - else - throw JSONRPCError(RPC_MISC_ERROR, "setlabel can only be used with own address"); return NullUniValue; } @@ -1562,7 +1577,7 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request) " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n" " \"label\" : \"label\", (string) The label of the receiving address. The default label is \"\".\n" " \"txids\": [\n" - " n, (numeric) The ids of transactions received with the address \n" + " \"txid\", (string) The ids of transactions received with the address \n" " ...\n" " ]\n" " }\n" @@ -3720,6 +3735,17 @@ UniValue DescribeWalletAddress(CWallet* pwallet, const CTxDestination& dest) return ret; } +/** Convert CAddressBookData to JSON record. */ +static UniValue AddressBookDataToJSON(const CAddressBookData& data, const bool verbose) +{ + UniValue ret(UniValue::VOBJ); + if (verbose) { + ret.pushKV("name", data.name); + } + ret.pushKV("purpose", data.purpose); + return ret; +} + UniValue getaddressinfo(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); @@ -3759,6 +3785,13 @@ UniValue getaddressinfo(const JSONRPCRequest& request) " \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n" " \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n" " \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n" + " \"labels\" (object) Array of labels associated with the address.\n" + " [\n" + " { (json object of label data)\n" + " \"name\": \"labelname\" (string) The label\n" + " \"purpose\": \"string\" (string) Purpose of address (\"send\" for sending address, \"receive\" for receiving address)\n" + " },...\n" + " ]\n" "}\n" "\nExamples:\n" + HelpExampleCli("getaddressinfo", "\"1PSSGeFHDnKNxiEyFrD1wcEaHr9hrQDDWc\"") @@ -3811,6 +3844,112 @@ UniValue getaddressinfo(const JSONRPCRequest& request) ret.pushKV("hdmasterkeyid", meta->hdMasterKeyID.GetHex()); } } + + // Currently only one label can be associated with an address, return an array + // so the API remains stable if we allow multiple labels to be associated with + // an address. + UniValue labels(UniValue::VARR); + std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(dest); + if (mi != pwallet->mapAddressBook.end()) { + labels.push_back(AddressBookDataToJSON(mi->second, true)); + } + ret.pushKV("labels", std::move(labels)); + + return ret; +} + +UniValue getaddressesbylabel(const JSONRPCRequest& request) +{ + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + if (request.fHelp || request.params.size() != 1) + throw std::runtime_error( + "getaddressesbylabel \"label\"\n" + "\nReturns the list of addresses assigned the specified label.\n" + "\nArguments:\n" + "1. \"label\" (string, required) The label.\n" + "\nResult:\n" + "{ (json object with addresses as keys)\n" + " \"address\": { (json object with information about address)\n" + " \"purpose\": \"string\" (string) Purpose of address (\"send\" for sending address, \"receive\" for receiving address)\n" + " },...\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getaddressesbylabel", "\"tabby\"") + + HelpExampleRpc("getaddressesbylabel", "\"tabby\"") + ); + + LOCK(pwallet->cs_wallet); + + std::string label = LabelFromValue(request.params[0]); + + // Find all addresses that have the given label + UniValue ret(UniValue::VOBJ); + for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) { + if (item.second.name == label) { + ret.pushKV(EncodeDestination(item.first), AddressBookDataToJSON(item.second, false)); + } + } + + if (ret.empty()) { + throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, std::string("No addresses with label " + label)); + } + + return ret; +} + +UniValue listlabels(const JSONRPCRequest& request) +{ + CWallet * const pwallet = GetWalletForJSONRPCRequest(request); + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + if (request.fHelp || request.params.size() > 1) + throw std::runtime_error( + "listlabels ( \"purpose\" )\n" + "\nReturns the list of all labels, or labels that are assigned to addresses with a specific purpose.\n" + "\nArguments:\n" + "1. \"purpose\" (string, optional) Address purpose to list labels for ('send','receive'). An empty string is the same as not providing this argument.\n" + "\nResult:\n" + "[ (json array of string)\n" + " \"label\", (string) Label name\n" + " ...\n" + "]\n" + "\nExamples:\n" + "\nList all labels\n" + + HelpExampleCli("listlabels", "") + + "\nList labels that have receiving addresses\n" + + HelpExampleCli("listlabels", "receive") + + "\nList labels that have sending addresses\n" + + HelpExampleCli("listlabels", "send") + + "\nAs json rpc call\n" + + HelpExampleRpc("listlabels", "receive") + ); + + LOCK(pwallet->cs_wallet); + + std::string purpose; + if (!request.params[0].isNull()) { + purpose = request.params[0].get_str(); + } + + // Add to a set to sort by label name, then insert into Univalue array + std::set<std::string> label_set; + for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) { + if (purpose.empty() || entry.second.purpose == purpose) { + label_set.insert(entry.second.name); + } + } + + UniValue ret(UniValue::VARR); + for (const std::string& name : label_set) { + ret.push_back(name); + } + return ret; } @@ -3840,16 +3979,10 @@ static const CRPCCommand commands[] = { "wallet", "dumpprivkey", &dumpprivkey, {"address"} }, { "wallet", "dumpwallet", &dumpwallet, {"filename"} }, { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} }, - { "wallet", "getlabeladdress", &getlabeladdress, {"label"} }, - { "wallet", "getaccountaddress", &getlabeladdress, {"account"} }, - { "wallet", "getaccount", &getaccount, {"address"} }, - { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} }, { "wallet", "getaddressinfo", &getaddressinfo, {"address"} }, { "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} }, { "wallet", "getnewaddress", &getnewaddress, {"label|account","address_type"} }, { "wallet", "getrawchangeaddress", &getrawchangeaddress, {"address_type"} }, - { "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf"} }, - { "wallet", "getreceivedbyaccount", &getreceivedbylabel, {"account","minconf"} }, { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} }, { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} }, { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} }, @@ -3861,7 +3994,6 @@ static const CRPCCommand commands[] = { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} }, { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} }, { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} }, - { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} }, { "wallet", "listaddressgroupings", &listaddressgroupings, {} }, { "wallet", "listlockunspent", &listlockunspent, {} }, { "wallet", "listreceivedbylabel", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} }, @@ -3872,12 +4004,9 @@ static const CRPCCommand commands[] = { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} }, { "wallet", "listwallets", &listwallets, {} }, { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} }, - { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} }, { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} }, { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} }, { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} }, - { "wallet", "setlabel", &setlabel, {"address","label"} }, - { "wallet", "setaccount", &setlabel, {"address","account"} }, { "wallet", "settxfee", &settxfee, {"amount"} }, { "wallet", "signmessage", &signmessage, {"address","message"} }, { "wallet", "signrawtransactionwithwallet", &signrawtransactionwithwallet, {"hexstring","prevtxs","sighashtype"} }, @@ -3887,6 +4016,24 @@ static const CRPCCommand commands[] = { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} }, { "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} }, + /** Account functions (deprecated) */ + { "wallet", "getaccountaddress", &getlabeladdress, {"account"} }, + { "wallet", "getaccount", &getaccount, {"address"} }, + { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} }, + { "wallet", "getreceivedbyaccount", &getreceivedbylabel, {"account","minconf"} }, + { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} }, + { "wallet", "listreceivedbyaccount", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} }, + { "wallet", "setaccount", &setlabel, {"address","account"} }, + { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} }, + + /** Label functions (to replace non-balance account functions) */ + { "wallet", "getlabeladdress", &getlabeladdress, {"label","force"} }, + { "wallet", "getaddressesbylabel", &getaddressesbylabel, {"label"} }, + { "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf"} }, + { "wallet", "listlabels", &listlabels, {"purpose"} }, + { "wallet", "listreceivedbylabel", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} }, + { "wallet", "setlabel", &setlabel, {"address","label"} }, + { "generating", "generate", &generate, {"nblocks","maxtries"} }, }; diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 727c6caf96..14c5ad7214 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -156,8 +156,8 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) ::importwallet(request); LOCK(wallet.cs_wallet); - BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3); - BOOST_CHECK_EQUAL(coinbaseTxns.size(), 103); + BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U); + BOOST_CHECK_EQUAL(coinbaseTxns.size(), 103U); for (size_t i = 0; i < coinbaseTxns.size(); ++i) { bool found = wallet.GetWalletTx(coinbaseTxns[i].GetHash()); bool expected = i >= 100; @@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(LoadReceiveRequests) m_wallet.AddDestData(dest, "rr1", "val_rr1"); auto values = m_wallet.GetDestValues("rr"); - BOOST_CHECK_EQUAL(values.size(), 2); + BOOST_CHECK_EQUAL(values.size(), 2U); BOOST_CHECK_EQUAL(values[0], "val_rr0"); BOOST_CHECK_EQUAL(values[1], "val_rr1"); } @@ -318,9 +318,9 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) // Confirm ListCoins initially returns 1 coin grouped under coinbaseKey // address. auto list = wallet->ListCoins(); - BOOST_CHECK_EQUAL(list.size(), 1); + BOOST_CHECK_EQUAL(list.size(), 1U); BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress); - BOOST_CHECK_EQUAL(list.begin()->second.size(), 1); + BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U); // Check initial balance from one mature coinbase transaction. BOOST_CHECK_EQUAL(50 * COIN, wallet->GetAvailableBalance()); @@ -331,16 +331,16 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) // pubkey. AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, false /* subtract fee */}); list = wallet->ListCoins(); - BOOST_CHECK_EQUAL(list.size(), 1); + BOOST_CHECK_EQUAL(list.size(), 1U); BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress); - BOOST_CHECK_EQUAL(list.begin()->second.size(), 2); + BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U); // Lock both coins. Confirm number of available coins drops to 0. { LOCK2(cs_main, wallet->cs_wallet); std::vector<COutput> available; wallet->AvailableCoins(available); - BOOST_CHECK_EQUAL(available.size(), 2); + BOOST_CHECK_EQUAL(available.size(), 2U); } for (const auto& group : list) { for (const auto& coin : group.second) { @@ -352,14 +352,14 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) LOCK2(cs_main, wallet->cs_wallet); std::vector<COutput> available; wallet->AvailableCoins(available); - BOOST_CHECK_EQUAL(available.size(), 0); + BOOST_CHECK_EQUAL(available.size(), 0U); } // Confirm ListCoins still returns same result as before, despite coins // being locked. list = wallet->ListCoins(); - BOOST_CHECK_EQUAL(list.size(), 1); + BOOST_CHECK_EQUAL(list.size(), 1U); BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress); - BOOST_CHECK_EQUAL(list.begin()->second.size(), 2); + BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4308b6d0e8..7d46f02745 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1714,6 +1714,9 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock CBlockIndex* pindex = pindexStart; CBlockIndex* ret = nullptr; + + if (pindex) LogPrintf("Rescan started from block %d...\n", pindex->nHeight); + { fAbortRescan = false; ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup @@ -3640,6 +3643,12 @@ std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) co return result; } +void CWallet::DeleteLabel(const std::string& label) +{ + WalletBatch batch(*database); + batch.EraseAccount(label); +} + bool CReserveKey::GetReservedKey(CPubKey& pubkey, bool internal) { if (nIndex == -1) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d66e3e481d..b85f374a06 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -549,7 +549,7 @@ public: }; /** - * Internal transfers. + * DEPRECATED Internal transfers. * Database key is acentry<account><counter>. */ class CAccountingEntry @@ -989,6 +989,7 @@ public: std::map<CTxDestination, CAmount> GetAddressBalances(); std::set<CTxDestination> GetLabelAddresses(const std::string& label) const; + void DeleteLabel(const std::string& label); isminetype IsMine(const CTxIn& txin) const; /** @@ -1184,7 +1185,7 @@ public: /** - * Account information. + * DEPRECATED Account information. * Stored in wallet with key "acc"+string account name. */ class CAccount diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 57261bb922..803cc5f0a0 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -161,6 +161,11 @@ bool WalletBatch::WriteAccount(const std::string& strAccount, const CAccount& ac return WriteIC(std::make_pair(std::string("acc"), strAccount), account); } +bool WalletBatch::EraseAccount(const std::string& strAccount) +{ + return EraseIC(std::make_pair(std::string("acc"), strAccount)); +} + bool WalletBatch::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry) { return WriteIC(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 040aa092e1..a73d727c0c 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -204,6 +204,7 @@ public: bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry); bool ReadAccount(const std::string& strAccount, CAccount& account); bool WriteAccount(const std::string& strAccount, const CAccount& account); + bool EraseAccount(const std::string& strAccount); /// Write destination data key,value tuple to database bool WriteDestData(const std::string &address, const std::string &key, const std::string &value); diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py index eb6747c6f4..8c754807e6 100755 --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -48,8 +48,8 @@ class WalletHDTest(BitcoinTestFramework): # Also send funds to each add self.nodes[0].generate(101) hd_add = None - num_hd_adds = 300 - for i in range(num_hd_adds): + NUM_HD_ADDS = 10 + for i in range(NUM_HD_ADDS): hd_add = self.nodes[1].getnewaddress() hd_info = self.nodes[1].getaddressinfo(hd_add) assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i)+"'") @@ -65,7 +65,7 @@ class WalletHDTest(BitcoinTestFramework): assert_equal(change_addrV["hdkeypath"], "m/0'/1'/1'") #second internal child key self.sync_all() - assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) self.log.info("Restore backup ...") self.stop_node(1) @@ -78,10 +78,10 @@ class WalletHDTest(BitcoinTestFramework): # Assert that derivation is deterministic hd_add_2 = None - for _ in range(num_hd_adds): + for i in range(NUM_HD_ADDS): hd_add_2 = self.nodes[1].getnewaddress() hd_info_2 = self.nodes[1].getaddressinfo(hd_add_2) - assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_)+"'") + assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(i)+"'") assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid) assert_equal(hd_add, hd_add_2) connect_nodes_bi(self.nodes, 0, 1) @@ -90,7 +90,7 @@ class WalletHDTest(BitcoinTestFramework): # Needs rescan self.stop_node(1) self.start_node(1, extra_args=self.extra_args[1] + ['-rescan']) - assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) # Try a RPC based rescan self.stop_node(1) @@ -100,13 +100,15 @@ class WalletHDTest(BitcoinTestFramework): self.start_node(1, extra_args=self.extra_args[1]) connect_nodes_bi(self.nodes, 0, 1) self.sync_all() + # Wallet automatically scans blocks older than key on startup + assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) out = self.nodes[1].rescanblockchain(0, 1) assert_equal(out['start_height'], 0) assert_equal(out['stop_height'], 1) out = self.nodes[1].rescanblockchain() assert_equal(out['start_height'], 0) assert_equal(out['stop_height'], self.nodes[1].getblockcount()) - assert_equal(self.nodes[1].getbalance(), num_hd_adds + 1) + assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) # send a tx and make sure its using the internal chain for the changeoutput txid = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1) diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py index b2695e681f..90eefc0438 100755 --- a/test/functional/wallet_labels.py +++ b/test/functional/wallet_labels.py @@ -12,6 +12,7 @@ RPCs tested are: - sendfrom (with account arguments) - move (with account arguments) """ +from collections import defaultdict from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal @@ -78,9 +79,12 @@ class WalletLabelsTest(BitcoinTestFramework): # recognize the label/address associations. labels = [Label(name) for name in ("a", "b", "c", "d", "e")] for label in labels: - label.add_receive_address(node.getlabeladdress(label.name)) + label.add_receive_address(node.getlabeladdress(label=label.name, force=True)) label.verify(node) + # Check all labels are returned by listlabels. + assert_equal(node.listlabels(), [label.name for label in labels]) + # Send a transaction to each label, and make sure this forces # getlabeladdress to generate a new receiving address. for label in labels: @@ -115,7 +119,7 @@ class WalletLabelsTest(BitcoinTestFramework): # Check that setlabel can assign a label to a new unused address. for label in labels: - address = node.getlabeladdress("") + address = node.getlabeladdress(label="", force=True) node.setlabel(address, label.name) label.add_address(address) label.verify(node) @@ -128,6 +132,7 @@ class WalletLabelsTest(BitcoinTestFramework): addresses.append(node.getnewaddress()) multisig_address = node.addmultisigaddress(5, addresses, label.name)['address'] label.add_address(multisig_address) + label.purpose[multisig_address] = "send" label.verify(node) node.sendfrom("", multisig_address, 50) node.generate(101) @@ -147,9 +152,7 @@ class WalletLabelsTest(BitcoinTestFramework): change_label(node, labels[2].addresses[0], labels[2], labels[2]) # Check that setlabel can set the label of an address which is - # already the receiving address of the label. It would probably make - # sense for this to be a no-op, but right now it resets the receiving - # address, causing getlabeladdress to return a brand new address. + # already the receiving address of the label. This is a no-op. change_label(node, labels[2].receive_address, labels[2], labels[2]) class Label: @@ -160,6 +163,8 @@ class Label: self.receive_address = None # List of all addresses assigned with this label self.addresses = [] + # Map of address to address purpose + self.purpose = defaultdict(lambda: "receive") def add_address(self, address): assert_equal(address not in self.addresses, True) @@ -175,9 +180,16 @@ class Label: assert_equal(node.getlabeladdress(self.name), self.receive_address) for address in self.addresses: + assert_equal( + node.getaddressinfo(address)['labels'][0], + {"name": self.name, + "purpose": self.purpose[address]}) assert_equal(node.getaccount(address), self.name) assert_equal( + node.getaddressesbylabel(self.name), + {address: {"purpose": self.purpose[address]} for address in self.addresses}) + assert_equal( set(node.getaddressesbyaccount(self.name)), set(self.addresses)) @@ -192,7 +204,7 @@ def change_label(node, address, old_label, new_label): # address of a different label should reset the receiving address of # the old label, causing getlabeladdress to return a brand new # address. - if address == old_label.receive_address: + if old_label.name != new_label.name and address == old_label.receive_address: new_address = node.getlabeladdress(old_label.name) assert_equal(new_address not in old_label.addresses, True) assert_equal(new_address not in new_label.addresses, True) diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py index a4754852ed..7b34febddc 100755 --- a/test/functional/wallet_listreceivedby.py +++ b/test/functional/wallet_listreceivedby.py @@ -140,7 +140,7 @@ class ReceivedByTest(BitcoinTestFramework): assert_equal(balance, balance_by_label + Decimal("0.1")) # Create a new label named "mynewlabel" that has a 0 balance - self.nodes[1].getlabeladdress("mynewlabel") + self.nodes[1].getlabeladdress(label="mynewlabel", force=True) received_by_label_json = [r for r in self.nodes[1].listreceivedbylabel(0, True) if r["label"] == "mynewlabel"][0] # Test includeempty of listreceivedbylabel |