diff options
Diffstat (limited to 'src/test')
68 files changed, 761 insertions, 393 deletions
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp index d438537606..49b40924e0 100644 --- a/src/test/addrman_tests.cpp +++ b/src/test/addrman_tests.cpp @@ -12,6 +12,7 @@ #include <boost/test/unit_test.hpp> +#include <optional> #include <string> class CAddrManTest : public CAddrMan @@ -392,7 +393,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) // Test: Sanity check, GetAddr should never return anything if addrman // is empty. BOOST_CHECK_EQUAL(addrman.size(), 0U); - std::vector<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */0); + std::vector<CAddress> vAddr1 = addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt); BOOST_CHECK_EQUAL(vAddr1.size(), 0U); CAddress addr1 = CAddress(ResolveService("250.250.2.1", 8333), NODE_NONE); @@ -415,15 +416,15 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) BOOST_CHECK(addrman.Add(addr4, source2)); BOOST_CHECK(addrman.Add(addr5, source1)); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U); // Net processing asks for 23% of addresses. 23% of 5 is 1 rounded down. - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).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(/* max_addresses */ 0, /* max_pct */ 0).size(), 5U); - BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23).size(), 1U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 0, /* max_pct */ 0, /* network */ std::nullopt).size(), 5U); + BOOST_CHECK_EQUAL(addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt).size(), 1U); // Test: Ensure GetAddr still returns 23% when addrman has many addrs. for (unsigned int i = 1; i < (8 * 256); i++) { @@ -438,7 +439,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr) if (i % 8 == 0) addrman.Good(addr); } - std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23); + std::vector<CAddress> vAddr = addrman.GetAddr(/* max_addresses */ 2500, /* max_pct */ 23, /* network */ std::nullopt); size_t percent23 = (addrman.size() * 23) / 100; BOOST_CHECK_EQUAL(vAddr.size(), percent23); diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index b523173a45..3779e7b964 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -2,15 +2,18 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <support/lockedpool.h> #include <util/system.h> -#include <test/util/setup_common.h> - +#include <limits> #include <memory> +#include <stdexcept> +#include <utility> +#include <vector> #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(allocator_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(allocator_tests) BOOST_AUTO_TEST_CASE(arena_tests) { diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp index 1a39498899..77b7758a17 100644 --- a/src/test/amount_tests.cpp +++ b/src/test/amount_tests.cpp @@ -4,11 +4,12 @@ #include <amount.h> #include <policy/feerate.h> -#include <test/util/setup_common.h> + +#include <limits> #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(amount_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(amount_tests) BOOST_AUTO_TEST_CASE(MoneyRangeTest) { @@ -83,7 +84,7 @@ BOOST_AUTO_TEST_CASE(GetFeeTest) BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32)); BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34)); // Maximum size in bytes, should not crash - CFeeRate(MAX_MONEY, std::numeric_limits<size_t>::max() >> 1).GetFeePerK(); + CFeeRate(MAX_MONEY, std::numeric_limits<uint32_t>::max()).GetFeePerK(); } BOOST_AUTO_TEST_CASE(BinaryOperatorTest) diff --git a/src/test/arith_uint256_tests.cpp b/src/test/arith_uint256_tests.cpp index a135c93786..a00888aae6 100644 --- a/src/test/arith_uint256_tests.cpp +++ b/src/test/arith_uint256_tests.cpp @@ -3,19 +3,19 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <arith_uint256.h> -#include <test/util/setup_common.h> #include <uint256.h> #include <boost/test/unit_test.hpp> #include <cmath> +#include <cstdint> #include <iomanip> #include <limits> #include <sstream> -#include <stdint.h> #include <string> +#include <vector> -BOOST_FIXTURE_TEST_SUITE(arith_uint256_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(arith_uint256_tests) /// Convert vector to arith_uint256, via uint256 blob static inline arith_uint256 arith_uint256V(const std::vector<unsigned char>& vch) diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index 3b44564ddb..22853555e2 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <test/util/setup_common.h> #include <util/strencodings.h> #include <boost/test/unit_test.hpp> @@ -10,7 +9,7 @@ using namespace std::literals; -BOOST_FIXTURE_TEST_SUITE(base32_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(base32_tests) BOOST_AUTO_TEST_CASE(base32_testvectors) { diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index dd760fe999..a090cb340b 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -16,7 +16,7 @@ using namespace std::literals; -extern UniValue read_json(const std::string& jsondata); +UniValue read_json(const std::string& jsondata); BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index 714fccffaa..9d1dfd46f1 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <test/util/setup_common.h> #include <util/strencodings.h> #include <boost/test/unit_test.hpp> @@ -10,7 +9,7 @@ using namespace std::literals; -BOOST_FIXTURE_TEST_SUITE(base64_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(base64_tests) BOOST_AUTO_TEST_CASE(base64_testvectors) { diff --git a/src/test/bech32_tests.cpp b/src/test/bech32_tests.cpp index 2651e46430..c0344b3cbb 100644 --- a/src/test/bech32_tests.cpp +++ b/src/test/bech32_tests.cpp @@ -3,12 +3,13 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <bech32.h> -#include <test/util/setup_common.h> #include <test/util/str.h> #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(bech32_tests, BasicTestingSetup) +#include <string> + +BOOST_AUTO_TEST_SUITE(bech32_tests) BOOST_AUTO_TEST_CASE(bech32_testvectors_valid) { diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index 32329eb510..fb16c92647 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2020 The Bitcoin Core developers +// Copyright (c) 2013-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -87,6 +87,18 @@ TestVector test3 = "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L", 0); +TestVector test4 = + TestVector("3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678") + ("xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa", + "xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv", + 0x80000000) + ("xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m", + "xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G", + 0x80000001) + ("xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt", + "xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1", + 0); + static void RunTest(const TestVector &test) { std::vector<unsigned char> seed = ParseHex(test.strHexMaster); CExtKey key; @@ -135,4 +147,8 @@ BOOST_AUTO_TEST_CASE(bip32_test3) { RunTest(test3); } +BOOST_AUTO_TEST_CASE(bip32_test4) { + RunTest(test4); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp index 9903ba75cb..2f532ef598 100644 --- a/src/test/blockfilter_index_tests.cpp +++ b/src/test/blockfilter_index_tests.cpp @@ -131,7 +131,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup) // BlockUntilSyncedToCurrentChain should return false before index is started. BOOST_CHECK(!filter_index.BlockUntilSyncedToCurrentChain()); - filter_index.Start(); + BOOST_REQUIRE(filter_index.Start(::ChainstateActive())); // Allow filter index to catch up with the block index. constexpr int64_t timeout_ms = 10 * 1000; diff --git a/src/test/bswap_tests.cpp b/src/test/bswap_tests.cpp index 2dbca4e8b6..4e75e74d77 100644 --- a/src/test/bswap_tests.cpp +++ b/src/test/bswap_tests.cpp @@ -3,11 +3,10 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <compat/byteswap.h> -#include <test/util/setup_common.h> #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(bswap_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(bswap_tests) BOOST_AUTO_TEST_CASE(bswap_tests) { diff --git a/src/test/coinstatsindex_tests.cpp b/src/test/coinstatsindex_tests.cpp index 3fc7b72077..106fcd2a33 100644 --- a/src/test/coinstatsindex_tests.cpp +++ b/src/test/coinstatsindex_tests.cpp @@ -32,7 +32,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup) // is started. BOOST_CHECK(!coin_stats_index.BlockUntilSyncedToCurrentChain()); - coin_stats_index.Start(); + BOOST_REQUIRE(coin_stats_index.Start(::ChainstateActive())); // Allow the CoinStatsIndex to catch up with the block index that is syncing // in a background thread. diff --git a/src/test/compilerbug_tests.cpp b/src/test/compilerbug_tests.cpp index b68bc279e1..a9cec624ae 100644 --- a/src/test/compilerbug_tests.cpp +++ b/src/test/compilerbug_tests.cpp @@ -3,9 +3,8 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <boost/test/unit_test.hpp> -#include <test/util/setup_common.h> -BOOST_FIXTURE_TEST_SUITE(compilerbug_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(compilerbug_tests) #if defined(__GNUC__) // This block will also be built under clang, which is fine (as it supports noinline) diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index b5f3bb2fa4..b6f5938892 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -26,9 +26,9 @@ BOOST_AUTO_TEST_CASE(dbwrapper) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_obfuscate_true" : "dbwrapper_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_obfuscate_true" : "dbwrapper_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); - char key = 'k'; + uint8_t key{'k'}; uint256 in = InsecureRand256(); uint256 res; @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_basic_data) { // Perform tests both obfuscated and non-obfuscated. for (bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_1_obfuscate_true" : "dbwrapper_1_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_1_obfuscate_true" : "dbwrapper_1_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), false, true, obfuscate); uint256 res; @@ -88,21 +88,21 @@ BOOST_AUTO_TEST_CASE(dbwrapper_basic_data) BOOST_CHECK_EQUAL(res.ToString(), in_utxo.ToString()); //Simulate last block file number - "l" - char key_last_blockfile_number = 'l'; + uint8_t key_last_blockfile_number{'l'}; uint32_t lastblockfilenumber = InsecureRand32(); BOOST_CHECK(dbw.Write(key_last_blockfile_number, lastblockfilenumber)); BOOST_CHECK(dbw.Read(key_last_blockfile_number, res_uint_32)); BOOST_CHECK_EQUAL(lastblockfilenumber, res_uint_32); //Simulate Is Reindexing - "R" - char key_IsReindexing = 'R'; + uint8_t key_IsReindexing{'R'}; bool isInReindexing = InsecureRandBool(); BOOST_CHECK(dbw.Write(key_IsReindexing, isInReindexing)); BOOST_CHECK(dbw.Read(key_IsReindexing, res_bool)); BOOST_CHECK_EQUAL(isInReindexing, res_bool); //Simulate last block hash up to which UXTO covers - 'B' - char key_lastblockhash_uxto = 'B'; + uint8_t key_lastblockhash_uxto{'B'}; uint256 lastblock_hash = InsecureRand256(); BOOST_CHECK(dbw.Write(key_lastblockhash_uxto, lastblock_hash)); BOOST_CHECK(dbw.Read(key_lastblockhash_uxto, res)); @@ -126,14 +126,14 @@ BOOST_AUTO_TEST_CASE(dbwrapper_batch) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_batch_obfuscate_true" : "dbwrapper_batch_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_batch_obfuscate_true" : "dbwrapper_batch_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); - char key = 'i'; + uint8_t key{'i'}; uint256 in = InsecureRand256(); - char key2 = 'j'; + uint8_t key2{'j'}; uint256 in2 = InsecureRand256(); - char key3 = 'k'; + uint8_t key3{'k'}; uint256 in3 = InsecureRand256(); uint256 res; @@ -162,14 +162,14 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) { // Perform tests both obfuscated and non-obfuscated. for (const bool obfuscate : {false, true}) { - fs::path ph = m_args.GetDataDirPath() / (obfuscate ? "dbwrapper_iterator_obfuscate_true" : "dbwrapper_iterator_obfuscate_false"); + fs::path ph = m_args.GetDataDirBase() / (obfuscate ? "dbwrapper_iterator_obfuscate_true" : "dbwrapper_iterator_obfuscate_false"); CDBWrapper dbw(ph, (1 << 20), true, false, obfuscate); // The two keys are intentionally chosen for ordering - char key = 'j'; + uint8_t key{'j'}; uint256 in = InsecureRand256(); BOOST_CHECK(dbw.Write(key, in)); - char key2 = 'k'; + uint8_t key2{'k'}; uint256 in2 = InsecureRand256(); BOOST_CHECK(dbw.Write(key2, in2)); @@ -178,7 +178,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) // Be sure to seek past the obfuscation key (if it exists) it->Seek(key); - char key_res; + uint8_t key_res; uint256 val_res; BOOST_REQUIRE(it->GetKey(key_res)); @@ -202,12 +202,12 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) { // We're going to share this fs::path between two wrappers - fs::path ph = m_args.GetDataDirPath() / "existing_data_no_obfuscate"; + fs::path ph = m_args.GetDataDirBase() / "existing_data_no_obfuscate"; create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false); - char key = 'k'; + uint8_t key{'k'}; uint256 in = InsecureRand256(); uint256 res; @@ -243,12 +243,12 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) BOOST_AUTO_TEST_CASE(existing_data_reindex) { // We're going to share this fs::path between two wrappers - fs::path ph = m_args.GetDataDirPath() / "existing_data_reindex"; + fs::path ph = m_args.GetDataDirBase() / "existing_data_reindex"; create_directories(ph); // Set up a non-obfuscated wrapper to write some initial data. std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false); - char key = 'k'; + uint8_t key{'k'}; uint256 in = InsecureRand256(); uint256 res; @@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) BOOST_AUTO_TEST_CASE(iterator_ordering) { - fs::path ph = m_args.GetDataDirPath() / "iterator_ordering"; + fs::path ph = m_args.GetDataDirBase() / "iterator_ordering"; CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<256; ++x) { uint8_t key = x; @@ -334,7 +334,7 @@ struct StringContentsSerializer { void Serialize(Stream& s) const { for (size_t i = 0; i < str.size(); i++) { - s << str[i]; + s << uint8_t(str[i]); } } @@ -342,7 +342,7 @@ struct StringContentsSerializer { void Unserialize(Stream& s) { str.clear(); - char c = 0; + uint8_t c{0}; while (true) { try { s >> c; @@ -358,7 +358,7 @@ BOOST_AUTO_TEST_CASE(iterator_string_ordering) { char buf[10]; - fs::path ph = m_args.GetDataDirPath() / "iterator_string_ordering"; + fs::path ph = m_args.GetDataDirBase() / "iterator_string_ordering"; CDBWrapper dbw(ph, (1 << 20), true, false, false); for (int x=0x00; x<10; ++x) { for (int y = 0; y < 10; y++) { @@ -404,7 +404,7 @@ BOOST_AUTO_TEST_CASE(unicodepath) // On Windows this test will fail if the directory is created using // the ANSI CreateDirectoryA call and the code page isn't UTF8. // It will succeed if created with CreateDirectoryW. - fs::path ph = m_args.GetDataDirPath() / "test_runner_₿_🏃_20191128_104644"; + fs::path ph = m_args.GetDataDirBase() / "test_runner_₿_🏃_20191128_104644"; CDBWrapper dbw(ph, (1 << 20)); fs::path lockPath = ph / "LOCK"; diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index ddf0e0ca90..a56ce51acb 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) BOOST_AUTO_TEST_CASE(peer_discouragement) { const CChainParams& chainparams = Params(); - auto banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); + auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique<CConnmanTest>(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); @@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement) BOOST_AUTO_TEST_CASE(DoS_bantime) { const CChainParams& chainparams = Params(); - auto banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); + auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool, false); diff --git a/src/test/flatfile_tests.cpp b/src/test/flatfile_tests.cpp index 9194ed8130..f4bc320f3c 100644 --- a/src/test/flatfile_tests.cpp +++ b/src/test/flatfile_tests.cpp @@ -14,7 +14,7 @@ BOOST_FIXTURE_TEST_SUITE(flatfile_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(flatfile_filename) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFilePos pos(456, 789); @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(flatfile_filename) BOOST_AUTO_TEST_CASE(flatfile_open) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFileSeq seq(data_dir, "a", 16 * 1024); std::string line1("A purely peer-to-peer version of electronic cash would allow online " @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(flatfile_open) BOOST_AUTO_TEST_CASE(flatfile_allocate) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFileSeq seq(data_dir, "a", 100); bool out_of_space; @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(flatfile_allocate) BOOST_AUTO_TEST_CASE(flatfile_flush) { - const auto data_dir = m_args.GetDataDirPath(); + const auto data_dir = m_args.GetDataDirBase(); FlatFileSeq seq(data_dir, "a", 100); bool out_of_space; diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp index 452bc06bbb..526a3c27be 100644 --- a/src/test/fs_tests.cpp +++ b/src/test/fs_tests.cpp @@ -13,7 +13,7 @@ BOOST_FIXTURE_TEST_SUITE(fs_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(fsbridge_fstream) { - fs::path tmpfolder = m_args.GetDataDirPath(); + fs::path tmpfolder = m_args.GetDataDirBase(); // tmpfile1 should be the same as tmpfile2 fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃"; fs::path tmpfile2 = tmpfolder / "fs_tests_₿_🏃"; diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp index 0baf30aef6..98ae32a8d0 100644 --- a/src/test/fuzz/addrman.cpp +++ b/src/test/fuzz/addrman.cpp @@ -60,7 +60,10 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman) (void)addr_man.Select(fuzzed_data_provider.ConsumeBool()); }, [&] { - (void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096)); + (void)addr_man.GetAddr( + /* max_addresses */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), + /* max_pct */ fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), + /* network */ std::nullopt); }, [&] { const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider); diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp index 8bf484722c..759a70a857 100644 --- a/src/test/fuzz/banman.cpp +++ b/src/test/fuzz/banman.cpp @@ -32,13 +32,17 @@ void initialize_banman() FUZZ_TARGET_INIT(banman, initialize_banman) { + // The complexity is O(N^2), where N is the input size, because each call + // might call DumpBanlist (or other methods that are at least linear + // complexity of the input size). + int limit_max_ops{300}; FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; SetMockTime(ConsumeTime(fuzzed_data_provider)); - const fs::path banlist_file = GetDataDir() / "fuzzed_banlist.dat"; + const fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist.dat"; fs::remove(banlist_file); { BanMan ban_man{banlist_file, nullptr, ConsumeBanTimeOffset(fuzzed_data_provider)}; - while (fuzzed_data_provider.ConsumeBool()) { + while (--limit_max_ops >= 0 && fuzzed_data_provider.ConsumeBool()) { CallOneOf( fuzzed_data_provider, [&] { @@ -52,7 +56,6 @@ FUZZ_TARGET_INIT(banman, initialize_banman) [&] { ban_man.ClearBanned(); }, - [] {}, [&] { ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider)); }, @@ -72,7 +75,6 @@ FUZZ_TARGET_INIT(banman, initialize_banman) [&] { ban_man.DumpBanlist(); }, - [] {}, [&] { ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider)); }); diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp index 21dc80cc8d..b509ee0b26 100644 --- a/src/test/fuzz/coins_view.cpp +++ b/src/test/fuzz/coins_view.cpp @@ -6,6 +6,7 @@ #include <chainparams.h> #include <chainparamsbase.h> #include <coins.h> +#include <consensus/tx_check.h> #include <consensus/tx_verify.h> #include <consensus/validation.h> #include <key.h> @@ -230,8 +231,14 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view) // consensus/tx_verify.cpp:171: bool Consensus::CheckTxInputs(const CTransaction &, TxValidationState &, const CCoinsViewCache &, int, CAmount &): Assertion `!coin.IsSpent()' failed. return; } - (void)Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, std::numeric_limits<int>::max()), tx_fee_out); - assert(MoneyRange(tx_fee_out)); + TxValidationState dummy; + if (!CheckTransaction(transaction, dummy)) { + // It is not allowed to call CheckTxInputs if CheckTransaction failed + return; + } + if (Consensus::CheckTxInputs(transaction, state, coins_view_cache, fuzzed_data_provider.ConsumeIntegralInRange<int>(0, std::numeric_limits<int>::max()), tx_fee_out)) { + assert(MoneyRange(tx_fee_out)); + } }, [&] { const CTransaction transaction{random_mutable_transaction}; diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp index e07f25dedf..bbec5943af 100644 --- a/src/test/fuzz/connman.cpp +++ b/src/test/fuzz/connman.cpp @@ -65,16 +65,19 @@ FUZZ_TARGET_INIT(connman, initialize_connman) connman.ForEachNode([](auto) {}); }, [&] { - connman.ForEachNodeThen([](auto) {}, []() {}); - }, - [&] { (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); }); }, [&] { - (void)connman.GetAddresses(fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>()); + (void)connman.GetAddresses( + /* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(), + /* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>(), + /* network */ std::nullopt); }, [&] { - (void)connman.GetAddresses(random_node, fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>()); + (void)connman.GetAddresses( + /* requestor */ random_node, + /* max_addresses */ fuzzed_data_provider.ConsumeIntegral<size_t>(), + /* max_pct */ fuzzed_data_provider.ConsumeIntegral<size_t>()); }, [&] { (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); diff --git a/src/test/fuzz/fee_rate.cpp b/src/test/fuzz/fee_rate.cpp index 2955213635..dff0e58000 100644 --- a/src/test/fuzz/fee_rate.cpp +++ b/src/test/fuzz/fee_rate.cpp @@ -20,8 +20,8 @@ FUZZ_TARGET(fee_rate) const CFeeRate fee_rate{satoshis_per_k}; (void)fee_rate.GetFeePerK(); - const size_t bytes = fuzzed_data_provider.ConsumeIntegral<size_t>(); - if (!MultiplicationOverflow(static_cast<int64_t>(bytes), satoshis_per_k) && bytes <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) { + const auto bytes = fuzzed_data_provider.ConsumeIntegral<uint32_t>(); + if (!MultiplicationOverflow(int64_t{bytes}, satoshis_per_k)) { (void)fee_rate.GetFee(bytes); } (void)fee_rate.ToString(); diff --git a/src/test/fuzz/float.cpp b/src/test/fuzz/float.cpp index d18a87d177..adef66a3ee 100644 --- a/src/test/fuzz/float.cpp +++ b/src/test/fuzz/float.cpp @@ -3,14 +3,14 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <memusage.h> -#include <serialize.h> -#include <streams.h> #include <test/fuzz/FuzzedDataProvider.h> #include <test/fuzz/fuzz.h> +#include <util/serfloat.h> #include <version.h> #include <cassert> -#include <cstdint> +#include <cmath> +#include <limits> FUZZ_TARGET(float) { @@ -19,24 +19,17 @@ FUZZ_TARGET(float) { const double d = fuzzed_data_provider.ConsumeFloatingPoint<double>(); (void)memusage::DynamicUsage(d); - assert(ser_uint64_to_double(ser_double_to_uint64(d)) == d); - CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); - stream << d; - double d_deserialized; - stream >> d_deserialized; - assert(d == d_deserialized); - } - - { - const float f = fuzzed_data_provider.ConsumeFloatingPoint<float>(); - (void)memusage::DynamicUsage(f); - assert(ser_uint32_to_float(ser_float_to_uint32(f)) == f); - - CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION); - stream << f; - float f_deserialized; - stream >> f_deserialized; - assert(f == f_deserialized); + uint64_t encoded = EncodeDouble(d); + if constexpr (std::numeric_limits<double>::is_iec559) { + if (!std::isnan(d)) { + uint64_t encoded_in_memory; + std::copy((const unsigned char*)&d, (const unsigned char*)(&d + 1), (unsigned char*)&encoded_in_memory); + assert(encoded_in_memory == encoded); + } + } + double d_deserialized = DecodeDouble(encoded); + assert(std::isnan(d) == std::isnan(d_deserialized)); + assert(std::isnan(d) || d == d_deserialized); } } diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp index 0d8d960d56..631c861bb6 100644 --- a/src/test/fuzz/fuzz.cpp +++ b/src/test/fuzz/fuzz.cpp @@ -4,10 +4,15 @@ #include <test/fuzz/fuzz.h> +#include <netaddress.h> +#include <netbase.h> #include <test/util/setup_common.h> #include <util/check.h> +#include <util/sock.h> #include <cstdint> +#include <exception> +#include <memory> #include <unistd.h> #include <vector> @@ -29,6 +34,9 @@ static TypeTestOneInput* g_test_one_input{nullptr}; void initialize() { + // Terminate immediately if a fuzzing harness ever tries to create a TCP socket. + CreateSock = [](const CService&) -> std::unique_ptr<Sock> { std::terminate(); }; + bool should_abort{false}; if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) { for (const auto& t : FuzzTargets()) { diff --git a/src/test/fuzz/i2p.cpp b/src/test/fuzz/i2p.cpp index 345d68502a..fb6d23aca5 100644 --- a/src/test/fuzz/i2p.cpp +++ b/src/test/fuzz/i2p.cpp @@ -30,14 +30,14 @@ FUZZ_TARGET_INIT(i2p, initialize_i2p) const CService sam_proxy; CThreadInterrupt interrupt; - i2p::sam::Session sess{GetDataDir() / "fuzzed_i2p_private_key", sam_proxy, &interrupt}; + i2p::sam::Session sess{gArgs.GetDataDirNet() / "fuzzed_i2p_private_key", sam_proxy, &interrupt}; i2p::Connection conn; if (sess.Listen(conn)) { if (sess.Accept(conn)) { try { - conn.sock->RecvUntilTerminator('\n', 10ms, interrupt, i2p::sam::MAX_MSG_SIZE); + (void)conn.sock->RecvUntilTerminator('\n', 10ms, interrupt, i2p::sam::MAX_MSG_SIZE); } catch (const std::runtime_error&) { } } diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index 5bc99ddcb9..e9fa343896 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -122,10 +122,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer) assert(dynamic_usage == incremental_dynamic_usage * i64s.size()); } (void)MillisToTimeval(i64); - const double d = ser_uint64_to_double(u64); - assert(ser_double_to_uint64(d) == u64); - const float f = ser_uint32_to_float(u32); - assert(ser_float_to_uint32(f) == u32); (void)SighashToStr(uch); (void)SipHashUint256(u64, u64, u256); (void)SipHashUint256Extra(u64, u64, u256, u32); diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp index 272f6415a9..20d8581312 100644 --- a/src/test/fuzz/net.cpp +++ b/src/test/fuzz/net.cpp @@ -58,27 +58,6 @@ FUZZ_TARGET_INIT(net, initialize_net) } }, [&] { - if (node.m_addr_known == nullptr) { - return; - } - const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider); - if (!addr_opt) { - return; - } - node.AddAddressKnown(*addr_opt); - }, - [&] { - if (node.m_addr_known == nullptr) { - return; - } - const std::optional<CAddress> addr_opt = ConsumeDeserializable<CAddress>(fuzzed_data_provider); - if (!addr_opt) { - return; - } - FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)}; - node.PushAddress(*addr_opt, fast_random_context); - }, - [&] { const std::optional<CInv> inv_opt = ConsumeDeserializable<CInv>(fuzzed_data_provider); if (!inv_opt) { return; @@ -110,7 +89,6 @@ FUZZ_TARGET_INIT(net, initialize_net) const int ref_count = node.GetRefCount(); assert(ref_count >= 0); (void)node.GetCommonVersion(); - (void)node.RelayAddrsWithConn(); const NetPermissionFlags net_permission_flags = ConsumeWeakEnum(fuzzed_data_provider, ALL_NET_PERMISSION_FLAGS); (void)node.HasPermission(net_permission_flags); diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp index 544a33047b..6ea79464d0 100644 --- a/src/test/fuzz/net_permissions.cpp +++ b/src/test/fuzz/net_permissions.cpp @@ -25,7 +25,7 @@ FUZZ_TARGET(net_permissions) (void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags); (void)NetPermissions::AddFlag(net_whitebind_permissions.m_flags, net_permission_flags); assert(NetPermissions::HasFlag(net_whitebind_permissions.m_flags, net_permission_flags)); - (void)NetPermissions::ClearFlag(net_whitebind_permissions.m_flags, net_permission_flags); + (void)NetPermissions::ClearFlag(net_whitebind_permissions.m_flags, NetPermissionFlags::Implicit); (void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags); } @@ -35,7 +35,7 @@ FUZZ_TARGET(net_permissions) (void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags); (void)NetPermissions::AddFlag(net_whitelist_permissions.m_flags, net_permission_flags); assert(NetPermissions::HasFlag(net_whitelist_permissions.m_flags, net_permission_flags)); - (void)NetPermissions::ClearFlag(net_whitelist_permissions.m_flags, net_permission_flags); + (void)NetPermissions::ClearFlag(net_whitelist_permissions.m_flags, NetPermissionFlags::Implicit); (void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags); } } diff --git a/src/test/fuzz/p2p_transport_deserializer.cpp b/src/test/fuzz/p2p_transport_deserializer.cpp deleted file mode 100644 index 3a1fdaad8f..0000000000 --- a/src/test/fuzz/p2p_transport_deserializer.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2019-2020 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 <chainparams.h> -#include <net.h> -#include <protocol.h> -#include <test/fuzz/fuzz.h> - -#include <cassert> -#include <cstdint> -#include <limits> -#include <optional> -#include <vector> - -void initialize_p2p_transport_deserializer() -{ - SelectParams(CBaseChainParams::REGTEST); -} - -FUZZ_TARGET_INIT(p2p_transport_deserializer, initialize_p2p_transport_deserializer) -{ - // Construct deserializer, with a dummy NodeId - V1TransportDeserializer deserializer{Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION}; - Span<const uint8_t> msg_bytes{buffer}; - while (msg_bytes.size() > 0) { - const int handled = deserializer.Read(msg_bytes); - if (handled < 0) { - break; - } - if (deserializer.Complete()) { - const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()}; - uint32_t out_err_raw_size{0}; - std::optional<CNetMessage> result{deserializer.GetMessage(m_time, out_err_raw_size)}; - if (result) { - assert(result->m_command.size() <= CMessageHeader::COMMAND_SIZE); - assert(result->m_raw_message_size <= buffer.size()); - assert(result->m_raw_message_size == CMessageHeader::HEADER_SIZE + result->m_message_size); - assert(result->m_time == m_time); - } - } - } -} diff --git a/src/test/fuzz/p2p_transport_serialization.cpp b/src/test/fuzz/p2p_transport_serialization.cpp new file mode 100644 index 0000000000..edee5aeef7 --- /dev/null +++ b/src/test/fuzz/p2p_transport_serialization.cpp @@ -0,0 +1,85 @@ +// Copyright (c) 2019-2020 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 <chainparams.h> +#include <hash.h> +#include <net.h> +#include <netmessagemaker.h> +#include <protocol.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> + +#include <cassert> +#include <cstdint> +#include <limits> +#include <optional> +#include <vector> + +void initialize_p2p_transport_serialization() +{ + SelectParams(CBaseChainParams::REGTEST); +} + +FUZZ_TARGET_INIT(p2p_transport_serialization, initialize_p2p_transport_serialization) +{ + // Construct deserializer, with a dummy NodeId + V1TransportDeserializer deserializer{Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION}; + V1TransportSerializer serializer{}; + FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()}; + + auto checksum_assist = fuzzed_data_provider.ConsumeBool(); + auto magic_bytes_assist = fuzzed_data_provider.ConsumeBool(); + std::vector<uint8_t> mutable_msg_bytes; + + auto header_bytes_remaining = CMessageHeader::HEADER_SIZE; + if (magic_bytes_assist) { + auto msg_start = Params().MessageStart(); + for (size_t i = 0; i < CMessageHeader::MESSAGE_SIZE_SIZE; ++i) { + mutable_msg_bytes.push_back(msg_start[i]); + } + header_bytes_remaining -= CMessageHeader::MESSAGE_SIZE_SIZE; + } + + if (checksum_assist) { + header_bytes_remaining -= CMessageHeader::CHECKSUM_SIZE; + } + + auto header_random_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(header_bytes_remaining); + mutable_msg_bytes.insert(mutable_msg_bytes.end(), header_random_bytes.begin(), header_random_bytes.end()); + auto payload_bytes = fuzzed_data_provider.ConsumeRemainingBytes<uint8_t>(); + + if (checksum_assist && mutable_msg_bytes.size() == CMessageHeader::CHECKSUM_OFFSET) { + CHash256 hasher; + unsigned char hsh[32]; + hasher.Write(payload_bytes); + hasher.Finalize(hsh); + for (size_t i = 0; i < CMessageHeader::CHECKSUM_SIZE; ++i) { + mutable_msg_bytes.push_back(hsh[i]); + } + } + + mutable_msg_bytes.insert(mutable_msg_bytes.end(), payload_bytes.begin(), payload_bytes.end()); + Span<const uint8_t> msg_bytes{mutable_msg_bytes}; + while (msg_bytes.size() > 0) { + const int handled = deserializer.Read(msg_bytes); + if (handled < 0) { + break; + } + if (deserializer.Complete()) { + const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()}; + uint32_t out_err_raw_size{0}; + std::optional<CNetMessage> result{deserializer.GetMessage(m_time, out_err_raw_size)}; + if (result) { + assert(result->m_command.size() <= CMessageHeader::COMMAND_SIZE); + assert(result->m_raw_message_size <= mutable_msg_bytes.size()); + assert(result->m_raw_message_size == CMessageHeader::HEADER_SIZE + result->m_message_size); + assert(result->m_time == m_time); + + std::vector<unsigned char> header; + auto msg = CNetMsgMaker{result->m_recv.GetVersion()}.Make(result->m_command, MakeUCharSpan(result->m_recv)); + serializer.prepareForTransport(msg, header); + } + } + } +} diff --git a/src/test/fuzz/rpc.cpp b/src/test/fuzz/rpc.cpp index cf32a79932..9195cc4873 100644 --- a/src/test/fuzz/rpc.cpp +++ b/src/test/fuzz/rpc.cpp @@ -168,6 +168,7 @@ const std::vector<std::string> RPC_COMMANDS_SAFE_FOR_FUZZING{ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider) { const size_t max_string_length = 4096; + const size_t max_base58_bytes_length{64}; std::string r; CallOneOf( fuzzed_data_provider, @@ -221,11 +222,11 @@ std::string ConsumeScalarRPCArgument(FuzzedDataProvider& fuzzed_data_provider) }, [&] { // base58 argument - r = EncodeBase58(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_string_length))); + r = EncodeBase58(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_base58_bytes_length))); }, [&] { // base58 argument with checksum - r = EncodeBase58Check(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_string_length))); + r = EncodeBase58Check(MakeUCharSpan(fuzzed_data_provider.ConsumeRandomLengthString(max_base58_bytes_length))); }, [&] { // hex encoded block diff --git a/src/test/fuzz/script_ops.cpp b/src/test/fuzz/script_ops.cpp index eb1c808a88..4bc709ed35 100644 --- a/src/test/fuzz/script_ops.cpp +++ b/src/test/fuzz/script_ops.cpp @@ -14,55 +14,54 @@ FUZZ_TARGET(script_ops) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); - CScript script = ConsumeScript(fuzzed_data_provider); + CScript script_mut = ConsumeScript(fuzzed_data_provider); while (fuzzed_data_provider.remaining_bytes() > 0) { CallOneOf( fuzzed_data_provider, [&] { CScript s = ConsumeScript(fuzzed_data_provider); - script = std::move(s); + script_mut = std::move(s); }, [&] { const CScript& s = ConsumeScript(fuzzed_data_provider); - script = s; + script_mut = s; }, [&] { - script << fuzzed_data_provider.ConsumeIntegral<int64_t>(); + script_mut << fuzzed_data_provider.ConsumeIntegral<int64_t>(); }, [&] { - script << ConsumeOpcodeType(fuzzed_data_provider); + script_mut << ConsumeOpcodeType(fuzzed_data_provider); }, [&] { - script << ConsumeScriptNum(fuzzed_data_provider); + script_mut << ConsumeScriptNum(fuzzed_data_provider); }, [&] { - script << ConsumeRandomLengthByteVector(fuzzed_data_provider); + script_mut << ConsumeRandomLengthByteVector(fuzzed_data_provider); }, [&] { - script.clear(); - }, - [&] { - (void)script.GetSigOpCount(false); - (void)script.GetSigOpCount(true); - (void)script.GetSigOpCount(script); - (void)script.HasValidOps(); - (void)script.IsPayToScriptHash(); - (void)script.IsPayToWitnessScriptHash(); - (void)script.IsPushOnly(); - (void)script.IsUnspendable(); - { - CScript::const_iterator pc = script.begin(); - opcodetype opcode; - (void)script.GetOp(pc, opcode); - std::vector<uint8_t> data; - (void)script.GetOp(pc, opcode, data); - (void)script.IsPushOnly(pc); - } - { - int version; - std::vector<uint8_t> program; - (void)script.IsWitnessProgram(version, program); - } + script_mut.clear(); }); } + const CScript& script = script_mut; + (void)script.GetSigOpCount(false); + (void)script.GetSigOpCount(true); + (void)script.GetSigOpCount(script); + (void)script.HasValidOps(); + (void)script.IsPayToScriptHash(); + (void)script.IsPayToWitnessScriptHash(); + (void)script.IsPushOnly(); + (void)script.IsUnspendable(); + { + CScript::const_iterator pc = script.begin(); + opcodetype opcode; + (void)script.GetOp(pc, opcode); + std::vector<uint8_t> data; + (void)script.GetOp(pc, opcode, data); + (void)script.IsPushOnly(pc); + } + { + int version; + std::vector<uint8_t> program; + (void)script.IsWitnessProgram(version, program); + } } diff --git a/src/test/fuzz/timedata.cpp b/src/test/fuzz/timedata.cpp index d7fa66298a..f7dc5f433e 100644 --- a/src/test/fuzz/timedata.cpp +++ b/src/test/fuzz/timedata.cpp @@ -15,10 +15,12 @@ FUZZ_TARGET(timedata) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); const unsigned int max_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1000); + // A max_size of 0 implies no limit, so cap the max number of insertions to avoid timeouts + auto max_to_insert = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 4000); // Divide by 2 to avoid signed integer overflow in .median() const int64_t initial_value = fuzzed_data_provider.ConsumeIntegral<int64_t>() / 2; CMedianFilter<int64_t> median_filter{max_size, initial_value}; - while (fuzzed_data_provider.remaining_bytes() > 0) { + while (fuzzed_data_provider.remaining_bytes() > 0 && --max_to_insert >= 0) { (void)median_filter.median(); assert(median_filter.size() > 0); assert(static_cast<size_t>(median_filter.size()) == median_filter.sorted().size()); diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp index 17e4405a13..ff34cc87b2 100644 --- a/src/test/fuzz/transaction.cpp +++ b/src/test/fuzz/transaction.cpp @@ -61,8 +61,11 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction) return; } - TxValidationState state_with_dupe_check; - (void)CheckTransaction(tx, state_with_dupe_check); + { + TxValidationState state_with_dupe_check; + const bool res{CheckTransaction(tx, state_with_dupe_check)}; + Assert(res == state_with_dupe_check.IsValid()); + } const CFeeRate dust_relay_fee{DUST_RELAY_TX_FEE}; std::string reason; @@ -100,9 +103,6 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction) (void)IsWitnessStandard(tx, coins_view_cache); UniValue u(UniValue::VOBJ); - TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ true, u); - TxToUniv(tx, /* hashBlock */ {}, /* include_addresses */ false, u); - static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); - TxToUniv(tx, u256_max, /* include_addresses */ true, u); - TxToUniv(tx, u256_max, /* include_addresses */ false, u); + TxToUniv(tx, /* hashBlock */ uint256::ZERO, /* include_addresses */ true, u); + TxToUniv(tx, /* hashBlock */ uint256::ONE, /* include_addresses */ false, u); } diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp index 59229987ba..bab34ea340 100644 --- a/src/test/fuzz/tx_pool.cpp +++ b/src/test/fuzz/tx_pool.cpp @@ -21,8 +21,9 @@ std::vector<COutPoint> g_outpoints_coinbase_init_mature; std::vector<COutPoint> g_outpoints_coinbase_init_immature; struct MockedTxPool : public CTxMemPool { - void RollingFeeUpdate() + void RollingFeeUpdate() EXCLUSIVE_LOCKS_REQUIRED(!cs) { + LOCK(cs); lastRollingFeeUpdate = GetTime(); blockSinceLastRollingFeeBump = true; } @@ -84,7 +85,7 @@ void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, CCh { BlockAssembler::Options options; options.nBlockMaxWeight = fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BLOCK_WEIGHT); - options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider)}; + options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /* max */ COIN)}; auto assembler = BlockAssembler{chainstate, *static_cast<CTxMemPool*>(&tx_pool), ::Params(), options}; auto block_template = assembler.CreateNewBlock(CScript{} << OP_TRUE); Assert(block_template->block.vtx.size() >= 1); @@ -218,6 +219,16 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) RegisterSharedValidationInterface(txr); const bool bypass_limits = fuzzed_data_provider.ConsumeBool(); ::fRequireStandard = fuzzed_data_provider.ConsumeBool(); + + // Make sure ProcessNewPackage on one transaction works and always fully validates the transaction. + // The result is not guaranteed to be the same as what is returned by ATMP. + const auto result_package = WITH_LOCK(::cs_main, + return ProcessNewPackage(node.chainman->ActiveChainstate(), tx_pool, {tx}, true)); + auto it = result_package.m_tx_results.find(tx->GetWitnessHash()); + Assert(it != result_package.m_tx_results.end()); + Assert(it->second.m_result_type == MempoolAcceptResult::ResultType::VALID || + it->second.m_result_type == MempoolAcceptResult::ResultType::INVALID); + const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx_pool, tx, bypass_limits)); const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID; SyncWithValidationInterfaceQueue(); diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index 574b694d1a..bcf0b0ce72 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -217,6 +217,11 @@ void FillNode(FuzzedDataProvider& fuzzed_data_provider, CNode& node, bool init_v } } +CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max) noexcept +{ + return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, max.value_or(MAX_MONEY)); +} + int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min, const std::optional<int64_t>& max) noexcept { // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime. diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h index 1a83f7a57a..36b1d5035c 100644 --- a/src/test/fuzz/util.h +++ b/src/test/fuzz/util.h @@ -123,10 +123,7 @@ template <typename WeakEnumType, size_t size> return static_cast<opcodetype>(fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, MAX_OPCODE)); } -[[nodiscard]] inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider) noexcept -{ - return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY); -} +[[nodiscard]] CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max = std::nullopt) noexcept; [[nodiscard]] int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min = std::nullopt, const std::optional<int64_t>& max = std::nullopt) noexcept; @@ -387,7 +384,7 @@ public: [&] { mode = "a+"; }); -#ifdef _GNU_SOURCE +#if defined _GNU_SOURCE && !defined __ANDROID__ const cookie_io_functions_t io_hooks = { FuzzedFileProvider::read, FuzzedFileProvider::write, @@ -516,8 +513,6 @@ void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noe WRITE_TO_STREAM_CASE(uint32_t, fuzzed_data_provider.ConsumeIntegral<uint32_t>()), WRITE_TO_STREAM_CASE(int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>()), WRITE_TO_STREAM_CASE(uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>()), - WRITE_TO_STREAM_CASE(float, fuzzed_data_provider.ConsumeFloatingPoint<float>()), - WRITE_TO_STREAM_CASE(double, fuzzed_data_provider.ConsumeFloatingPoint<double>()), WRITE_TO_STREAM_CASE(std::string, fuzzed_data_provider.ConsumeRandomLengthString(32)), WRITE_TO_STREAM_CASE(std::vector<char>, ConsumeRandomLengthIntegralVector<char>(fuzzed_data_provider))); } catch (const std::ios_base::failure&) { @@ -548,8 +543,6 @@ void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) no READ_FROM_STREAM_CASE(uint32_t), READ_FROM_STREAM_CASE(int64_t), READ_FROM_STREAM_CASE(uint64_t), - READ_FROM_STREAM_CASE(float), - READ_FROM_STREAM_CASE(double), READ_FROM_STREAM_CASE(std::string), READ_FROM_STREAM_CASE(std::vector<char>)); } catch (const std::ios_base::failure&) { diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp new file mode 100644 index 0000000000..6f2bc081c6 --- /dev/null +++ b/src/test/fuzz/utxo_snapshot.cpp @@ -0,0 +1,87 @@ +// Copyright (c) 2021 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 <chainparams.h> +#include <consensus/validation.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <test/util/mining.h> +#include <test/util/setup_common.h> +#include <validation.h> +#include <validationinterface.h> + +namespace { + +const std::vector<std::shared_ptr<CBlock>>* g_chain; + +void initialize_chain() +{ + const auto params{CreateChainParams(ArgsManager{}, CBaseChainParams::REGTEST)}; + static const auto chain{CreateBlockChain(2 * COINBASE_MATURITY, *params)}; + g_chain = &chain; +} + +FUZZ_TARGET_INIT(utxo_snapshot, initialize_chain) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + std::unique_ptr<const TestingSetup> setup{MakeNoLogFileContext<const TestingSetup>()}; + const auto& node = setup->m_node; + auto& chainman{*node.chainman}; + + const auto snapshot_path = gArgs.GetDataDirNet() / "fuzzed_snapshot.dat"; + + Assert(!chainman.SnapshotBlockhash()); + + { + CAutoFile outfile{fsbridge::fopen(snapshot_path, "wb"), SER_DISK, CLIENT_VERSION}; + const auto file_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)}; + outfile << Span<const uint8_t>{file_data}; + } + + const auto ActivateFuzzedSnapshot{[&] { + CAutoFile infile{fsbridge::fopen(snapshot_path, "rb"), SER_DISK, CLIENT_VERSION}; + SnapshotMetadata metadata; + try { + infile >> metadata; + } catch (const std::ios_base::failure&) { + return false; + } + return chainman.ActivateSnapshot(infile, metadata, /* in_memory */ true); + }}; + + if (fuzzed_data_provider.ConsumeBool()) { + for (const auto& block : *g_chain) { + BlockValidationState dummy; + bool processed{chainman.ProcessNewBlockHeaders({*block}, dummy, ::Params())}; + Assert(processed); + const auto* index{WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(block->GetHash()))}; + Assert(index); + } + } + + if (ActivateFuzzedSnapshot()) { + LOCK(::cs_main); + Assert(!chainman.ActiveChainstate().m_from_snapshot_blockhash->IsNull()); + Assert(*chainman.ActiveChainstate().m_from_snapshot_blockhash == + *chainman.SnapshotBlockhash()); + const auto& coinscache{chainman.ActiveChainstate().CoinsTip()}; + int64_t chain_tx{}; + for (const auto& block : *g_chain) { + Assert(coinscache.HaveCoin(COutPoint{block->vtx.at(0)->GetHash(), 0})); + const auto* index{chainman.m_blockman.LookupBlockIndex(block->GetHash())}; + const auto num_tx{Assert(index)->nTx}; + Assert(num_tx == 1); + chain_tx += num_tx; + } + Assert(g_chain->size() == coinscache.GetCacheSize()); + Assert(chain_tx == chainman.ActiveTip()->nChainTx); + } else { + Assert(!chainman.SnapshotBlockhash()); + Assert(!chainman.ActiveChainstate().m_from_snapshot_blockhash); + } + // Snapshot should refuse to load a second time regardless of validity + Assert(!ActivateFuzzedSnapshot()); +} +} // namespace diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index 41a626c0ea..677bf39fd9 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -10,7 +10,7 @@ #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(hash_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(hash_tests) BOOST_AUTO_TEST_CASE(murmurhash3) { diff --git a/src/test/i2p_tests.cpp b/src/test/i2p_tests.cpp index 334f71106c..bd9ba4b8f7 100644 --- a/src/test/i2p_tests.cpp +++ b/src/test/i2p_tests.cpp @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(unlimited_recv) }; CThreadInterrupt interrupt; - i2p::sam::Session session(GetDataDir() / "test_i2p_private_key", CService{}, &interrupt); + i2p::sam::Session session(gArgs.GetDataDirNet() / "test_i2p_private_key", CService{}, &interrupt); { ASSERT_DEBUG_LOG("Creating SAM session"); diff --git a/src/test/key_io_tests.cpp b/src/test/key_io_tests.cpp index 611e9f2623..8629d13840 100644 --- a/src/test/key_io_tests.cpp +++ b/src/test/key_io_tests.cpp @@ -15,7 +15,7 @@ #include <univalue.h> -extern UniValue read_json(const std::string& jsondata); +UniValue read_json(const std::string& jsondata); BOOST_FIXTURE_TEST_SUITE(key_io_tests, BasicTestingSetup) diff --git a/src/test/merkleblock_tests.cpp b/src/test/merkleblock_tests.cpp index 98b27994a6..e540b59b35 100644 --- a/src/test/merkleblock_tests.cpp +++ b/src/test/merkleblock_tests.cpp @@ -8,8 +8,10 @@ #include <boost/test/unit_test.hpp> +#include <set> +#include <vector> -BOOST_FIXTURE_TEST_SUITE(merkleblock_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(merkleblock_tests) /** * Create a CMerkleBlock using a list of txids which will be found in the diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 9ba004cc38..c47d0eae1e 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -28,7 +28,8 @@ struct MinerTestingSetup : public TestingSetup { void TestPackageSelection(const CChainParams& chainparams, const CScript& scriptPubKey, const std::vector<CTransactionRef>& txFirst) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs); bool TestSequenceLocks(const CTransaction& tx, int flags) EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs) { - return CheckSequenceLocks(::ChainstateActive(), *m_node.mempool, tx, flags); + CCoinsViewMemPool viewMempool(&m_node.chainman->ActiveChainstate().CoinsTip(), *m_node.mempool); + return CheckSequenceLocks(m_node.chainman->ActiveChain().Tip(), viewMempool, tx, flags); } BlockAssembler AssemblerForTest(const CChainParams& params); }; diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 1c397481dc..7a122bd8b0 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -300,13 +300,17 @@ BOOST_AUTO_TEST_CASE(cnetaddr_basic) // IPv6, scoped/link-local. See https://tools.ietf.org/html/rfc4007 // We support non-negative decimal integers (uint32_t) as zone id indices. - // Test with a fairly-high value, e.g. 32, to avoid locally reserved ids. + // Normal link-local scoped address functionality is to append "%" plus the + // zone id, for example, given a link-local address of "fe80::1" and a zone + // id of "32", return the address as "fe80::1%32". const std::string link_local{"fe80::1"}; const std::string scoped_addr{link_local + "%32"}; BOOST_REQUIRE(LookupHost(scoped_addr, addr, false)); BOOST_REQUIRE(addr.IsValid()); BOOST_REQUIRE(addr.IsIPv6()); BOOST_CHECK(!addr.IsBindAny()); + BOOST_CHECK_EQUAL(addr.ToString(), scoped_addr); + // Test that the delimiter "%" and default zone id of 0 can be omitted for the default scope. BOOST_REQUIRE(LookupHost(link_local + "%0", addr, false)); BOOST_REQUIRE(addr.IsValid()); diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 33b56624a8..3c47cf83e2 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -381,41 +381,63 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) // If no permission flags, assume backward compatibility BOOST_CHECK(NetWhitebindPermissions::TryParse("1.2.3.4:32", whitebindPermissions, error)); BOOST_CHECK(error.empty()); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_ISIMPLICIT); - BOOST_CHECK(NetPermissions::HasFlag(whitebindPermissions.m_flags, PF_ISIMPLICIT)); - NetPermissions::ClearFlag(whitebindPermissions.m_flags, PF_ISIMPLICIT); - BOOST_CHECK(!NetPermissions::HasFlag(whitebindPermissions.m_flags, PF_ISIMPLICIT)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_NONE); - NetPermissions::AddFlag(whitebindPermissions.m_flags, PF_ISIMPLICIT); - BOOST_CHECK(NetPermissions::HasFlag(whitebindPermissions.m_flags, PF_ISIMPLICIT)); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::Implicit); + BOOST_CHECK(NetPermissions::HasFlag(whitebindPermissions.m_flags, NetPermissionFlags::Implicit)); + NetPermissions::ClearFlag(whitebindPermissions.m_flags, NetPermissionFlags::Implicit); + BOOST_CHECK(!NetPermissions::HasFlag(whitebindPermissions.m_flags, NetPermissionFlags::Implicit)); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::None); + NetPermissions::AddFlag(whitebindPermissions.m_flags, NetPermissionFlags::Implicit); + BOOST_CHECK(NetPermissions::HasFlag(whitebindPermissions.m_flags, NetPermissionFlags::Implicit)); // Can set one permission BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::BloomFilter); BOOST_CHECK(NetWhitebindPermissions::TryParse("@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_NONE); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::None); + + NetWhitebindPermissions noban, noban_download, download_noban, download; + + // "noban" implies "download" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("noban@1.2.3.4:32", noban, error)); + BOOST_CHECK_EQUAL(noban.m_flags, NetPermissionFlags::NoBan); + BOOST_CHECK(NetPermissions::HasFlag(noban.m_flags, NetPermissionFlags::Download)); + BOOST_CHECK(NetPermissions::HasFlag(noban.m_flags, NetPermissionFlags::NoBan)); + + // "noban,download" is equivalent to "noban" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("noban,download@1.2.3.4:32", noban_download, error)); + BOOST_CHECK_EQUAL(noban_download.m_flags, noban.m_flags); + + // "download,noban" is equivalent to "noban" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("download,noban@1.2.3.4:32", download_noban, error)); + BOOST_CHECK_EQUAL(download_noban.m_flags, noban.m_flags); + + // "download" excludes (does not imply) "noban" + BOOST_REQUIRE(NetWhitebindPermissions::TryParse("download@1.2.3.4:32", download, error)); + BOOST_CHECK_EQUAL(download.m_flags, NetPermissionFlags::Download); + BOOST_CHECK(NetPermissions::HasFlag(download.m_flags, NetPermissionFlags::Download)); + BOOST_CHECK(!NetPermissions::HasFlag(download.m_flags, NetPermissionFlags::NoBan)); // Happy path, can parse flags BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,forcerelay@1.2.3.4:32", whitebindPermissions, error)); // forcerelay should also activate the relay permission - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_FORCERELAY | PF_RELAY); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::BloomFilter | NetPermissionFlags::ForceRelay | NetPermissionFlags::Relay); BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,relay,noban@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_RELAY | PF_NOBAN); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::BloomFilter | NetPermissionFlags::Relay | NetPermissionFlags::NoBan); BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,forcerelay,noban@1.2.3.4:32", whitebindPermissions, error)); BOOST_CHECK(NetWhitebindPermissions::TryParse("all@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_ALL); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::All); // Allow dups BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,relay,noban,noban@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_RELAY | PF_NOBAN); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::BloomFilter | NetPermissionFlags::Relay | NetPermissionFlags::NoBan | NetPermissionFlags::Download); // "noban" implies "download" // Allow empty BOOST_CHECK(NetWhitebindPermissions::TryParse("bloom,relay,,noban@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_BLOOMFILTER | PF_RELAY | PF_NOBAN); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::BloomFilter | NetPermissionFlags::Relay | NetPermissionFlags::NoBan); BOOST_CHECK(NetWhitebindPermissions::TryParse(",@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_NONE); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::None); BOOST_CHECK(NetWhitebindPermissions::TryParse(",,@1.2.3.4:32", whitebindPermissions, error)); - BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, PF_NONE); + BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::None); // Detect invalid flag BOOST_CHECK(!NetWhitebindPermissions::TryParse("bloom,forcerelay,oopsie@1.2.3.4:32", whitebindPermissions, error)); @@ -427,14 +449,16 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) // Happy path for whitelist parsing BOOST_CHECK(NetWhitelistPermissions::TryParse("noban@1.2.3.4", whitelistPermissions, error)); - BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, PF_NOBAN); + BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, NetPermissionFlags::NoBan); + BOOST_CHECK(NetPermissions::HasFlag(whitelistPermissions.m_flags, NetPermissionFlags::NoBan)); + BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay@1.2.3.4/32", whitelistPermissions, error)); - BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, PF_BLOOMFILTER | PF_FORCERELAY | PF_NOBAN | PF_RELAY); + BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, NetPermissionFlags::BloomFilter | NetPermissionFlags::ForceRelay | NetPermissionFlags::NoBan | NetPermissionFlags::Relay); BOOST_CHECK(error.empty()); BOOST_CHECK_EQUAL(whitelistPermissions.m_subnet.ToString(), "1.2.3.4/32"); BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay,mempool@1.2.3.4/32", whitelistPermissions, error)); - const auto strings = NetPermissions::ToStrings(PF_ALL); + const auto strings = NetPermissions::ToStrings(NetPermissionFlags::All); BOOST_CHECK_EQUAL(strings.size(), 7U); BOOST_CHECK(std::find(strings.begin(), strings.end(), "bloomfilter") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "forcerelay") != strings.end()); diff --git a/src/test/policy_fee_tests.cpp b/src/test/policy_fee_tests.cpp index 6d8872b11e..4a15be6ca6 100644 --- a/src/test/policy_fee_tests.cpp +++ b/src/test/policy_fee_tests.cpp @@ -5,11 +5,11 @@ #include <amount.h> #include <policy/fees.h> -#include <test/util/setup_common.h> - #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(policy_fee_tests, BasicTestingSetup) +#include <set> + +BOOST_AUTO_TEST_SUITE(policy_fee_tests) BOOST_AUTO_TEST_CASE(FeeRounder) { diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp index 7da364d316..21576bb868 100644 --- a/src/test/reverselock_tests.cpp +++ b/src/test/reverselock_tests.cpp @@ -7,7 +7,9 @@ #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup) +#include <stdexcept> + +BOOST_AUTO_TEST_SUITE(reverselock_tests) BOOST_AUTO_TEST_CASE(reverselock_basics) { diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 171234f745..62fd81673d 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -39,8 +39,7 @@ static const unsigned int gFlags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(std::string strFlags); std::string FormatScriptFlags(unsigned int flags); -UniValue -read_json(const std::string& jsondata) +UniValue read_json(const std::string& jsondata) { UniValue v; diff --git a/src/test/serfloat_tests.cpp b/src/test/serfloat_tests.cpp new file mode 100644 index 0000000000..54e07b0f61 --- /dev/null +++ b/src/test/serfloat_tests.cpp @@ -0,0 +1,129 @@ +// Copyright (c) 2014-2020 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 <hash.h> +#include <test/util/setup_common.h> +#include <util/serfloat.h> +#include <serialize.h> +#include <streams.h> + +#include <boost/test/unit_test.hpp> + +#include <cmath> +#include <limits> + +BOOST_FIXTURE_TEST_SUITE(serfloat_tests, BasicTestingSetup) + +namespace { + +uint64_t TestDouble(double f) { + uint64_t i = EncodeDouble(f); + double f2 = DecodeDouble(i); + if (std::isnan(f)) { + // NaN is not guaranteed to round-trip exactly. + BOOST_CHECK(std::isnan(f2)); + } else { + // Everything else is. + BOOST_CHECK(!std::isnan(f2)); + uint64_t i2 = EncodeDouble(f2); + BOOST_CHECK_EQUAL(f, f2); + BOOST_CHECK_EQUAL(i, i2); + } + return i; +} + +} // namespace + +BOOST_AUTO_TEST_CASE(double_serfloat_tests) { + BOOST_CHECK_EQUAL(TestDouble(0.0), 0); + BOOST_CHECK_EQUAL(TestDouble(-0.0), 0x8000000000000000); + BOOST_CHECK_EQUAL(TestDouble(std::numeric_limits<double>::infinity()), 0x7ff0000000000000); + BOOST_CHECK_EQUAL(TestDouble(-std::numeric_limits<double>::infinity()), 0xfff0000000000000); + BOOST_CHECK_EQUAL(TestDouble(0.5), 0x3fe0000000000000ULL); + BOOST_CHECK_EQUAL(TestDouble(1.0), 0x3ff0000000000000ULL); + BOOST_CHECK_EQUAL(TestDouble(2.0), 0x4000000000000000ULL); + BOOST_CHECK_EQUAL(TestDouble(4.0), 0x4010000000000000ULL); + BOOST_CHECK_EQUAL(TestDouble(785.066650390625), 0x4088888880000000ULL); + + // Roundtrip test on IEC559-compatible systems + if (std::numeric_limits<double>::is_iec559) { + BOOST_CHECK_EQUAL(sizeof(double), 8); + BOOST_CHECK_EQUAL(sizeof(uint64_t), 8); + // Test extreme values + TestDouble(std::numeric_limits<double>::min()); + TestDouble(-std::numeric_limits<double>::min()); + TestDouble(std::numeric_limits<double>::max()); + TestDouble(-std::numeric_limits<double>::max()); + TestDouble(std::numeric_limits<double>::lowest()); + TestDouble(-std::numeric_limits<double>::lowest()); + TestDouble(std::numeric_limits<double>::quiet_NaN()); + TestDouble(-std::numeric_limits<double>::quiet_NaN()); + TestDouble(std::numeric_limits<double>::signaling_NaN()); + TestDouble(-std::numeric_limits<double>::signaling_NaN()); + TestDouble(std::numeric_limits<double>::denorm_min()); + TestDouble(-std::numeric_limits<double>::denorm_min()); + // Test exact encoding: on currently supported platforms, EncodeDouble + // should produce exactly the same as the in-memory representation for non-NaN. + for (int j = 0; j < 1000; ++j) { + // Iterate over 9 specific bits exhaustively; the others are chosen randomly. + // These specific bits are the sign bit, and the 2 top and bottom bits of + // exponent and mantissa in the IEEE754 binary64 format. + for (int x = 0; x < 512; ++x) { + uint64_t v = InsecureRandBits(64); + v &= ~(uint64_t{1} << 0); + if (x & 1) v |= (uint64_t{1} << 0); + v &= ~(uint64_t{1} << 1); + if (x & 2) v |= (uint64_t{1} << 1); + v &= ~(uint64_t{1} << 50); + if (x & 4) v |= (uint64_t{1} << 50); + v &= ~(uint64_t{1} << 51); + if (x & 8) v |= (uint64_t{1} << 51); + v &= ~(uint64_t{1} << 52); + if (x & 16) v |= (uint64_t{1} << 52); + v &= ~(uint64_t{1} << 53); + if (x & 32) v |= (uint64_t{1} << 53); + v &= ~(uint64_t{1} << 61); + if (x & 64) v |= (uint64_t{1} << 61); + v &= ~(uint64_t{1} << 62); + if (x & 128) v |= (uint64_t{1} << 62); + v &= ~(uint64_t{1} << 63); + if (x & 256) v |= (uint64_t{1} << 63); + double f; + memcpy(&f, &v, 8); + uint64_t v2 = TestDouble(f); + if (!std::isnan(f)) BOOST_CHECK_EQUAL(v, v2); + } + } + } +} + +/* +Python code to generate the below hashes: + + def reversed_hex(x): + return binascii.hexlify(''.join(reversed(x))) + def dsha256(x): + return hashlib.sha256(hashlib.sha256(x).digest()).digest() + + reversed_hex(dsha256(''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96' +*/ +BOOST_AUTO_TEST_CASE(doubles) +{ + CDataStream ss(SER_DISK, 0); + // encode + for (int i = 0; i < 1000; i++) { + ss << EncodeDouble(i); + } + BOOST_CHECK(Hash(ss) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96")); + + // decode + for (int i = 0; i < 1000; i++) { + uint64_t val; + ss >> val; + double j = DecodeDouble(val); + BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index f77cda7ba2..4b55e3bc26 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -24,7 +24,7 @@ protected: CTransactionRef txval; public: CSerializeMethodsTestSingle() = default; - CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const char* charstrvalin, const CTransactionRef& txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), txval(txvalin) + CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const uint8_t* charstrvalin, const CTransactionRef& txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), txval(txvalin) { memcpy(charstrval, charstrvalin, sizeof(charstrval)); } @@ -70,10 +70,8 @@ BOOST_AUTO_TEST_CASE(sizes) BOOST_CHECK_EQUAL(sizeof(uint32_t), GetSerializeSize(uint32_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(int64_t), GetSerializeSize(int64_t(0), 0)); BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0)); - BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0)); - BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0)); - // Bool is serialized as char - BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0)); + // Bool is serialized as uint8_t + BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(bool(0), 0)); // Sanity-check GetSerializeSize and c++ type matching BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1U); @@ -85,93 +83,9 @@ BOOST_AUTO_TEST_CASE(sizes) 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) -{ - // Choose values that map unambiguously to binary floating point to avoid - // rounding issues at the compiler side. - BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F); - BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F); - BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f800000), 1.0F); - BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40000000), 2.0F); - 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), 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) -{ - // Choose values that map unambiguously to binary floating point to avoid - // rounding issues at the compiler side. - BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0); - BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5); - BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3ff0000000000000ULL), 1.0); - BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4000000000000000ULL), 2.0); - BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4010000000000000ULL), 4.0); - BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4088888880000000ULL), 785.066650390625); - - BOOST_CHECK_EQUAL(ser_double_to_uint64(0.0), 0x0000000000000000ULL); - BOOST_CHECK_EQUAL(ser_double_to_uint64(0.5), 0x3fe0000000000000ULL); - BOOST_CHECK_EQUAL(ser_double_to_uint64(1.0), 0x3ff0000000000000ULL); - BOOST_CHECK_EQUAL(ser_double_to_uint64(2.0), 0x4000000000000000ULL); - BOOST_CHECK_EQUAL(ser_double_to_uint64(4.0), 0x4010000000000000ULL); - BOOST_CHECK_EQUAL(ser_double_to_uint64(785.066650390625), 0x4088888880000000ULL); -} -/* -Python code to generate the below hashes: - - def reversed_hex(x): - return binascii.hexlify(''.join(reversed(x))) - def dsha256(x): - return hashlib.sha256(hashlib.sha256(x).digest()).digest() - - reversed_hex(dsha256(''.join(struct.pack('<f', x) for x in range(0,1000)))) == '8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c' - reversed_hex(dsha256(''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96' -*/ -BOOST_AUTO_TEST_CASE(floats) -{ - CDataStream ss(SER_DISK, 0); - // encode - for (int i = 0; i < 1000; i++) { - ss << float(i); - } - BOOST_CHECK(Hash(ss) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c")); - - // decode - for (int i = 0; i < 1000; i++) { - float j; - ss >> j; - BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); - } -} - -BOOST_AUTO_TEST_CASE(doubles) -{ - CDataStream ss(SER_DISK, 0); - // encode - for (int i = 0; i < 1000; i++) { - ss << double(i); - } - BOOST_CHECK(Hash(ss) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96")); - - // decode - for (int i = 0; i < 1000; i++) { - double j; - ss >> j; - BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); - } -} - BOOST_AUTO_TEST_CASE(varints) { // encode @@ -349,7 +263,7 @@ BOOST_AUTO_TEST_CASE(class_methods) int intval(100); bool boolval(true); std::string stringval("testing"); - const char charstrval[16] = "testing charstr"; + const uint8_t charstrval[16]{"testing charstr"}; CMutableTransaction txval; CTransactionRef tx_ref{MakeTransactionRef(txval)}; CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, charstrval, tx_ref); diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp index f5ae9f86d1..340ce33d91 100644 --- a/src/test/settings_tests.cpp +++ b/src/test/settings_tests.cpp @@ -45,7 +45,7 @@ BOOST_FIXTURE_TEST_SUITE(settings_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(ReadWrite) { - fs::path path = m_args.GetDataDirPath() / "settings.json"; + fs::path path = m_args.GetDataDirBase() / "settings.json"; WriteText(path, R"({ "string": "string", diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 2eb980e8cd..195565c1f8 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -21,7 +21,7 @@ #include <univalue.h> -extern UniValue read_json(const std::string& jsondata); +UniValue read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) diff --git a/src/test/sock_tests.cpp b/src/test/sock_tests.cpp index 400de875b7..9e98f4f0b1 100644 --- a/src/test/sock_tests.cpp +++ b/src/test/sock_tests.cpp @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(wait) Sock sock0(s[0]); Sock sock1(s[1]); - std::thread waiter([&sock0]() { sock0.Wait(24h, Sock::RECV); }); + std::thread waiter([&sock0]() { (void)sock0.Wait(24h, Sock::RECV); }); BOOST_REQUIRE_EQUAL(sock1.Send("a", 1, 0), 1); @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(recv_until_terminator_limit) // BOOST_CHECK_EXCEPTION() writes to some variables shared with the main thread which // creates a data race. So mimic it manually. try { - sock_recv.RecvUntilTerminator('\n', timeout, interrupt, max_data); + (void)sock_recv.RecvUntilTerminator('\n', timeout, interrupt, max_data); } catch (const std::runtime_error& e) { threw_as_expected = HasReason("too many bytes without a terminator")(e); } diff --git a/src/test/sync_tests.cpp b/src/test/sync_tests.cpp index 3e4d1dac9e..f5a8fc3aa6 100644 --- a/src/test/sync_tests.cpp +++ b/src/test/sync_tests.cpp @@ -8,6 +8,7 @@ #include <boost/test/unit_test.hpp> #include <mutex> +#include <stdexcept> namespace { template <typename MutexType> @@ -76,7 +77,7 @@ void TestInconsistentLockOrderDetected(MutexType& mutex1, MutexType& mutex2) NO_ } } // namespace -BOOST_FIXTURE_TEST_SUITE(sync_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(sync_tests) BOOST_AUTO_TEST_CASE(potential_deadlock_detected) { diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp index 41aa17988c..659caaef61 100644 --- a/src/test/torcontrol_tests.cpp +++ b/src/test/torcontrol_tests.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. // -#include <test/util/setup_common.h> #include <boost/test/unit_test.hpp> @@ -15,7 +14,7 @@ std::pair<std::string, std::string> SplitTorReplyLine(const std::string& s); std::map<std::string, std::string> ParseTorReplyMapping(const std::string& s); -BOOST_FIXTURE_TEST_SUITE(torcontrol_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(torcontrol_tests) static void CheckSplitTorReplyLine(std::string input, std::string command, std::string args) { diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 9bbf9567f5..40c53cb2ec 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -39,7 +39,7 @@ typedef std::vector<unsigned char> valtype; // In script_tests.cpp -extern UniValue read_json(const std::string& jsondata); +UniValue read_json(const std::string& jsondata); static std::map<std::string, unsigned int> mapFlagNames = { {std::string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH}, diff --git a/src/test/txindex_tests.cpp b/src/test/txindex_tests.cpp index 5fc172ee86..d47c54fd6e 100644 --- a/src/test/txindex_tests.cpp +++ b/src/test/txindex_tests.cpp @@ -7,6 +7,7 @@ #include <script/standard.h> #include <test/util/setup_common.h> #include <util/time.h> +#include <validation.h> #include <boost/test/unit_test.hpp> @@ -27,7 +28,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup) // BlockUntilSyncedToCurrentChain should return false before txindex is started. BOOST_CHECK(!txindex.BlockUntilSyncedToCurrentChain()); - txindex.Start(); + BOOST_REQUIRE(txindex.Start(::ChainstateActive())); // Allow tx index to catch up with the block index. constexpr int64_t timeout_ms = 10 * 1000; diff --git a/src/test/txvalidation_tests.cpp b/src/test/txvalidation_tests.cpp index 8d14071297..95ad85d0f8 100644 --- a/src/test/txvalidation_tests.cpp +++ b/src/test/txvalidation_tests.cpp @@ -3,8 +3,12 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <consensus/validation.h> +#include <key_io.h> +#include <policy/packages.h> +#include <policy/policy.h> #include <primitives/transaction.h> #include <script/script.h> +#include <script/standard.h> #include <test/util/setup_common.h> #include <validation.h> @@ -47,4 +51,98 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup) BOOST_CHECK(result.m_state.GetResult() == TxValidationResult::TX_CONSENSUS); } +// Create placeholder transactions that have no meaning. +inline CTransactionRef create_placeholder_tx(size_t num_inputs, size_t num_outputs) +{ + CMutableTransaction mtx = CMutableTransaction(); + mtx.vin.resize(num_inputs); + mtx.vout.resize(num_outputs); + auto random_script = CScript() << ToByteVector(InsecureRand256()) << ToByteVector(InsecureRand256()); + for (size_t i{0}; i < num_inputs; ++i) { + mtx.vin[i].prevout.hash = InsecureRand256(); + mtx.vin[i].prevout.n = 0; + mtx.vin[i].scriptSig = random_script; + } + for (size_t o{0}; o < num_outputs; ++o) { + mtx.vout[o].nValue = 1 * CENT; + mtx.vout[o].scriptPubKey = random_script; + } + return MakeTransactionRef(mtx); +} + +BOOST_FIXTURE_TEST_CASE(package_tests, TestChain100Setup) +{ + LOCK(cs_main); + unsigned int initialPoolSize = m_node.mempool->size(); + + // Parent and Child Package + CKey parent_key; + parent_key.MakeNewKey(true); + CScript parent_locking_script = GetScriptForDestination(PKHash(parent_key.GetPubKey())); + auto mtx_parent = CreateValidMempoolTransaction(/* input_transaction */ m_coinbase_txns[0], /* vout */ 0, + /* input_height */ 0, /* input_signing_key */ coinbaseKey, + /* output_destination */ parent_locking_script, + /* output_amount */ CAmount(49 * COIN), /* submit */ false); + CTransactionRef tx_parent = MakeTransactionRef(mtx_parent); + + CKey child_key; + child_key.MakeNewKey(true); + CScript child_locking_script = GetScriptForDestination(PKHash(child_key.GetPubKey())); + auto mtx_child = CreateValidMempoolTransaction(/* input_transaction */ tx_parent, /* vout */ 0, + /* input_height */ 101, /* input_signing_key */ parent_key, + /* output_destination */ child_locking_script, + /* output_amount */ CAmount(48 * COIN), /* submit */ false); + CTransactionRef tx_child = MakeTransactionRef(mtx_child); + const auto result_parent_child = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {tx_parent, tx_child}, /* test_accept */ true); + BOOST_CHECK_MESSAGE(result_parent_child.m_state.IsValid(), + "Package validation unexpectedly failed: " << result_parent_child.m_state.GetRejectReason()); + auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetWitnessHash()); + auto it_child = result_parent_child.m_tx_results.find(tx_child->GetWitnessHash()); + BOOST_CHECK(it_parent != result_parent_child.m_tx_results.end()); + BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(), + "Package validation unexpectedly failed: " << it_parent->second.m_state.GetRejectReason()); + BOOST_CHECK(it_child != result_parent_child.m_tx_results.end()); + BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(), + "Package validation unexpectedly failed: " << it_child->second.m_state.GetRejectReason()); + + // Packages can't have more than 25 transactions. + Package package_too_many; + package_too_many.reserve(MAX_PACKAGE_COUNT + 1); + for (size_t i{0}; i < MAX_PACKAGE_COUNT + 1; ++i) { + package_too_many.emplace_back(create_placeholder_tx(1, 1)); + } + auto result_too_many = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_too_many, /* test_accept */ true); + BOOST_CHECK(result_too_many.m_state.IsInvalid()); + BOOST_CHECK_EQUAL(result_too_many.m_state.GetResult(), PackageValidationResult::PCKG_POLICY); + BOOST_CHECK_EQUAL(result_too_many.m_state.GetRejectReason(), "package-too-many-transactions"); + + // Packages can't have a total size of more than 101KvB. + CTransactionRef large_ptx = create_placeholder_tx(150, 150); + Package package_too_large; + auto size_large = GetVirtualTransactionSize(*large_ptx); + size_t total_size{0}; + while (total_size <= MAX_PACKAGE_SIZE * 1000) { + package_too_large.push_back(large_ptx); + total_size += size_large; + } + BOOST_CHECK(package_too_large.size() <= MAX_PACKAGE_COUNT); + auto result_too_large = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_too_large, /* test_accept */ true); + BOOST_CHECK(result_too_large.m_state.IsInvalid()); + BOOST_CHECK_EQUAL(result_too_large.m_state.GetResult(), PackageValidationResult::PCKG_POLICY); + BOOST_CHECK_EQUAL(result_too_large.m_state.GetRejectReason(), "package-too-large"); + + // A single, giant transaction submitted through ProcessNewPackage fails on single tx policy. + CTransactionRef giant_ptx = create_placeholder_tx(999, 999); + BOOST_CHECK(GetVirtualTransactionSize(*giant_ptx) > MAX_PACKAGE_SIZE * 1000); + auto result_single_large = ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, {giant_ptx}, /* test_accept */ true); + BOOST_CHECK(result_single_large.m_state.IsInvalid()); + BOOST_CHECK_EQUAL(result_single_large.m_state.GetResult(), PackageValidationResult::PCKG_TX); + BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(), "transaction failed"); + auto it_giant_tx = result_single_large.m_tx_results.find(giant_ptx->GetWitnessHash()); + BOOST_CHECK(it_giant_tx != result_single_large.m_tx_results.end()); + BOOST_CHECK_EQUAL(it_giant_tx->second.m_state.GetRejectReason(), "tx-size"); + + // Check that mempool size hasn't changed. + BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index ae626d4613..b4744cabc7 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -13,8 +13,9 @@ #include <iomanip> #include <sstream> #include <string> +#include <vector> -BOOST_FIXTURE_TEST_SUITE(uint256_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(uint256_tests) const unsigned char R1Array[] = "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp index 3fc3329da2..1204873828 100644 --- a/src/test/util/mining.cpp +++ b/src/test/util/mining.cpp @@ -11,8 +11,10 @@ #include <node/context.h> #include <pow.h> #include <script/standard.h> +#include <test/util/script.h> #include <util/check.h> #include <validation.h> +#include <versionbits.h> CTxIn generatetoaddress(const NodeContext& node, const std::string& address) { @@ -23,6 +25,37 @@ CTxIn generatetoaddress(const NodeContext& node, const std::string& address) return MineBlock(node, coinbase_script); } +std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params) +{ + std::vector<std::shared_ptr<CBlock>> ret{total_height}; + auto time{params.GenesisBlock().nTime}; + for (size_t height{0}; height < total_height; ++height) { + CBlock& block{*(ret.at(height) = std::make_shared<CBlock>())}; + + CMutableTransaction coinbase_tx; + coinbase_tx.vin.resize(1); + coinbase_tx.vin[0].prevout.SetNull(); + coinbase_tx.vout.resize(1); + coinbase_tx.vout[0].scriptPubKey = P2WSH_OP_TRUE; + coinbase_tx.vout[0].nValue = GetBlockSubsidy(height + 1, params.GetConsensus()); + coinbase_tx.vin[0].scriptSig = CScript() << (height + 1) << OP_0; + block.vtx = {MakeTransactionRef(std::move(coinbase_tx))}; + + block.nVersion = VERSIONBITS_LAST_OLD_BLOCK_VERSION; + block.hashPrevBlock = (height >= 1 ? *ret.at(height - 1) : params.GenesisBlock()).GetHash(); + block.hashMerkleRoot = BlockMerkleRoot(block); + block.nTime = ++time; + block.nBits = params.GenesisBlock().nBits; + block.nNonce = 0; + + while (!CheckProofOfWork(block.GetHash(), block.nBits, params.GetConsensus())) { + ++block.nNonce; + assert(block.nNonce); + } + } + return ret; +} + CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey) { auto block = PrepareBlock(node, coinbase_scriptPubKey); diff --git a/src/test/util/mining.h b/src/test/util/mining.h index 5f250fffe8..1fc1864b91 100644 --- a/src/test/util/mining.h +++ b/src/test/util/mining.h @@ -7,12 +7,17 @@ #include <memory> #include <string> +#include <vector> class CBlock; +class CChainParams; class CScript; class CTxIn; struct NodeContext; +/** Create a blockchain, starting from genesis */ +std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params); + /** Returns the generated coin */ CTxIn MineBlock(const NodeContext&, const CScript& coinbase_scriptPubKey); diff --git a/src/test/util/net.h b/src/test/util/net.h index 9268d60a1e..71685d437a 100644 --- a/src/test/util/net.h +++ b/src/test/util/net.h @@ -46,16 +46,16 @@ constexpr ServiceFlags ALL_SERVICE_FLAGS[]{ }; constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]{ - NetPermissionFlags::PF_NONE, - NetPermissionFlags::PF_BLOOMFILTER, - NetPermissionFlags::PF_RELAY, - NetPermissionFlags::PF_FORCERELAY, - NetPermissionFlags::PF_NOBAN, - NetPermissionFlags::PF_MEMPOOL, - NetPermissionFlags::PF_ADDR, - NetPermissionFlags::PF_DOWNLOAD, - NetPermissionFlags::PF_ISIMPLICIT, - NetPermissionFlags::PF_ALL, + NetPermissionFlags::None, + NetPermissionFlags::BloomFilter, + NetPermissionFlags::Relay, + NetPermissionFlags::ForceRelay, + NetPermissionFlags::NoBan, + NetPermissionFlags::Mempool, + NetPermissionFlags::Addr, + NetPermissionFlags::Download, + NetPermissionFlags::Implicit, + NetPermissionFlags::All, }; constexpr ConnectionType ALL_CONNECTION_TYPES[]{ diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index ffc5115145..863c3ab565 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -28,6 +28,8 @@ #include <txdb.h> #include <util/strencodings.h> #include <util/string.h> +#include <util/thread.h> +#include <util/threadnames.h> #include <util/time.h> #include <util/translation.h> #include <util/url.h> @@ -135,7 +137,7 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve // We have to run a scheduler thread to prevent ActivateBestChain // from blocking due to queue overrun. m_node.scheduler = std::make_unique<CScheduler>(); - m_node.scheduler->m_service_thread = std::thread([&] { TraceThread("scheduler", [&] { m_node.scheduler->serviceQueue(); }); }); + m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); }); GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler); pblocktree.reset(new CBlockTreeDB(1 << 20, true)); @@ -193,7 +195,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const } m_node.addrman = std::make_unique<CAddrMan>(); - m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirPath() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); + m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); m_node.connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); // Deterministic randomness for tests. m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman, m_node.banman.get(), *m_node.scheduler, *m_node.chainman, @@ -244,8 +246,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa for (const CMutableTransaction& tx : txns) { block.vtx.push_back(MakeTransactionRef(tx)); } - CBlockIndex* prev_block = WITH_LOCK(::cs_main, return g_chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock)); - RegenerateCommitments(block, prev_block); + RegenerateCommitments(block, *Assert(m_node.chainman)); while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; @@ -261,7 +262,8 @@ CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactio int input_height, CKey input_signing_key, CScript output_destination, - CAmount output_amount) + CAmount output_amount, + bool submit) { // Transaction we will submit to the mempool CMutableTransaction mempool_txn; @@ -294,8 +296,8 @@ CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactio std::map<int, std::string> input_errors; assert(SignTransaction(mempool_txn, &keystore, input_coins, nHashType, input_errors)); - // Add transaction to the mempool - { + // If submit=true, add transaction to the mempool. + if (submit) { LOCK(cs_main); const MempoolAcceptResult result = AcceptToMemoryPool(::ChainstateActive(), *m_node.mempool.get(), MakeTransactionRef(mempool_txn), /* bypass_limits */ false); assert(result.m_result_type == MempoolAcceptResult::ResultType::VALID); diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index b19dd75765..5d12dc2323 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -135,13 +135,15 @@ struct TestChain100Setup : public RegTestingSetup { * @param input_signing_key The key to spend the input_transaction * @param output_destination Where to send the output * @param output_amount How much to send + * @param submit Whether or not to submit to mempool */ CMutableTransaction CreateValidMempoolTransaction(CTransactionRef input_transaction, int input_vout, int input_height, CKey input_signing_key, CScript output_destination, - CAmount output_amount = CAmount(1 * COIN)); + CAmount output_amount = CAmount(1 * COIN), + bool submit = true); ~TestChain100Setup(); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 534d28e5de..d463bcdd8e 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -53,23 +53,23 @@ BOOST_AUTO_TEST_CASE(util_datadir) ArgsManager args; args.ForceSetArg("-datadir", m_path_root.string()); - const fs::path dd_norm = args.GetDataDirPath(); + const fs::path dd_norm = args.GetDataDirBase(); args.ForceSetArg("-datadir", dd_norm.string() + "/"); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); args.ForceSetArg("-datadir", dd_norm.string() + "/."); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); args.ForceSetArg("-datadir", dd_norm.string() + "/./"); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); args.ForceSetArg("-datadir", dd_norm.string() + "/.//"); args.ClearPathCache(); - BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirPath()); + BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase()); } BOOST_AUTO_TEST_CASE(util_check) @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(util_FormatParseISO8601DateTime) BOOST_CHECK_EQUAL(ParseISO8601DateTime("1960-01-01T00:00:00Z"), 0); BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z"), 1317425777); - auto time = GetSystemTimeInSeconds(); + auto time = GetTimeSeconds(); BOOST_CHECK_EQUAL(ParseISO8601DateTime(FormatISO8601DateTime(time)), time); } @@ -1159,10 +1159,10 @@ BOOST_AUTO_TEST_CASE(util_ReadWriteSettings) // Test error logging, and remove previously written setting. { ASSERT_DEBUG_LOG("Failed renaming settings file"); - fs::remove(args1.GetDataDirPath() / "settings.json"); - fs::create_directory(args1.GetDataDirPath() / "settings.json"); + fs::remove(args1.GetDataDirBase() / "settings.json"); + fs::create_directory(args1.GetDataDirBase() / "settings.json"); args2.WriteSettingsFile(); - fs::remove(args1.GetDataDirPath() / "settings.json"); + fs::remove(args1.GetDataDirBase() / "settings.json"); } } @@ -1810,7 +1810,7 @@ static constexpr char ExitCommand = 'X'; BOOST_AUTO_TEST_CASE(test_LockDirectory) { - fs::path dirname = m_args.GetDataDirPath() / "lock_dir"; + fs::path dirname = m_args.GetDataDirBase() / "lock_dir"; const std::string lockname = ".lock"; #ifndef WIN32 // Revert SIGCHLD to default, otherwise boost.test will catch and fail on @@ -1899,7 +1899,7 @@ BOOST_AUTO_TEST_CASE(test_LockDirectory) BOOST_AUTO_TEST_CASE(test_DirIsWritable) { // Should be able to write to the data dir. - fs::path tmpdirname = m_args.GetDataDirPath(); + fs::path tmpdirname = m_args.GetDataDirBase(); BOOST_CHECK_EQUAL(DirIsWritable(tmpdirname), true); // Should not be able to write to a non-existent dir. diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp index f3f9fb2bff..a5b456dd7a 100644 --- a/src/test/util_threadnames_tests.cpp +++ b/src/test/util_threadnames_tests.cpp @@ -2,12 +2,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <test/util/setup_common.h> #include <util/string.h> #include <util/threadnames.h> #include <mutex> #include <set> +#include <string> #include <thread> #include <vector> @@ -17,7 +17,7 @@ #include <boost/test/unit_test.hpp> -BOOST_FIXTURE_TEST_SUITE(util_threadnames_tests, BasicTestingSetup) +BOOST_AUTO_TEST_SUITE(util_threadnames_tests) const std::string TEST_THREAD_NAME_BASE = "test_thread."; diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp index 82e70b5cdc..0b912acb08 100644 --- a/src/test/validation_chainstatemanager_tests.cpp +++ b/src/test/validation_chainstatemanager_tests.cpp @@ -226,10 +226,8 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup) // Snapshot should refuse to load at this height. BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot(m_node, m_path_root)); - BOOST_CHECK(chainman.ActiveChainstate().m_from_snapshot_blockhash.IsNull()); - BOOST_CHECK_EQUAL( - chainman.ActiveChainstate().m_from_snapshot_blockhash, - chainman.SnapshotBlockhash().value_or(uint256())); + BOOST_CHECK(!chainman.ActiveChainstate().m_from_snapshot_blockhash); + BOOST_CHECK(!chainman.SnapshotBlockhash()); // Mine 10 more blocks, putting at us height 110 where a valid assumeutxo value can // be found. @@ -263,15 +261,20 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup) BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot( m_node, m_path_root, [](CAutoFile& auto_infile, SnapshotMetadata& metadata) { // Wrong hash + metadata.m_base_blockhash = uint256::ZERO; + })); + BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot( + m_node, m_path_root, [](CAutoFile& auto_infile, SnapshotMetadata& metadata) { + // Wrong hash metadata.m_base_blockhash = uint256::ONE; })); BOOST_REQUIRE(CreateAndActivateUTXOSnapshot(m_node, m_path_root)); // Ensure our active chain is the snapshot chainstate. - BOOST_CHECK(!chainman.ActiveChainstate().m_from_snapshot_blockhash.IsNull()); + BOOST_CHECK(!chainman.ActiveChainstate().m_from_snapshot_blockhash->IsNull()); BOOST_CHECK_EQUAL( - chainman.ActiveChainstate().m_from_snapshot_blockhash, + *chainman.ActiveChainstate().m_from_snapshot_blockhash, *chainman.SnapshotBlockhash()); const AssumeutxoData& au_data = *ExpectedAssumeutxo(snapshot_height, ::Params()); @@ -347,7 +350,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager_activate_snapshot, TestChain100Setup) // Snapshot blockhash should be unchanged. BOOST_CHECK_EQUAL( - chainman.ActiveChainstate().m_from_snapshot_blockhash, + *chainman.ActiveChainstate().m_from_snapshot_blockhash, loaded_snapshot_blockhash); } diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp index d0317aca0a..a0c2e76f00 100644 --- a/src/test/validation_tests.cpp +++ b/src/test/validation_tests.cpp @@ -135,12 +135,12 @@ BOOST_AUTO_TEST_CASE(test_assumeutxo) } const auto out110 = *ExpectedAssumeutxo(110, *params); - BOOST_CHECK_EQUAL(out110.hash_serialized, uint256S("1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618")); - BOOST_CHECK_EQUAL(out110.nChainTx, (unsigned int)110); + BOOST_CHECK_EQUAL(out110.hash_serialized.ToString(), "1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618"); + BOOST_CHECK_EQUAL(out110.nChainTx, 110U); - const auto out210 = *ExpectedAssumeutxo(210, *params); - BOOST_CHECK_EQUAL(out210.hash_serialized, uint256S("9c5ed99ef98544b34f8920b6d1802f72ac28ae6e2bd2bd4c316ff10c230df3f2")); - BOOST_CHECK_EQUAL(out210.nChainTx, (unsigned int)210); + const auto out210 = *ExpectedAssumeutxo(200, *params); + BOOST_CHECK_EQUAL(out210.hash_serialized.ToString(), "51c8d11d8b5c1de51543c579736e786aa2736206d1e11e627568029ce092cf62"); + BOOST_CHECK_EQUAL(out210.nChainTx, 200U); } BOOST_AUTO_TEST_SUITE_END() |