aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/addrman_tests.cpp443
-rw-r--r--src/test/bip32_tests.cpp34
-rw-r--r--src/test/crypto_tests.cpp4
-rw-r--r--src/test/denialofservice_tests.cpp8
-rw-r--r--src/test/fuzz/addrdb.cpp37
-rw-r--r--src/test/fuzz/addrman.cpp249
-rw-r--r--src/test/fuzz/banman.cpp14
-rw-r--r--src/test/fuzz/blockfilter.cpp5
-rw-r--r--src/test/fuzz/coins_view.cpp2
-rw-r--r--src/test/fuzz/connman.cpp8
-rw-r--r--src/test/fuzz/crypto.cpp7
-rw-r--r--src/test/fuzz/data_stream.cpp2
-rw-r--r--src/test/fuzz/deserialize.cpp279
-rw-r--r--src/test/fuzz/fuzz.h7
-rw-r--r--src/test/fuzz/integer.cpp26
-rw-r--r--src/test/fuzz/key_io.cpp11
-rw-r--r--src/test/fuzz/kitchen_sink.cpp8
-rw-r--r--src/test/fuzz/multiplication_overflow.cpp12
-rw-r--r--src/test/fuzz/net.cpp6
-rw-r--r--src/test/fuzz/netaddress.cpp2
-rw-r--r--src/test/fuzz/parse_numbers.cpp3
-rw-r--r--src/test/fuzz/prevector.cpp3
-rw-r--r--src/test/fuzz/process_message.cpp12
-rw-r--r--src/test/fuzz/rolling_bloom_filter.cpp14
-rw-r--r--src/test/fuzz/script.cpp40
-rw-r--r--src/test/fuzz/script_sign.cpp3
-rw-r--r--src/test/fuzz/string.cpp3
-rw-r--r--src/test/fuzz/system.cpp3
-rw-r--r--src/test/fuzz/tx_pool.cpp6
-rw-r--r--src/test/fuzz/util.cpp194
-rw-r--r--src/test/fuzz/util.h189
-rw-r--r--src/test/logging_tests.cpp2
-rw-r--r--src/test/miner_tests.cpp62
-rw-r--r--src/test/net_peer_eviction_tests.cpp22
-rw-r--r--src/test/net_tests.cpp179
-rw-r--r--src/test/script_tests.cpp16
-rw-r--r--src/test/serfloat_tests.cpp13
-rw-r--r--src/test/sigopcount_tests.cpp4
-rw-r--r--src/test/streams_tests.cpp2
-rw-r--r--src/test/transaction_tests.cpp133
-rw-r--r--src/test/txvalidationcache_tests.cpp11
-rw-r--r--src/test/util/net.cpp25
-rw-r--r--src/test/util/net.h2
-rw-r--r--src/test/util/setup_common.cpp12
-rw-r--r--src/test/util/wallet.cpp3
-rw-r--r--src/test/util_tests.cpp129
-rw-r--r--src/test/validation_block_tests.cpp18
-rw-r--r--src/test/validation_chainstate_tests.cpp3
-rw-r--r--src/test/validation_chainstatemanager_tests.cpp8
-rw-r--r--src/test/validation_flush_tests.cpp25
50 files changed, 1239 insertions, 1064 deletions
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
index eb5c37b34d..e1b5df9502 100644
--- a/src/test/addrman_tests.cpp
+++ b/src/test/addrman_tests.cpp
@@ -1,7 +1,10 @@
// Copyright (c) 2012-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 <addrdb.h>
#include <addrman.h>
+#include <chainparams.h>
#include <test/data/asmap.raw.h>
#include <test/util/setup_common.h>
#include <util/asmap.h>
@@ -15,27 +18,73 @@
#include <optional>
#include <string>
+using namespace std::literals;
+
+class CAddrManSerializationMock : public CAddrMan
+{
+public:
+ virtual void Serialize(CDataStream& s) const = 0;
+
+ CAddrManSerializationMock()
+ : CAddrMan(/* asmap */ std::vector<bool>(), /* deterministic */ true, /* consistency_check_ratio */ 100)
+ {}
+};
+
+class CAddrManUncorrupted : public CAddrManSerializationMock
+{
+public:
+ void Serialize(CDataStream& s) const override
+ {
+ CAddrMan::Serialize(s);
+ }
+};
+
+class CAddrManCorrupted : public CAddrManSerializationMock
+{
+public:
+ void Serialize(CDataStream& s) const override
+ {
+ // Produces corrupt output that claims addrman has 20 addrs when it only has one addr.
+ unsigned char nVersion = 1;
+ s << nVersion;
+ s << ((unsigned char)32);
+ s << uint256::ONE;
+ s << 10; // nNew
+ s << 10; // nTried
+
+ int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
+ s << nUBuckets;
+
+ CService serv;
+ BOOST_CHECK(Lookup("252.1.1.1", serv, 7777, false));
+ CAddress addr = CAddress(serv, NODE_NONE);
+ CNetAddr resolved;
+ BOOST_CHECK(LookupHost("252.2.2.2", resolved, false));
+ CAddrInfo info = CAddrInfo(addr, resolved);
+ s << info;
+ }
+};
+
+static CDataStream AddrmanToStream(const CAddrManSerializationMock& _addrman)
+{
+ CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
+ ssPeersIn << Params().MessageStart();
+ ssPeersIn << _addrman;
+ std::string str = ssPeersIn.str();
+ std::vector<unsigned char> vchData(str.begin(), str.end());
+ return CDataStream(vchData, SER_DISK, CLIENT_VERSION);
+}
+
class CAddrManTest : public CAddrMan
{
private:
bool deterministic;
public:
explicit CAddrManTest(bool makeDeterministic = true,
- std::vector<bool> asmap = std::vector<bool>())
+ std::vector<bool> asmap = std::vector<bool>())
+ : CAddrMan(asmap, makeDeterministic, /* consistency_check_ratio */ 100)
{
- if (makeDeterministic) {
- // Set addrman addr placement to be deterministic.
- MakeDeterministic();
- }
deterministic = makeDeterministic;
- m_asmap = asmap;
- }
-
- //! Ensure that bucket placement is always the same for testing purposes.
- void MakeDeterministic()
- {
- nKey.SetNull();
- insecure_rand = FastRandomContext(true);
}
CAddrInfo* Find(const CNetAddr& addr, int* pnId = nullptr)
@@ -76,22 +125,12 @@ public:
{
int64_t nLastSuccess = 1;
// Set last good connection in the deep past.
- Good(addr, true, nLastSuccess);
+ Good(addr, nLastSuccess);
bool count_failure = false;
int64_t nLastTry = GetAdjustedTime()-61;
Attempt(addr, count_failure, nLastTry);
}
-
- void Clear()
- {
- CAddrMan::Clear();
- if (deterministic) {
- nKey.SetNull();
- insecure_rand = FastRandomContext(true);
- }
- }
-
};
static CNetAddr ResolveIP(const std::string& ip)
@@ -125,27 +164,27 @@ BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(addrman_simple)
{
- CAddrManTest addrman;
+ auto addrman = std::make_unique<CAddrManTest>();
CNetAddr source = ResolveIP("252.2.2.2");
// Test: Does Addrman respond correctly when empty.
- BOOST_CHECK_EQUAL(addrman.size(), 0U);
- CAddrInfo addr_null = addrman.Select();
+ BOOST_CHECK_EQUAL(addrman->size(), 0U);
+ CAddrInfo addr_null = addrman->Select();
BOOST_CHECK_EQUAL(addr_null.ToString(), "[::]:0");
// Test: Does Addrman::Add work as expected.
CService addr1 = ResolveService("250.1.1.1", 8333);
- BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 1U);
- CAddrInfo addr_ret1 = addrman.Select();
+ BOOST_CHECK(addrman->Add({CAddress(addr1, NODE_NONE)}, source));
+ BOOST_CHECK_EQUAL(addrman->size(), 1U);
+ CAddrInfo addr_ret1 = addrman->Select();
BOOST_CHECK_EQUAL(addr_ret1.ToString(), "250.1.1.1:8333");
// Test: Does IP address deduplication work correctly.
// Expected dup IP should not be added.
CService addr1_dup = ResolveService("250.1.1.1", 8333);
- BOOST_CHECK(!addrman.Add(CAddress(addr1_dup, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 1U);
+ BOOST_CHECK(!addrman->Add({CAddress(addr1_dup, NODE_NONE)}, source));
+ BOOST_CHECK_EQUAL(addrman->size(), 1U);
// Test: New table has one addr and we add a diff addr we should
@@ -155,21 +194,16 @@ BOOST_AUTO_TEST_CASE(addrman_simple)
// success.
CService addr2 = ResolveService("250.1.1.2", 8333);
- BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source));
- BOOST_CHECK(addrman.size() >= 1);
+ BOOST_CHECK(addrman->Add({CAddress(addr2, NODE_NONE)}, source));
+ BOOST_CHECK(addrman->size() >= 1);
- // Test: AddrMan::Clear() should empty the new table.
- addrman.Clear();
- BOOST_CHECK_EQUAL(addrman.size(), 0U);
- CAddrInfo addr_null2 = addrman.Select();
- BOOST_CHECK_EQUAL(addr_null2.ToString(), "[::]:0");
-
- // Test: AddrMan::Add multiple addresses works as expected
+ // Test: reset addrman and test AddrMan::Add multiple addresses works as expected
+ addrman = std::make_unique<CAddrManTest>();
std::vector<CAddress> vAddr;
vAddr.push_back(CAddress(ResolveService("250.1.1.3", 8333), NODE_NONE));
vAddr.push_back(CAddress(ResolveService("250.1.1.4", 8333), NODE_NONE));
- BOOST_CHECK(addrman.Add(vAddr, source));
- BOOST_CHECK(addrman.size() >= 1);
+ BOOST_CHECK(addrman->Add(vAddr, source));
+ BOOST_CHECK(addrman->size() >= 1);
}
BOOST_AUTO_TEST_CASE(addrman_ports)
@@ -182,11 +216,11 @@ BOOST_AUTO_TEST_CASE(addrman_ports)
// Test 7; Addr with same IP but diff port does not replace existing addr.
CService addr1 = ResolveService("250.1.1.1", 8333);
- BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
+ BOOST_CHECK(addrman.Add({CAddress(addr1, NODE_NONE)}, source));
BOOST_CHECK_EQUAL(addrman.size(), 1U);
CService addr1_port = ResolveService("250.1.1.1", 8334);
- BOOST_CHECK(!addrman.Add(CAddress(addr1_port, NODE_NONE), source));
+ BOOST_CHECK(!addrman.Add({CAddress(addr1_port, NODE_NONE)}, source));
BOOST_CHECK_EQUAL(addrman.size(), 1U);
CAddrInfo addr_ret2 = addrman.Select();
BOOST_CHECK_EQUAL(addr_ret2.ToString(), "250.1.1.1:8333");
@@ -209,7 +243,7 @@ BOOST_AUTO_TEST_CASE(addrman_select)
// Test: Select from new with 1 addr in new.
CService addr1 = ResolveService("250.1.1.1", 8333);
- BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
+ BOOST_CHECK(addrman.Add({CAddress(addr1, NODE_NONE)}, source));
BOOST_CHECK_EQUAL(addrman.size(), 1U);
bool newOnly = true;
@@ -233,20 +267,20 @@ BOOST_AUTO_TEST_CASE(addrman_select)
CService addr3 = ResolveService("250.3.2.2", 9999);
CService addr4 = ResolveService("250.3.3.3", 9999);
- BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), ResolveService("250.3.1.1", 8333)));
- BOOST_CHECK(addrman.Add(CAddress(addr3, NODE_NONE), ResolveService("250.3.1.1", 8333)));
- BOOST_CHECK(addrman.Add(CAddress(addr4, NODE_NONE), ResolveService("250.4.1.1", 8333)));
+ BOOST_CHECK(addrman.Add({CAddress(addr2, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
+ BOOST_CHECK(addrman.Add({CAddress(addr3, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
+ BOOST_CHECK(addrman.Add({CAddress(addr4, NODE_NONE)}, ResolveService("250.4.1.1", 8333)));
// Add three addresses to tried table.
CService addr5 = ResolveService("250.4.4.4", 8333);
CService addr6 = ResolveService("250.4.5.5", 7777);
CService addr7 = ResolveService("250.4.6.6", 8333);
- BOOST_CHECK(addrman.Add(CAddress(addr5, NODE_NONE), ResolveService("250.3.1.1", 8333)));
+ BOOST_CHECK(addrman.Add({CAddress(addr5, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
addrman.Good(CAddress(addr5, NODE_NONE));
- BOOST_CHECK(addrman.Add(CAddress(addr6, NODE_NONE), ResolveService("250.3.1.1", 8333)));
+ BOOST_CHECK(addrman.Add({CAddress(addr6, NODE_NONE)}, ResolveService("250.3.1.1", 8333)));
addrman.Good(CAddress(addr6, NODE_NONE));
- BOOST_CHECK(addrman.Add(CAddress(addr7, NODE_NONE), ResolveService("250.1.1.3", 8333)));
+ BOOST_CHECK(addrman.Add({CAddress(addr7, NODE_NONE)}, ResolveService("250.1.1.3", 8333)));
addrman.Good(CAddress(addr7, NODE_NONE));
// Test: 6 addrs + 1 addr from last test = 7.
@@ -266,24 +300,27 @@ BOOST_AUTO_TEST_CASE(addrman_new_collisions)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK_EQUAL(addrman.size(), 0U);
+ uint32_t num_addrs{0};
- for (unsigned int i = 1; i < 18; i++) {
- CService addr = ResolveService("250.1.1." + ToString(i));
- BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs);
+
+ while (num_addrs < 22) { // Magic number! 250.1.1.1 - 250.1.1.22 do not collide with deterministic key = 1
+ CService addr = ResolveService("250.1.1." + ToString(++num_addrs));
+ BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
//Test: No collision in new table yet.
- BOOST_CHECK_EQUAL(addrman.size(), i);
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs);
}
//Test: new table collision!
- CService addr1 = ResolveService("250.1.1.18");
- BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 17U);
-
- CService addr2 = ResolveService("250.1.1.19");
- BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 18U);
+ CService addr1 = ResolveService("250.1.1." + ToString(++num_addrs));
+ uint32_t collisions{1};
+ BOOST_CHECK(addrman.Add({CAddress(addr1, NODE_NONE)}, source));
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs - collisions);
+
+ CService addr2 = ResolveService("250.1.1." + ToString(++num_addrs));
+ BOOST_CHECK(addrman.Add({CAddress(addr2, NODE_NONE)}, source));
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs - collisions);
}
BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
@@ -292,25 +329,28 @@ BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
CNetAddr source = ResolveIP("252.2.2.2");
- BOOST_CHECK_EQUAL(addrman.size(), 0U);
+ uint32_t num_addrs{0};
+
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs);
- for (unsigned int i = 1; i < 80; i++) {
- CService addr = ResolveService("250.1.1." + ToString(i));
- BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
+ while (num_addrs < 64) { // Magic number! 250.1.1.1 - 250.1.1.64 do not collide with deterministic key = 1
+ CService addr = ResolveService("250.1.1." + ToString(++num_addrs));
+ BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
addrman.Good(CAddress(addr, NODE_NONE));
//Test: No collision in tried table yet.
- BOOST_CHECK_EQUAL(addrman.size(), i);
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs);
}
//Test: tried table collision!
- CService addr1 = ResolveService("250.1.1.80");
- BOOST_CHECK(addrman.Add(CAddress(addr1, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 79U);
-
- CService addr2 = ResolveService("250.1.1.81");
- BOOST_CHECK(addrman.Add(CAddress(addr2, NODE_NONE), source));
- BOOST_CHECK_EQUAL(addrman.size(), 80U);
+ CService addr1 = ResolveService("250.1.1." + ToString(++num_addrs));
+ uint32_t collisions{1};
+ BOOST_CHECK(addrman.Add({CAddress(addr1, NODE_NONE)}, source));
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs - collisions);
+
+ CService addr2 = ResolveService("250.1.1." + ToString(++num_addrs));
+ BOOST_CHECK(addrman.Add({CAddress(addr2, NODE_NONE)}, source));
+ BOOST_CHECK_EQUAL(addrman.size(), num_addrs - collisions);
}
BOOST_AUTO_TEST_CASE(addrman_find)
@@ -326,9 +366,9 @@ BOOST_AUTO_TEST_CASE(addrman_find)
CNetAddr source1 = ResolveIP("250.1.2.1");
CNetAddr source2 = ResolveIP("250.1.2.2");
- BOOST_CHECK(addrman.Add(addr1, source1));
- BOOST_CHECK(!addrman.Add(addr2, source2));
- BOOST_CHECK(addrman.Add(addr3, source1));
+ BOOST_CHECK(addrman.Add({addr1}, source1));
+ BOOST_CHECK(!addrman.Add({addr2}, source2));
+ BOOST_CHECK(addrman.Add({addr3}, source1));
// Test: ensure Find returns an IP matching what we searched on.
CAddrInfo* info1 = addrman.Find(addr1);
@@ -410,11 +450,8 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
CNetAddr source2 = ResolveIP("250.2.3.3");
// Test: Ensure GetAddr works with new addresses.
- BOOST_CHECK(addrman.Add(addr1, source1));
- BOOST_CHECK(addrman.Add(addr2, source2));
- BOOST_CHECK(addrman.Add(addr3, source1));
- BOOST_CHECK(addrman.Add(addr4, source2));
- BOOST_CHECK(addrman.Add(addr5, source1));
+ BOOST_CHECK(addrman.Add({addr1, addr3, addr5}, source1));
+ BOOST_CHECK(addrman.Add({addr2, addr4}, source2));
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.
@@ -435,7 +472,7 @@ BOOST_AUTO_TEST_CASE(addrman_getaddr)
// Ensure that for all addrs in addrman, isTerrible == false.
addr.nTime = GetAdjustedTime();
- addrman.Add(addr, ResolveIP(strAddr));
+ addrman.Add({addr}, ResolveIP(strAddr));
if (i % 8 == 0)
addrman.Good(addr);
}
@@ -721,23 +758,23 @@ BOOST_AUTO_TEST_CASE(addrman_serialization)
{
std::vector<bool> asmap1 = FromBytes(asmap_raw, sizeof(asmap_raw) * 8);
- CAddrManTest addrman_asmap1(true, asmap1);
- CAddrManTest addrman_asmap1_dup(true, asmap1);
- CAddrManTest addrman_noasmap;
+ auto addrman_asmap1 = std::make_unique<CAddrManTest>(true, asmap1);
+ auto addrman_asmap1_dup = std::make_unique<CAddrManTest>(true, asmap1);
+ auto addrman_noasmap = std::make_unique<CAddrManTest>();
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
CAddress addr = CAddress(ResolveService("250.1.1.1"), NODE_NONE);
CNetAddr default_source;
- addrman_asmap1.Add(addr, default_source);
+ addrman_asmap1->Add({addr}, default_source);
- stream << addrman_asmap1;
+ stream << *addrman_asmap1;
// serizalizing/deserializing addrman with the same asmap
- stream >> addrman_asmap1_dup;
+ stream >> *addrman_asmap1_dup;
- std::pair<int, int> bucketAndEntry_asmap1 = addrman_asmap1.GetBucketAndEntry(addr);
- std::pair<int, int> bucketAndEntry_asmap1_dup = addrman_asmap1_dup.GetBucketAndEntry(addr);
+ std::pair<int, int> bucketAndEntry_asmap1 = addrman_asmap1->GetBucketAndEntry(addr);
+ std::pair<int, int> bucketAndEntry_asmap1_dup = addrman_asmap1_dup->GetBucketAndEntry(addr);
BOOST_CHECK(bucketAndEntry_asmap1.second != -1);
BOOST_CHECK(bucketAndEntry_asmap1_dup.second != -1);
@@ -745,44 +782,83 @@ BOOST_AUTO_TEST_CASE(addrman_serialization)
BOOST_CHECK(bucketAndEntry_asmap1.second == bucketAndEntry_asmap1_dup.second);
// deserializing asmaped peers.dat to non-asmaped addrman
- stream << addrman_asmap1;
- stream >> addrman_noasmap;
- std::pair<int, int> bucketAndEntry_noasmap = addrman_noasmap.GetBucketAndEntry(addr);
+ stream << *addrman_asmap1;
+ stream >> *addrman_noasmap;
+ std::pair<int, int> bucketAndEntry_noasmap = addrman_noasmap->GetBucketAndEntry(addr);
BOOST_CHECK(bucketAndEntry_noasmap.second != -1);
BOOST_CHECK(bucketAndEntry_asmap1.first != bucketAndEntry_noasmap.first);
BOOST_CHECK(bucketAndEntry_asmap1.second != bucketAndEntry_noasmap.second);
// deserializing non-asmaped peers.dat to asmaped addrman
- addrman_asmap1.Clear();
- addrman_noasmap.Clear();
- addrman_noasmap.Add(addr, default_source);
- stream << addrman_noasmap;
- stream >> addrman_asmap1;
- std::pair<int, int> bucketAndEntry_asmap1_deser = addrman_asmap1.GetBucketAndEntry(addr);
+ addrman_asmap1 = std::make_unique<CAddrManTest>(true, asmap1);
+ addrman_noasmap = std::make_unique<CAddrManTest>();
+ addrman_noasmap->Add({addr}, default_source);
+ stream << *addrman_noasmap;
+ stream >> *addrman_asmap1;
+ std::pair<int, int> bucketAndEntry_asmap1_deser = addrman_asmap1->GetBucketAndEntry(addr);
BOOST_CHECK(bucketAndEntry_asmap1_deser.second != -1);
BOOST_CHECK(bucketAndEntry_asmap1_deser.first != bucketAndEntry_noasmap.first);
BOOST_CHECK(bucketAndEntry_asmap1_deser.first == bucketAndEntry_asmap1_dup.first);
BOOST_CHECK(bucketAndEntry_asmap1_deser.second == bucketAndEntry_asmap1_dup.second);
// used to map to different buckets, now maps to the same bucket.
- addrman_asmap1.Clear();
- addrman_noasmap.Clear();
+ addrman_asmap1 = std::make_unique<CAddrManTest>(true, asmap1);
+ addrman_noasmap = std::make_unique<CAddrManTest>();
CAddress addr1 = CAddress(ResolveService("250.1.1.1"), NODE_NONE);
CAddress addr2 = CAddress(ResolveService("250.2.1.1"), NODE_NONE);
- addrman_noasmap.Add(addr, default_source);
- addrman_noasmap.Add(addr2, default_source);
- std::pair<int, int> bucketAndEntry_noasmap_addr1 = addrman_noasmap.GetBucketAndEntry(addr1);
- std::pair<int, int> bucketAndEntry_noasmap_addr2 = addrman_noasmap.GetBucketAndEntry(addr2);
+ addrman_noasmap->Add({addr, addr2}, default_source);
+ std::pair<int, int> bucketAndEntry_noasmap_addr1 = addrman_noasmap->GetBucketAndEntry(addr1);
+ std::pair<int, int> bucketAndEntry_noasmap_addr2 = addrman_noasmap->GetBucketAndEntry(addr2);
BOOST_CHECK(bucketAndEntry_noasmap_addr1.first != bucketAndEntry_noasmap_addr2.first);
BOOST_CHECK(bucketAndEntry_noasmap_addr1.second != bucketAndEntry_noasmap_addr2.second);
- stream << addrman_noasmap;
- stream >> addrman_asmap1;
- std::pair<int, int> bucketAndEntry_asmap1_deser_addr1 = addrman_asmap1.GetBucketAndEntry(addr1);
- std::pair<int, int> bucketAndEntry_asmap1_deser_addr2 = addrman_asmap1.GetBucketAndEntry(addr2);
+ stream << *addrman_noasmap;
+ stream >> *addrman_asmap1;
+ std::pair<int, int> bucketAndEntry_asmap1_deser_addr1 = addrman_asmap1->GetBucketAndEntry(addr1);
+ std::pair<int, int> bucketAndEntry_asmap1_deser_addr2 = addrman_asmap1->GetBucketAndEntry(addr2);
BOOST_CHECK(bucketAndEntry_asmap1_deser_addr1.first == bucketAndEntry_asmap1_deser_addr2.first);
BOOST_CHECK(bucketAndEntry_asmap1_deser_addr1.second != bucketAndEntry_asmap1_deser_addr2.second);
}
+BOOST_AUTO_TEST_CASE(remove_invalid)
+{
+ // Confirm that invalid addresses are ignored in unserialization.
+
+ auto addrman = std::make_unique<CAddrManTest>();
+ CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
+
+ const CAddress new1{ResolveService("5.5.5.5"), NODE_NONE};
+ const CAddress new2{ResolveService("6.6.6.6"), NODE_NONE};
+ const CAddress tried1{ResolveService("7.7.7.7"), NODE_NONE};
+ const CAddress tried2{ResolveService("8.8.8.8"), NODE_NONE};
+
+ addrman->Add({new1, tried1, new2, tried2}, CNetAddr{});
+ addrman->Good(tried1);
+ addrman->Good(tried2);
+ BOOST_REQUIRE_EQUAL(addrman->size(), 4);
+
+ stream << *addrman;
+
+ const std::string str{stream.str()};
+ size_t pos;
+
+ const char new2_raw[]{6, 6, 6, 6};
+ const uint8_t new2_raw_replacement[]{0, 0, 0, 0}; // 0.0.0.0 is !IsValid()
+ pos = str.find(new2_raw, 0, sizeof(new2_raw));
+ BOOST_REQUIRE(pos != std::string::npos);
+ BOOST_REQUIRE(pos + sizeof(new2_raw_replacement) <= stream.size());
+ memcpy(stream.data() + pos, new2_raw_replacement, sizeof(new2_raw_replacement));
+
+ const char tried2_raw[]{8, 8, 8, 8};
+ const uint8_t tried2_raw_replacement[]{255, 255, 255, 255}; // 255.255.255.255 is !IsValid()
+ pos = str.find(tried2_raw, 0, sizeof(tried2_raw));
+ BOOST_REQUIRE(pos != std::string::npos);
+ BOOST_REQUIRE(pos + sizeof(tried2_raw_replacement) <= stream.size());
+ memcpy(stream.data() + pos, tried2_raw_replacement, sizeof(tried2_raw_replacement));
+
+ addrman = std::make_unique<CAddrManTest>();
+ stream >> *addrman;
+ BOOST_CHECK_EQUAL(addrman->size(), 2);
+}
BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision)
{
@@ -797,7 +873,7 @@ BOOST_AUTO_TEST_CASE(addrman_selecttriedcollision)
CNetAddr source = ResolveIP("252.2.2.2");
for (unsigned int i = 1; i < 23; i++) {
CService addr = ResolveService("250.1.1."+ToString(i));
- BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
+ BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
addrman.Good(addr);
// No collisions yet.
@@ -820,11 +896,11 @@ BOOST_AUTO_TEST_CASE(addrman_noevict)
{
CAddrManTest addrman;
- // Add twenty two addresses.
+ // Add 35 addresses.
CNetAddr source = ResolveIP("252.2.2.2");
- for (unsigned int i = 1; i < 23; i++) {
+ for (unsigned int i = 1; i < 36; i++) {
CService addr = ResolveService("250.1.1."+ToString(i));
- BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
+ BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
addrman.Good(addr);
// No collision yet.
@@ -832,22 +908,22 @@ BOOST_AUTO_TEST_CASE(addrman_noevict)
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
}
- // Collision between 23 and 19.
- CService addr23 = ResolveService("250.1.1.23");
- BOOST_CHECK(addrman.Add(CAddress(addr23, NODE_NONE), source));
- addrman.Good(addr23);
+ // Collision between 36 and 19.
+ CService addr36 = ResolveService("250.1.1.36");
+ BOOST_CHECK(addrman.Add({CAddress(addr36, NODE_NONE)}, source));
+ addrman.Good(addr36);
- BOOST_CHECK(addrman.size() == 23);
- BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.19:0");
+ BOOST_CHECK(addrman.size() == 36);
+ BOOST_CHECK_EQUAL(addrman.SelectTriedCollision().ToString(), "250.1.1.19:0");
- // 23 should be discarded and 19 not evicted.
+ // 36 should be discarded and 19 not evicted.
addrman.ResolveCollisions();
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
// Lets create two collisions.
- for (unsigned int i = 24; i < 33; i++) {
+ for (unsigned int i = 37; i < 59; i++) {
CService addr = ResolveService("250.1.1."+ToString(i));
- BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
+ BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
addrman.Good(addr);
BOOST_CHECK(addrman.size() == i);
@@ -855,17 +931,17 @@ BOOST_AUTO_TEST_CASE(addrman_noevict)
}
// Cause a collision.
- CService addr33 = ResolveService("250.1.1.33");
- BOOST_CHECK(addrman.Add(CAddress(addr33, NODE_NONE), source));
- addrman.Good(addr33);
- BOOST_CHECK(addrman.size() == 33);
+ CService addr59 = ResolveService("250.1.1.59");
+ BOOST_CHECK(addrman.Add({CAddress(addr59, NODE_NONE)}, source));
+ addrman.Good(addr59);
+ BOOST_CHECK(addrman.size() == 59);
- BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.27:0");
+ BOOST_CHECK_EQUAL(addrman.SelectTriedCollision().ToString(), "250.1.1.10:0");
// Cause a second collision.
- BOOST_CHECK(!addrman.Add(CAddress(addr23, NODE_NONE), source));
- addrman.Good(addr23);
- BOOST_CHECK(addrman.size() == 33);
+ BOOST_CHECK(!addrman.Add({CAddress(addr36, NODE_NONE)}, source));
+ addrman.Good(addr36);
+ BOOST_CHECK(addrman.size() == 59);
BOOST_CHECK(addrman.SelectTriedCollision().ToString() != "[::]:0");
addrman.ResolveCollisions();
@@ -881,11 +957,11 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
// Empty addrman should return blank addrman info.
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
- // Add twenty two addresses.
+ // Add 35 addresses
CNetAddr source = ResolveIP("252.2.2.2");
- for (unsigned int i = 1; i < 23; i++) {
+ for (unsigned int i = 1; i < 36; i++) {
CService addr = ResolveService("250.1.1."+ToString(i));
- BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
+ BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
addrman.Good(addr);
// No collision yet.
@@ -893,38 +969,111 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
}
- // Collision between 23 and 19.
- CService addr = ResolveService("250.1.1.23");
- BOOST_CHECK(addrman.Add(CAddress(addr, NODE_NONE), source));
+ // Collision between 36 and 19.
+ CService addr = ResolveService("250.1.1.36");
+ BOOST_CHECK(addrman.Add({CAddress(addr, NODE_NONE)}, source));
addrman.Good(addr);
- BOOST_CHECK(addrman.size() == 23);
+ BOOST_CHECK_EQUAL(addrman.size(), 36);
CAddrInfo info = addrman.SelectTriedCollision();
- BOOST_CHECK(info.ToString() == "250.1.1.19:0");
+ BOOST_CHECK_EQUAL(info.ToString(), "250.1.1.19:0");
// Ensure test of address fails, so that it is evicted.
addrman.SimConnFail(info);
- // Should swap 23 for 19.
+ // Should swap 36 for 19.
addrman.ResolveCollisions();
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
- // If 23 was swapped for 19, then this should cause no collisions.
- BOOST_CHECK(!addrman.Add(CAddress(addr, NODE_NONE), source));
+ // If 36 was swapped for 19, then this should cause no collisions.
+ BOOST_CHECK(!addrman.Add({CAddress(addr, NODE_NONE)}, source));
addrman.Good(addr);
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
- // If we insert 19 is should collide with 23.
+ // If we insert 19 it should collide with 36
CService addr19 = ResolveService("250.1.1.19");
- BOOST_CHECK(!addrman.Add(CAddress(addr19, NODE_NONE), source));
+ BOOST_CHECK(!addrman.Add({CAddress(addr19, NODE_NONE)}, source));
addrman.Good(addr19);
- BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "250.1.1.23:0");
+ BOOST_CHECK_EQUAL(addrman.SelectTriedCollision().ToString(), "250.1.1.36:0");
addrman.ResolveCollisions();
BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
}
+BOOST_AUTO_TEST_CASE(caddrdb_read)
+{
+ CAddrManUncorrupted addrmanUncorrupted;
+
+ CService addr1, addr2, addr3;
+ BOOST_CHECK(Lookup("250.7.1.1", addr1, 8333, false));
+ BOOST_CHECK(Lookup("250.7.2.2", addr2, 9999, false));
+ BOOST_CHECK(Lookup("250.7.3.3", addr3, 9999, false));
+ BOOST_CHECK(Lookup("250.7.3.3"s, addr3, 9999, false));
+ BOOST_CHECK(!Lookup("250.7.3.3\0example.com"s, addr3, 9999, false));
+
+ // Add three addresses to new table.
+ CService source;
+ BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false));
+ std::vector<CAddress> addresses{CAddress(addr1, NODE_NONE), CAddress(addr2, NODE_NONE), CAddress(addr3, NODE_NONE)};
+ BOOST_CHECK(addrmanUncorrupted.Add(addresses, source));
+ BOOST_CHECK(addrmanUncorrupted.size() == 3);
+
+ // Test that the de-serialization does not throw an exception.
+ CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
+ bool exceptionThrown = false;
+ CAddrMan addrman1(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 100);
+
+ BOOST_CHECK(addrman1.size() == 0);
+ try {
+ unsigned char pchMsgTmp[4];
+ ssPeers1 >> pchMsgTmp;
+ ssPeers1 >> addrman1;
+ } catch (const std::exception&) {
+ exceptionThrown = true;
+ }
+
+ BOOST_CHECK(addrman1.size() == 3);
+ BOOST_CHECK(exceptionThrown == false);
+
+ // Test that CAddrDB::Read creates an addrman with the correct number of addrs.
+ CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted);
+
+ CAddrMan addrman2(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 100);
+ BOOST_CHECK(addrman2.size() == 0);
+ BOOST_CHECK(CAddrDB::Read(addrman2, ssPeers2));
+ BOOST_CHECK(addrman2.size() == 3);
+}
+
+
+BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
+{
+ CAddrManCorrupted addrmanCorrupted;
+
+ // Test that the de-serialization of corrupted addrman throws an exception.
+ CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted);
+ bool exceptionThrown = false;
+ CAddrMan addrman1(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 100);
+ BOOST_CHECK(addrman1.size() == 0);
+ try {
+ unsigned char pchMsgTmp[4];
+ ssPeers1 >> pchMsgTmp;
+ ssPeers1 >> addrman1;
+ } catch (const std::exception&) {
+ exceptionThrown = true;
+ }
+ // Even through de-serialization failed addrman is not left in a clean state.
+ BOOST_CHECK(addrman1.size() == 1);
+ BOOST_CHECK(exceptionThrown);
+
+ // Test that CAddrDB::Read fails if peers.dat is corrupt
+ CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted);
+
+ CAddrMan addrman2(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 100);
+ BOOST_CHECK(addrman2.size() == 0);
+ BOOST_CHECK(!CAddrDB::Read(addrman2, ssPeers2));
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp
index fb16c92647..a89868e1ef 100644
--- a/src/test/bip32_tests.cpp
+++ b/src/test/bip32_tests.cpp
@@ -14,6 +14,8 @@
#include <string>
#include <vector>
+namespace {
+
struct TestDerivation {
std::string pub;
std::string prv;
@@ -99,7 +101,26 @@ TestVector test4 =
"xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1",
0);
-static void RunTest(const TestVector &test) {
+const std::vector<std::string> TEST5 = {
+ "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm",
+ "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH",
+ "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Txnt3siSujt9RCVYsx4qHZGc62TG4McvMGcAUjeuwZdduYEvFn",
+ "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGpWnsj83BHtEy5Zt8CcDr1UiRXuWCmTQLxEK9vbz5gPstX92JQ",
+ "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6N8ZMMXctdiCjxTNq964yKkwrkBJJwpzZS4HS2fxvyYUA4q2Xe4",
+ "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fEQ3Qen6J",
+ "xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv",
+ "xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ",
+ "xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN",
+ "xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8",
+ "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4",
+ "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9",
+ "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx",
+ "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G",
+ "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Q5JXayek4PRsn35jii4veMimro1xefsM58PgBMrvdYre8QyULY",
+ "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHL"
+};
+
+void RunTest(const TestVector &test) {
std::vector<unsigned char> seed = ParseHex(test.strHexMaster);
CExtKey key;
CExtPubKey pubkey;
@@ -133,6 +154,8 @@ static void RunTest(const TestVector &test) {
}
}
+} // namespace
+
BOOST_FIXTURE_TEST_SUITE(bip32_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(bip32_test1) {
@@ -151,4 +174,13 @@ BOOST_AUTO_TEST_CASE(bip32_test4) {
RunTest(test4);
}
+BOOST_AUTO_TEST_CASE(bip32_test5) {
+ for (const auto& str : TEST5) {
+ auto dec_extkey = DecodeExtKey(str);
+ auto dec_extpubkey = DecodeExtPubKey(str);
+ BOOST_CHECK_MESSAGE(!dec_extkey.key.IsValid(), "Decoding '" + str + "' as xprv should fail");
+ BOOST_CHECK_MESSAGE(!dec_extpubkey.pubkey.IsValid(), "Decoding '" + str + "' as xpub should fail");
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp
index edec5f0a31..5b3b39fdb8 100644
--- a/src/test/crypto_tests.cpp
+++ b/src/test/crypto_tests.cpp
@@ -617,7 +617,7 @@ static void TestChaCha20Poly1305AEAD(bool must_succeed, unsigned int expected_aa
ChaCha20Poly1305AEAD aead(aead_K_1.data(), aead_K_1.size(), aead_K_2.data(), aead_K_2.size());
// create a chacha20 instance to compare against
- ChaCha20 cmp_ctx(aead_K_2.data(), 32);
+ ChaCha20 cmp_ctx(aead_K_1.data(), 32);
// encipher
bool res = aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, ciphertext_buf.data(), ciphertext_buf.size(), plaintext_buf.data(), plaintext_buf.size(), true);
@@ -708,8 +708,8 @@ BOOST_AUTO_TEST_CASE(chacha20_poly1305_aead_testvector)
"b1a03d5bd2855d60699e7d3a3133fa47be740fe4e4c1f967555e2d9271f31c3a8bd94d54b5ecabbc41ffbb0c90924080");
TestChaCha20Poly1305AEAD(true, 255,
"ff0000f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9",
- "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"ff0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"c640c1711e3ee904ac35c57ab9791c8a1c408603a90b77a83b54f6c844cb4b06d94e7fc6c800e165acd66147e80ec45a567f6ce66d05ec0cae679dceeb890017",
"3940c1e92da4582ff6f92a776aeb14d014d384eeb30f660dacf70a14a23fd31e91212701334e2ce1acf5199dc84f4d61ddbe6571bca5af874b4c9226c26e650995d157644e1848b96ed6c2102d5489a050e71d29a5a66ece11de5fb5c9558d54da28fe45b0bc4db4e5b88030bfc4a352b4b7068eccf656bae7ad6a35615315fc7c49d4200388d5eca67c2e822e069336c69b40db67e0f3c81209c50f3216a4b89fb3ae1b984b7851a2ec6f68ab12b101ab120e1ea7313bb93b5a0f71185c7fea017ddb92769861c29dba4fbc432280d5dff21b36d1c4c790128b22699950bb18bf74c448cdfe547d8ed4f657d8005fdc0cd7a050c2d46050a44c4376355858981fbe8b184288276e7a93eabc899c4a",
"f039c6689eaeef0456685200feaab9d54bbd9acde4410a3b6f4321296f4a8ca2604b49727d8892c57e005d799b2a38e85e809f20146e08eec75169691c8d4f54a0d51a1e1c7b381e0474eb02f994be9415ef3ffcbd2343f0601e1f3b172a1d494f838824e4df570f8e3b0c04e27966e36c82abd352d07054ef7bd36b84c63f9369afe7ed79b94f953873006b920c3fa251a771de1b63da927058ade119aa898b8c97e42a606b2f6df1e2d957c22f7593c1e2002f4252f4c9ae4bf773499e5cfcfe14dfc1ede26508953f88553bf4a76a802f6a0068d59295b01503fd9a600067624203e880fdf53933b96e1f4d9eb3f4e363dd8165a278ff667a41ee42b9892b077cefff92b93441f7be74cf10e6cd");
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index 5668ead1fb..0bfe6eecd9 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
const CChainParams& chainparams = Params();
auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr,
- *m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
+ *m_node.chainman, *m_node.mempool, false);
// Mock an outbound peer
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
const CChainParams& chainparams = Params();
auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman);
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr,
- *m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
+ *m_node.chainman, *m_node.mempool, false);
constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
CConnman::Options options;
@@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = std::make_unique<ConnmanTestMsg>(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);
+ *m_node.chainman, *m_node.mempool, false);
CNetAddr tor_netaddr;
BOOST_REQUIRE(
@@ -288,7 +288,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", 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);
+ *m_node.chainman, *m_node.mempool, false);
banman->ClearBanned();
int64_t nStartTime = GetTime();
diff --git a/src/test/fuzz/addrdb.cpp b/src/test/fuzz/addrdb.cpp
deleted file mode 100644
index d15c785673..0000000000
--- a/src/test/fuzz/addrdb.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 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 <addrdb.h>
-#include <test/fuzz/FuzzedDataProvider.h>
-#include <test/fuzz/fuzz.h>
-#include <test/fuzz/util.h>
-
-#include <cassert>
-#include <cstdint>
-#include <optional>
-#include <string>
-#include <vector>
-
-FUZZ_TARGET(addrdb)
-{
- FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
-
- // The point of this code is to exercise all CBanEntry constructors.
- const CBanEntry ban_entry = [&] {
- switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 2)) {
- case 0:
- return CBanEntry{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
- break;
- case 1: {
- const std::optional<CBanEntry> ban_entry = ConsumeDeserializable<CBanEntry>(fuzzed_data_provider);
- if (ban_entry) {
- return *ban_entry;
- }
- break;
- }
- }
- return CBanEntry{};
- }();
- (void)ban_entry; // currently unused
-}
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
index db0b461873..e95126a80f 100644
--- a/src/test/fuzz/addrman.cpp
+++ b/src/test/fuzz/addrman.cpp
@@ -12,6 +12,7 @@
#include <time.h>
#include <util/asmap.h>
+#include <cassert>
#include <cstdint>
#include <optional>
#include <string>
@@ -25,45 +26,233 @@ void initialize_addrman()
class CAddrManDeterministic : public CAddrMan
{
public:
- void MakeDeterministic(const uint256& random_seed)
+ FuzzedDataProvider& m_fuzzed_data_provider;
+
+ explicit CAddrManDeterministic(std::vector<bool> asmap, FuzzedDataProvider& fuzzed_data_provider)
+ : CAddrMan(std::move(asmap), /* deterministic */ true, /* consistency_check_ratio */ 0)
+ , m_fuzzed_data_provider(fuzzed_data_provider)
{
- insecure_rand = FastRandomContext{random_seed};
- Clear();
+ WITH_LOCK(cs, insecure_rand = FastRandomContext{ConsumeUInt256(fuzzed_data_provider)});
+ }
+
+ /**
+ * Generate a random address. Always returns a valid address.
+ */
+ CNetAddr RandAddr() EXCLUSIVE_LOCKS_REQUIRED(cs)
+ {
+ CNetAddr addr;
+ if (m_fuzzed_data_provider.remaining_bytes() > 1 && m_fuzzed_data_provider.ConsumeBool()) {
+ addr = ConsumeNetAddr(m_fuzzed_data_provider);
+ } else {
+ // The networks [1..6] correspond to CNetAddr::BIP155Network (private).
+ static const std::map<uint8_t, uint8_t> net_len_map = {{1, ADDR_IPV4_SIZE},
+ {2, ADDR_IPV6_SIZE},
+ {4, ADDR_TORV3_SIZE},
+ {5, ADDR_I2P_SIZE},
+ {6, ADDR_CJDNS_SIZE}};
+ uint8_t net = insecure_rand.randrange(5) + 1; // [1..5]
+ if (net == 3) {
+ net = 6;
+ }
+
+ CDataStream s(SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
+
+ s << net;
+ s << insecure_rand.randbytes(net_len_map.at(net));
+
+ s >> addr;
+ }
+
+ // Return a dummy IPv4 5.5.5.5 if we generated an invalid address.
+ if (!addr.IsValid()) {
+ in_addr v4_addr = {};
+ v4_addr.s_addr = 0x05050505;
+ addr = CNetAddr{v4_addr};
+ }
+
+ return addr;
+ }
+
+ /**
+ * Fill this addrman with lots of addresses from lots of sources.
+ */
+ void Fill()
+ {
+ LOCK(cs);
+
+ // Add some of the addresses directly to the "tried" table.
+
+ // 0, 1, 2, 3 corresponding to 0%, 100%, 50%, 33%
+ const size_t n = m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 3);
+
+ const size_t num_sources = m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(10, 50);
+ CNetAddr prev_source;
+ // Use insecure_rand inside the loops instead of m_fuzzed_data_provider because when
+ // the latter is exhausted it just returns 0.
+ for (size_t i = 0; i < num_sources; ++i) {
+ const auto source = RandAddr();
+ const size_t num_addresses = insecure_rand.randrange(500) + 1; // [1..500]
+
+ for (size_t j = 0; j < num_addresses; ++j) {
+ const auto addr = CAddress{CService{RandAddr(), 8333}, NODE_NETWORK};
+ const auto time_penalty = insecure_rand.randrange(100000001);
+#if 1
+ // 2.83 sec to fill.
+ if (n > 0 && mapInfo.size() % n == 0 && mapAddr.find(addr) == mapAddr.end()) {
+ // Add to the "tried" table (if the bucket slot is free).
+ const CAddrInfo dummy{addr, source};
+ const int bucket = dummy.GetTriedBucket(nKey, m_asmap);
+ const int bucket_pos = dummy.GetBucketPosition(nKey, false, bucket);
+ if (vvTried[bucket][bucket_pos] == -1) {
+ int id;
+ CAddrInfo* addr_info = Create(addr, source, &id);
+ vvTried[bucket][bucket_pos] = id;
+ addr_info->fInTried = true;
+ ++nTried;
+ }
+ } else {
+ // Add to the "new" table.
+ Add_(addr, source, time_penalty);
+ }
+#else
+ // 261.91 sec to fill.
+ Add_(addr, source, time_penalty);
+ if (n > 0 && mapInfo.size() % n == 0) {
+ Good_(addr, false, GetTime());
+ }
+#endif
+ // Add 10% of the addresses from more than one source.
+ if (insecure_rand.randrange(10) == 0 && prev_source.IsValid()) {
+ Add_(addr, prev_source, time_penalty);
+ }
+ }
+ prev_source = source;
+ }
+ }
+
+ /**
+ * Compare with another AddrMan.
+ * This compares:
+ * - the values in `mapInfo` (the keys aka ids are ignored)
+ * - vvNew entries refer to the same addresses
+ * - vvTried entries refer to the same addresses
+ */
+ bool operator==(const CAddrManDeterministic& other)
+ {
+ LOCK2(cs, other.cs);
+
+ if (mapInfo.size() != other.mapInfo.size() || nNew != other.nNew ||
+ nTried != other.nTried) {
+ return false;
+ }
+
+ // Check that all values in `mapInfo` are equal to all values in `other.mapInfo`.
+ // Keys may be different.
+
+ using CAddrInfoHasher = std::function<size_t(const CAddrInfo&)>;
+ using CAddrInfoEq = std::function<bool(const CAddrInfo&, const CAddrInfo&)>;
+
+ CNetAddrHash netaddr_hasher;
+
+ CAddrInfoHasher addrinfo_hasher = [&netaddr_hasher](const CAddrInfo& a) {
+ return netaddr_hasher(static_cast<CNetAddr>(a)) ^ netaddr_hasher(a.source) ^
+ a.nLastSuccess ^ a.nAttempts ^ a.nRefCount ^ a.fInTried;
+ };
+
+ CAddrInfoEq addrinfo_eq = [](const CAddrInfo& lhs, const CAddrInfo& rhs) {
+ return static_cast<CNetAddr>(lhs) == static_cast<CNetAddr>(rhs) &&
+ lhs.source == rhs.source && lhs.nLastSuccess == rhs.nLastSuccess &&
+ lhs.nAttempts == rhs.nAttempts && lhs.nRefCount == rhs.nRefCount &&
+ lhs.fInTried == rhs.fInTried;
+ };
+
+ using Addresses = std::unordered_set<CAddrInfo, CAddrInfoHasher, CAddrInfoEq>;
+
+ const size_t num_addresses{mapInfo.size()};
+
+ Addresses addresses{num_addresses, addrinfo_hasher, addrinfo_eq};
+ for (const auto& [id, addr] : mapInfo) {
+ addresses.insert(addr);
+ }
+
+ Addresses other_addresses{num_addresses, addrinfo_hasher, addrinfo_eq};
+ for (const auto& [id, addr] : other.mapInfo) {
+ other_addresses.insert(addr);
+ }
+
+ if (addresses != other_addresses) {
+ return false;
+ }
+
+ auto IdsReferToSameAddress = [&](int id, int other_id) EXCLUSIVE_LOCKS_REQUIRED(cs, other.cs) {
+ if (id == -1 && other_id == -1) {
+ return true;
+ }
+ if ((id == -1 && other_id != -1) || (id != -1 && other_id == -1)) {
+ return false;
+ }
+ return mapInfo.at(id) == other.mapInfo.at(other_id);
+ };
+
+ // Check that `vvNew` contains the same addresses as `other.vvNew`. Notice - `vvNew[i][j]`
+ // contains just an id and the address is to be found in `mapInfo.at(id)`. The ids
+ // themselves may differ between `vvNew` and `other.vvNew`.
+ for (size_t i = 0; i < ADDRMAN_NEW_BUCKET_COUNT; ++i) {
+ for (size_t j = 0; j < ADDRMAN_BUCKET_SIZE; ++j) {
+ if (!IdsReferToSameAddress(vvNew[i][j], other.vvNew[i][j])) {
+ return false;
+ }
+ }
+ }
+
+ // Same for `vvTried`.
+ for (size_t i = 0; i < ADDRMAN_TRIED_BUCKET_COUNT; ++i) {
+ for (size_t j = 0; j < ADDRMAN_BUCKET_SIZE; ++j) {
+ if (!IdsReferToSameAddress(vvTried[i][j], other.vvTried[i][j])) {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
};
+[[nodiscard]] inline std::vector<bool> ConsumeAsmap(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
+ if (!SanityCheckASMap(asmap)) asmap.clear();
+ return asmap;
+}
+
FUZZ_TARGET_INIT(addrman, initialize_addrman)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
SetMockTime(ConsumeTime(fuzzed_data_provider));
- CAddrManDeterministic addr_man;
- addr_man.MakeDeterministic(ConsumeUInt256(fuzzed_data_provider));
+ std::vector<bool> asmap = ConsumeAsmap(fuzzed_data_provider);
+ auto addr_man_ptr = std::make_unique<CAddrManDeterministic>(asmap, fuzzed_data_provider);
if (fuzzed_data_provider.ConsumeBool()) {
- addr_man.m_asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
- if (!SanityCheckASMap(addr_man.m_asmap)) {
- addr_man.m_asmap.clear();
+ const std::vector<uint8_t> serialized_data{ConsumeRandomLengthByteVector(fuzzed_data_provider)};
+ CDataStream ds(serialized_data, SER_DISK, INIT_PROTO_VERSION);
+ const auto ser_version{fuzzed_data_provider.ConsumeIntegral<int32_t>()};
+ ds.SetVersion(ser_version);
+ try {
+ ds >> *addr_man_ptr;
+ } catch (const std::ios_base::failure&) {
+ addr_man_ptr = std::make_unique<CAddrManDeterministic>(asmap, fuzzed_data_provider);
}
}
+ CAddrManDeterministic& addr_man = *addr_man_ptr;
while (fuzzed_data_provider.ConsumeBool()) {
CallOneOf(
fuzzed_data_provider,
[&] {
- addr_man.Clear();
- },
- [&] {
addr_man.ResolveCollisions();
},
[&] {
(void)addr_man.SelectTriedCollision();
},
[&] {
- const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
- const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
- if (opt_address && opt_net_addr) {
- addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
- }
- },
- [&] {
std::vector<CAddress> addresses;
while (fuzzed_data_provider.ConsumeBool()) {
const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
@@ -80,7 +269,7 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
[&] {
const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
if (opt_service) {
- addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
+ addr_man.Good(*opt_service, ConsumeTime(fuzzed_data_provider));
}
},
[&] {
@@ -103,12 +292,30 @@ FUZZ_TARGET_INIT(addrman, initialize_addrman)
});
}
const CAddrMan& const_addr_man{addr_man};
- (void)/*const_*/addr_man.GetAddr(
+ (void)const_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);
- (void)/*const_*/addr_man.Select(fuzzed_data_provider.ConsumeBool());
+ (void)const_addr_man.Select(fuzzed_data_provider.ConsumeBool());
(void)const_addr_man.size();
CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
data_stream << const_addr_man;
}
+
+// Check that serialize followed by unserialize produces the same addrman.
+FUZZ_TARGET_INIT(addrman_serdeser, initialize_addrman)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
+
+ std::vector<bool> asmap = ConsumeAsmap(fuzzed_data_provider);
+ CAddrManDeterministic addr_man1{asmap, fuzzed_data_provider};
+ CAddrManDeterministic addr_man2{asmap, fuzzed_data_provider};
+
+ CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
+
+ addr_man1.Fill();
+ data_stream << addr_man1;
+ data_stream >> addr_man2;
+ assert(addr_man1 == addr_man2);
+}
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
index 182aabc79b..561cc83c72 100644
--- a/src/test/fuzz/banman.cpp
+++ b/src/test/fuzz/banman.cpp
@@ -41,10 +41,6 @@ static bool operator==(const CBanEntry& lhs, const CBanEntry& rhs)
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));
fs::path banlist_file = gArgs.GetDataDirNet() / "fuzzed_banlist";
@@ -52,8 +48,7 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
const bool start_with_corrupted_banlist{fuzzed_data_provider.ConsumeBool()};
bool force_read_and_write_to_err{false};
if (start_with_corrupted_banlist) {
- const std::string sfx{fuzzed_data_provider.ConsumeBool() ? ".dat" : ".json"};
- assert(WriteBinaryFile(banlist_file.string() + sfx,
+ assert(WriteBinaryFile(banlist_file.string() + ".json",
fuzzed_data_provider.ConsumeRandomLengthString()));
} else {
force_read_and_write_to_err = fuzzed_data_provider.ConsumeBool();
@@ -64,7 +59,11 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
{
BanMan ban_man{banlist_file, /* client_interface */ nullptr, /* default_ban_time */ ConsumeBanTimeOffset(fuzzed_data_provider)};
- while (--limit_max_ops >= 0 && fuzzed_data_provider.ConsumeBool()) {
+ // 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).
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
+ {
CallOneOf(
fuzzed_data_provider,
[&] {
@@ -112,6 +111,5 @@ FUZZ_TARGET_INIT(banman, initialize_banman)
assert(banmap == banmap_read);
}
}
- fs::remove(banlist_file.string() + ".dat");
fs::remove(banlist_file.string() + ".json");
}
diff --git a/src/test/fuzz/blockfilter.cpp b/src/test/fuzz/blockfilter.cpp
index 7fa06085f8..96f049625d 100644
--- a/src/test/fuzz/blockfilter.cpp
+++ b/src/test/fuzz/blockfilter.cpp
@@ -36,9 +36,10 @@ FUZZ_TARGET(blockfilter)
(void)gcs_filter.GetEncoded();
(void)gcs_filter.Match(ConsumeRandomLengthByteVector(fuzzed_data_provider));
GCSFilter::ElementSet element_set;
- while (fuzzed_data_provider.ConsumeBool()) {
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 30000)
+ {
element_set.insert(ConsumeRandomLengthByteVector(fuzzed_data_provider));
- gcs_filter.MatchAny(element_set);
}
+ gcs_filter.MatchAny(element_set);
}
}
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index f452696689..bbdb2c6917 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -258,7 +258,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
// consensus/tx_verify.cpp:130: unsigned int GetP2SHSigOpCount(const CTransaction &, const CCoinsViewCache &): Assertion `!coin.IsSpent()' failed.
return;
}
- const int flags = fuzzed_data_provider.ConsumeIntegral<int>();
+ const auto flags{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
if (!transaction.vin.empty() && (flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
// Avoid:
// script/interpreter.cpp:1705: size_t CountWitnessSigOps(const CScript &, const CScript &, const CScriptWitness *, unsigned int): Assertion `(flags & SCRIPT_VERIFY_P2SH) != 0' failed.
diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp
index bbec5943af..01741103e4 100644
--- a/src/test/fuzz/connman.cpp
+++ b/src/test/fuzz/connman.cpp
@@ -25,7 +25,7 @@ FUZZ_TARGET_INIT(connman, initialize_connman)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
SetMockTime(ConsumeTime(fuzzed_data_provider));
- CAddrMan addrman;
+ CAddrMan addrman(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 0);
CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>(), addrman, fuzzed_data_provider.ConsumeBool()};
CNetAddr random_netaddr;
CNode random_node = ConsumeNode(fuzzed_data_provider);
@@ -104,12 +104,6 @@ FUZZ_TARGET_INIT(connman, initialize_connman)
connman.RemoveAddedNode(random_string);
},
[&] {
- const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
- if (SanityCheckASMap(asmap)) {
- connman.SetAsmap(asmap);
- }
- },
- [&] {
connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
},
[&] {
diff --git a/src/test/fuzz/crypto.cpp b/src/test/fuzz/crypto.cpp
index f83747e424..84b95117e2 100644
--- a/src/test/fuzz/crypto.cpp
+++ b/src/test/fuzz/crypto.cpp
@@ -19,10 +19,6 @@
FUZZ_TARGET(crypto)
{
- // Hashing is expensive with sanitizers enabled, so limit the number of
- // calls
- int limit_max_ops{30};
-
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
std::vector<uint8_t> data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
if (data.empty()) {
@@ -40,7 +36,8 @@ FUZZ_TARGET(crypto)
SHA3_256 sha3;
CSipHasher sip_hasher{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
- while (--limit_max_ops >= 0 && fuzzed_data_provider.ConsumeBool()) {
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 30)
+ {
CallOneOf(
fuzzed_data_provider,
[&] {
diff --git a/src/test/fuzz/data_stream.cpp b/src/test/fuzz/data_stream.cpp
index 473caec6ff..8178878c30 100644
--- a/src/test/fuzz/data_stream.cpp
+++ b/src/test/fuzz/data_stream.cpp
@@ -21,6 +21,6 @@ FUZZ_TARGET_INIT(data_stream_addr_man, initialize_data_stream_addr_man)
{
FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
CDataStream data_stream = ConsumeDataStream(fuzzed_data_provider);
- CAddrMan addr_man;
+ CAddrMan addr_man(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 0);
CAddrDB::Read(addr_man, data_stream);
}
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index 721e4360d0..83ae1680e3 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -100,228 +100,213 @@ void AssertEqualAfterSerializeDeserialize(const T& obj, const int version = INIT
} // namespace
FUZZ_TARGET_DESERIALIZE(block_filter_deserialize, {
- BlockFilter block_filter;
- DeserializeFromFuzzingInput(buffer, block_filter);
+ BlockFilter block_filter;
+ DeserializeFromFuzzingInput(buffer, block_filter);
})
FUZZ_TARGET_DESERIALIZE(addr_info_deserialize, {
- CAddrInfo addr_info;
- DeserializeFromFuzzingInput(buffer, addr_info);
+ CAddrInfo addr_info;
+ DeserializeFromFuzzingInput(buffer, addr_info);
})
FUZZ_TARGET_DESERIALIZE(block_file_info_deserialize, {
- CBlockFileInfo block_file_info;
- DeserializeFromFuzzingInput(buffer, block_file_info);
+ CBlockFileInfo block_file_info;
+ DeserializeFromFuzzingInput(buffer, block_file_info);
})
FUZZ_TARGET_DESERIALIZE(block_header_and_short_txids_deserialize, {
- CBlockHeaderAndShortTxIDs block_header_and_short_txids;
- DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
+ CBlockHeaderAndShortTxIDs block_header_and_short_txids;
+ DeserializeFromFuzzingInput(buffer, block_header_and_short_txids);
})
FUZZ_TARGET_DESERIALIZE(fee_rate_deserialize, {
- CFeeRate fee_rate;
- DeserializeFromFuzzingInput(buffer, fee_rate);
- AssertEqualAfterSerializeDeserialize(fee_rate);
+ CFeeRate fee_rate;
+ DeserializeFromFuzzingInput(buffer, fee_rate);
+ AssertEqualAfterSerializeDeserialize(fee_rate);
})
FUZZ_TARGET_DESERIALIZE(merkle_block_deserialize, {
- CMerkleBlock merkle_block;
- DeserializeFromFuzzingInput(buffer, merkle_block);
+ CMerkleBlock merkle_block;
+ DeserializeFromFuzzingInput(buffer, merkle_block);
})
FUZZ_TARGET_DESERIALIZE(out_point_deserialize, {
- COutPoint out_point;
- DeserializeFromFuzzingInput(buffer, out_point);
- AssertEqualAfterSerializeDeserialize(out_point);
+ COutPoint out_point;
+ DeserializeFromFuzzingInput(buffer, out_point);
+ AssertEqualAfterSerializeDeserialize(out_point);
})
FUZZ_TARGET_DESERIALIZE(partial_merkle_tree_deserialize, {
- CPartialMerkleTree partial_merkle_tree;
- DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
+ CPartialMerkleTree partial_merkle_tree;
+ DeserializeFromFuzzingInput(buffer, partial_merkle_tree);
})
FUZZ_TARGET_DESERIALIZE(pub_key_deserialize, {
- CPubKey pub_key;
- DeserializeFromFuzzingInput(buffer, pub_key);
- AssertEqualAfterSerializeDeserialize(pub_key);
+ CPubKey pub_key;
+ DeserializeFromFuzzingInput(buffer, pub_key);
+ AssertEqualAfterSerializeDeserialize(pub_key);
})
FUZZ_TARGET_DESERIALIZE(script_deserialize, {
- CScript script;
- DeserializeFromFuzzingInput(buffer, script);
-})
-FUZZ_TARGET_DESERIALIZE(sub_net_deserialize, {
- CSubNet sub_net_1;
- DeserializeFromFuzzingInput(buffer, sub_net_1, INIT_PROTO_VERSION);
- AssertEqualAfterSerializeDeserialize(sub_net_1, INIT_PROTO_VERSION);
- CSubNet sub_net_2;
- DeserializeFromFuzzingInput(buffer, sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
- CSubNet sub_net_3;
- DeserializeFromFuzzingInput(buffer, sub_net_3);
- AssertEqualAfterSerializeDeserialize(sub_net_3, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ CScript script;
+ DeserializeFromFuzzingInput(buffer, script);
})
FUZZ_TARGET_DESERIALIZE(tx_in_deserialize, {
- CTxIn tx_in;
- DeserializeFromFuzzingInput(buffer, tx_in);
- AssertEqualAfterSerializeDeserialize(tx_in);
+ CTxIn tx_in;
+ DeserializeFromFuzzingInput(buffer, tx_in);
+ AssertEqualAfterSerializeDeserialize(tx_in);
})
FUZZ_TARGET_DESERIALIZE(flat_file_pos_deserialize, {
- FlatFilePos flat_file_pos;
- DeserializeFromFuzzingInput(buffer, flat_file_pos);
- AssertEqualAfterSerializeDeserialize(flat_file_pos);
+ FlatFilePos flat_file_pos;
+ DeserializeFromFuzzingInput(buffer, flat_file_pos);
+ AssertEqualAfterSerializeDeserialize(flat_file_pos);
})
FUZZ_TARGET_DESERIALIZE(key_origin_info_deserialize, {
- KeyOriginInfo key_origin_info;
- DeserializeFromFuzzingInput(buffer, key_origin_info);
- AssertEqualAfterSerializeDeserialize(key_origin_info);
+ KeyOriginInfo key_origin_info;
+ DeserializeFromFuzzingInput(buffer, key_origin_info);
+ AssertEqualAfterSerializeDeserialize(key_origin_info);
})
FUZZ_TARGET_DESERIALIZE(partially_signed_transaction_deserialize, {
- PartiallySignedTransaction partially_signed_transaction;
- DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
+ PartiallySignedTransaction partially_signed_transaction;
+ DeserializeFromFuzzingInput(buffer, partially_signed_transaction);
})
FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, {
- PrefilledTransaction prefilled_transaction;
- DeserializeFromFuzzingInput(buffer, prefilled_transaction);
+ PrefilledTransaction prefilled_transaction;
+ DeserializeFromFuzzingInput(buffer, prefilled_transaction);
})
FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, {
- PSBTInput psbt_input;
- DeserializeFromFuzzingInput(buffer, psbt_input);
+ PSBTInput psbt_input;
+ DeserializeFromFuzzingInput(buffer, psbt_input);
})
FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, {
- PSBTOutput psbt_output;
- DeserializeFromFuzzingInput(buffer, psbt_output);
+ PSBTOutput psbt_output;
+ DeserializeFromFuzzingInput(buffer, psbt_output);
})
FUZZ_TARGET_DESERIALIZE(block_deserialize, {
- CBlock block;
- DeserializeFromFuzzingInput(buffer, block);
+ CBlock block;
+ DeserializeFromFuzzingInput(buffer, block);
})
FUZZ_TARGET_DESERIALIZE(blocklocator_deserialize, {
- CBlockLocator bl;
- DeserializeFromFuzzingInput(buffer, bl);
+ CBlockLocator bl;
+ DeserializeFromFuzzingInput(buffer, bl);
})
FUZZ_TARGET_DESERIALIZE(blockmerkleroot, {
- CBlock block;
- DeserializeFromFuzzingInput(buffer, block);
- bool mutated;
- BlockMerkleRoot(block, &mutated);
+ CBlock block;
+ DeserializeFromFuzzingInput(buffer, block);
+ bool mutated;
+ BlockMerkleRoot(block, &mutated);
})
FUZZ_TARGET_DESERIALIZE(addrman_deserialize, {
- CAddrMan am;
- DeserializeFromFuzzingInput(buffer, am);
+ CAddrMan am(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 0);
+ DeserializeFromFuzzingInput(buffer, am);
})
FUZZ_TARGET_DESERIALIZE(blockheader_deserialize, {
- CBlockHeader bh;
- DeserializeFromFuzzingInput(buffer, bh);
-})
-FUZZ_TARGET_DESERIALIZE(banentry_deserialize, {
- CBanEntry be;
- DeserializeFromFuzzingInput(buffer, be);
+ CBlockHeader bh;
+ DeserializeFromFuzzingInput(buffer, bh);
})
FUZZ_TARGET_DESERIALIZE(txundo_deserialize, {
- CTxUndo tu;
- DeserializeFromFuzzingInput(buffer, tu);
+ CTxUndo tu;
+ DeserializeFromFuzzingInput(buffer, tu);
})
FUZZ_TARGET_DESERIALIZE(blockundo_deserialize, {
- CBlockUndo bu;
- DeserializeFromFuzzingInput(buffer, bu);
+ CBlockUndo bu;
+ DeserializeFromFuzzingInput(buffer, bu);
})
FUZZ_TARGET_DESERIALIZE(coins_deserialize, {
- Coin coin;
- DeserializeFromFuzzingInput(buffer, coin);
+ Coin coin;
+ DeserializeFromFuzzingInput(buffer, coin);
})
FUZZ_TARGET_DESERIALIZE(netaddr_deserialize, {
- CNetAddr na;
- DeserializeFromFuzzingInput(buffer, na);
- if (na.IsAddrV1Compatible()) {
- AssertEqualAfterSerializeDeserialize(na);
- }
- AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ CNetAddr na;
+ DeserializeFromFuzzingInput(buffer, na);
+ if (na.IsAddrV1Compatible()) {
+ AssertEqualAfterSerializeDeserialize(na);
+ }
+ AssertEqualAfterSerializeDeserialize(na, INIT_PROTO_VERSION | ADDRV2_FORMAT);
})
FUZZ_TARGET_DESERIALIZE(service_deserialize, {
- CService s;
- DeserializeFromFuzzingInput(buffer, s);
- if (s.IsAddrV1Compatible()) {
- AssertEqualAfterSerializeDeserialize(s);
- }
- AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT);
- CService s1;
- DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION);
- AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION);
- assert(s1.IsAddrV1Compatible());
- CService s2;
- DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ CService s;
+ DeserializeFromFuzzingInput(buffer, s);
+ if (s.IsAddrV1Compatible()) {
+ AssertEqualAfterSerializeDeserialize(s);
+ }
+ AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ CService s1;
+ DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION);
+ AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION);
+ assert(s1.IsAddrV1Compatible());
+ CService s2;
+ DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
})
FUZZ_TARGET_DESERIALIZE(messageheader_deserialize, {
- CMessageHeader mh;
- DeserializeFromFuzzingInput(buffer, mh);
- (void)mh.IsCommandValid();
+ CMessageHeader mh;
+ DeserializeFromFuzzingInput(buffer, mh);
+ (void)mh.IsCommandValid();
})
FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_notime, {
- CAddress a;
- DeserializeFromFuzzingInput(buffer, a, INIT_PROTO_VERSION);
- // A CAddress without nTime (as is expected under INIT_PROTO_VERSION) will roundtrip
- // in all 5 formats (with/without nTime, v1/v2, network/disk)
- AssertEqualAfterSerializeDeserialize(a, INIT_PROTO_VERSION);
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
- AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
+ CAddress a;
+ DeserializeFromFuzzingInput(buffer, a, INIT_PROTO_VERSION);
+ // A CAddress without nTime (as is expected under INIT_PROTO_VERSION) will roundtrip
+ // in all 5 formats (with/without nTime, v1/v2, network/disk)
+ AssertEqualAfterSerializeDeserialize(a, INIT_PROTO_VERSION);
+ AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
+ AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
+ AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
})
FUZZ_TARGET_DESERIALIZE(address_deserialize_v1_withtime, {
- CAddress a;
- DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION);
- // A CAddress in V1 mode will roundtrip in all 4 formats that have nTime.
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
- AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
+ CAddress a;
+ DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION);
+ // A CAddress in V1 mode will roundtrip in all 4 formats that have nTime.
+ AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
+ AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
+ AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
})
FUZZ_TARGET_DESERIALIZE(address_deserialize_v2, {
- CAddress a;
- DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- // A CAddress in V2 mode will roundtrip in both V2 formats, and also in the V1 formats
- // with time if it's V1 compatible.
- if (a.IsAddrV1Compatible()) {
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
- AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
- }
- AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
- AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
+ CAddress a;
+ DeserializeFromFuzzingInput(buffer, a, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ // A CAddress in V2 mode will roundtrip in both V2 formats, and also in the V1 formats
+ // with time if it's V1 compatible.
+ if (a.IsAddrV1Compatible()) {
+ AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION);
+ AssertEqualAfterSerializeDeserialize(a, 0, SER_DISK);
+ }
+ AssertEqualAfterSerializeDeserialize(a, PROTOCOL_VERSION | ADDRV2_FORMAT);
+ AssertEqualAfterSerializeDeserialize(a, ADDRV2_FORMAT, SER_DISK);
})
FUZZ_TARGET_DESERIALIZE(inv_deserialize, {
- CInv i;
- DeserializeFromFuzzingInput(buffer, i);
+ CInv i;
+ DeserializeFromFuzzingInput(buffer, i);
})
FUZZ_TARGET_DESERIALIZE(bloomfilter_deserialize, {
- CBloomFilter bf;
- DeserializeFromFuzzingInput(buffer, bf);
+ CBloomFilter bf;
+ DeserializeFromFuzzingInput(buffer, bf);
})
FUZZ_TARGET_DESERIALIZE(diskblockindex_deserialize, {
- CDiskBlockIndex dbi;
- DeserializeFromFuzzingInput(buffer, dbi);
+ CDiskBlockIndex dbi;
+ DeserializeFromFuzzingInput(buffer, dbi);
})
FUZZ_TARGET_DESERIALIZE(txoutcompressor_deserialize, {
- CTxOut to;
- auto toc = Using<TxOutCompression>(to);
- DeserializeFromFuzzingInput(buffer, toc);
+ CTxOut to;
+ auto toc = Using<TxOutCompression>(to);
+ DeserializeFromFuzzingInput(buffer, toc);
})
FUZZ_TARGET_DESERIALIZE(blocktransactions_deserialize, {
- BlockTransactions bt;
- DeserializeFromFuzzingInput(buffer, bt);
+ BlockTransactions bt;
+ DeserializeFromFuzzingInput(buffer, bt);
})
FUZZ_TARGET_DESERIALIZE(blocktransactionsrequest_deserialize, {
- BlockTransactionsRequest btr;
- DeserializeFromFuzzingInput(buffer, btr);
+ BlockTransactionsRequest btr;
+ DeserializeFromFuzzingInput(buffer, btr);
})
FUZZ_TARGET_DESERIALIZE(snapshotmetadata_deserialize, {
- SnapshotMetadata snapshot_metadata;
- DeserializeFromFuzzingInput(buffer, snapshot_metadata);
+ SnapshotMetadata snapshot_metadata;
+ DeserializeFromFuzzingInput(buffer, snapshot_metadata);
})
FUZZ_TARGET_DESERIALIZE(uint160_deserialize, {
- uint160 u160;
- DeserializeFromFuzzingInput(buffer, u160);
- AssertEqualAfterSerializeDeserialize(u160);
+ uint160 u160;
+ DeserializeFromFuzzingInput(buffer, u160);
+ AssertEqualAfterSerializeDeserialize(u160);
})
FUZZ_TARGET_DESERIALIZE(uint256_deserialize, {
- uint256 u256;
- DeserializeFromFuzzingInput(buffer, u256);
- AssertEqualAfterSerializeDeserialize(u256);
-})
- // Classes intentionally not covered in this file since their deserialization code is
- // fuzzed elsewhere:
- // * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
- // * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp
+ uint256 u256;
+ DeserializeFromFuzzingInput(buffer, u256);
+ AssertEqualAfterSerializeDeserialize(u256);
+})
+// Classes intentionally not covered in this file since their deserialization code is
+// fuzzed elsewhere:
+// * Deserialization of CTxOut is fuzzed in test/fuzz/tx_out.cpp
+// * Deserialization of CMutableTransaction is fuzzed in src/test/fuzz/transaction.cpp
diff --git a/src/test/fuzz/fuzz.h b/src/test/fuzz/fuzz.h
index 2bad77bdc1..c91c33da67 100644
--- a/src/test/fuzz/fuzz.h
+++ b/src/test/fuzz/fuzz.h
@@ -11,6 +11,13 @@
#include <functional>
#include <string_view>
+/**
+ * Can be used to limit a theoretically unbounded loop. This caps the runtime
+ * to avoid timeouts or OOMs.
+ */
+#define LIMITED_WHILE(condition, limit) \
+ for (unsigned _count{limit}; (condition) && _count; --_count)
+
using FuzzBufferType = Span<const uint8_t>;
using TypeTestOneInput = std::function<void(FuzzBufferType)>;
diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp
index e9fa343896..5d26529837 100644
--- a/src/test/fuzz/integer.cpp
+++ b/src/test/fuzz/integer.cpp
@@ -16,8 +16,6 @@
#include <pow.h>
#include <protocol.h>
#include <pubkey.h>
-#include <rpc/util.h>
-#include <script/signingprovider.h>
#include <script/standard.h>
#include <serialize.h>
#include <streams.h>
@@ -85,9 +83,8 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
(void)FormatISO8601Date(i64);
(void)FormatISO8601DateTime(i64);
{
- int64_t parsed_money;
- if (ParseMoney(FormatMoney(i64), parsed_money)) {
- assert(parsed_money == i64);
+ if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {
+ assert(parsed.value() == i64);
}
}
(void)GetSizeOfCompactSize(u64);
@@ -128,9 +125,8 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
(void)ToLower(ch);
(void)ToUpper(ch);
{
- int64_t parsed_money;
- if (ParseMoney(ValueFromAmount(i64).getValStr(), parsed_money)) {
- assert(parsed_money == i64);
+ if (std::optional<CAmount> parsed = ParseMoney(ValueFromAmount(i64).getValStr())) {
+ assert(parsed.value() == i64);
}
}
if (i32 >= 0 && i32 <= 16) {
@@ -158,20 +154,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer)
const CKeyID key_id{u160};
const CScriptID script_id{u160};
- // CTxDestination = CNoDestination ∪ PKHash ∪ ScriptHash ∪ WitnessV0ScriptHash ∪ WitnessV0KeyHash ∪ WitnessUnknown
- const PKHash pk_hash{u160};
- const ScriptHash script_hash{u160};
- const WitnessV0KeyHash witness_v0_key_hash{u160};
- const WitnessV0ScriptHash witness_v0_script_hash{u256};
- const std::vector<CTxDestination> destinations{pk_hash, script_hash, witness_v0_key_hash, witness_v0_script_hash};
- const SigningProvider store;
- for (const CTxDestination& destination : destinations) {
- (void)DescribeAddress(destination);
- (void)EncodeDestination(destination);
- (void)GetKeyForDestination(store, destination);
- (void)GetScriptForDestination(destination);
- (void)IsValidDestination(destination);
- }
{
CDataStream stream(SER_NETWORK, INIT_PROTO_VERSION);
diff --git a/src/test/fuzz/key_io.cpp b/src/test/fuzz/key_io.cpp
index 665ca01fa1..f58bf8b316 100644
--- a/src/test/fuzz/key_io.cpp
+++ b/src/test/fuzz/key_io.cpp
@@ -4,9 +4,6 @@
#include <chainparams.h>
#include <key_io.h>
-#include <rpc/util.h>
-#include <script/signingprovider.h>
-#include <script/standard.h>
#include <test/fuzz/fuzz.h>
#include <cassert>
@@ -39,12 +36,4 @@ FUZZ_TARGET_INIT(key_io, initialize_key_io)
if (ext_pub_key.pubkey.size() == CPubKey::COMPRESSED_SIZE) {
assert(ext_pub_key == DecodeExtPubKey(EncodeExtPubKey(ext_pub_key)));
}
-
- const CTxDestination tx_destination = DecodeDestination(random_string);
- (void)DescribeAddress(tx_destination);
- (void)GetKeyForDestination(/* store */ {}, tx_destination);
- (void)GetScriptForDestination(tx_destination);
- (void)IsValidDestination(tx_destination);
-
- (void)IsValidDestinationString(random_string);
}
diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp
index 908e9a1c83..82f3a306c5 100644
--- a/src/test/fuzz/kitchen_sink.cpp
+++ b/src/test/fuzz/kitchen_sink.cpp
@@ -13,6 +13,7 @@
#include <array>
#include <cstdint>
+#include <optional>
#include <vector>
namespace {
@@ -46,11 +47,10 @@ FUZZ_TARGET(kitchen_sink)
const OutputType output_type = fuzzed_data_provider.PickValueInArray(OUTPUT_TYPES);
const std::string& output_type_string = FormatOutputType(output_type);
- OutputType output_type_parsed;
- const bool parsed = ParseOutputType(output_type_string, output_type_parsed);
+ const std::optional<OutputType> parsed = ParseOutputType(output_type_string);
assert(parsed);
- assert(output_type == output_type_parsed);
- (void)ParseOutputType(fuzzed_data_provider.ConsumeRandomLengthString(64), output_type_parsed);
+ assert(output_type == parsed.value());
+ (void)ParseOutputType(fuzzed_data_provider.ConsumeRandomLengthString(64));
const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
const std::vector<bool> bits = BytesToBits(bytes);
diff --git a/src/test/fuzz/multiplication_overflow.cpp b/src/test/fuzz/multiplication_overflow.cpp
index 0f054529a6..c7251650c2 100644
--- a/src/test/fuzz/multiplication_overflow.cpp
+++ b/src/test/fuzz/multiplication_overflow.cpp
@@ -2,6 +2,10 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#if defined(HAVE_CONFIG_H)
+#include <config/bitcoin-config.h>
+#endif
+
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
@@ -10,14 +14,6 @@
#include <string>
#include <vector>
-#if defined(__has_builtin)
-#if __has_builtin(__builtin_mul_overflow)
-#define HAVE_BUILTIN_MUL_OVERFLOW
-#endif
-#elif defined(__GNUC__)
-#define HAVE_BUILTIN_MUL_OVERFLOW
-#endif
-
namespace {
template <typename T>
void TestMultiplicationOverflow(FuzzedDataProvider& fuzzed_data_provider)
diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp
index 20d8581312..ff0259c182 100644
--- a/src/test/fuzz/net.cpp
+++ b/src/test/fuzz/net.cpp
@@ -38,15 +38,12 @@ FUZZ_TARGET_INIT(net, initialize_net)
node.CloseSocketDisconnect();
},
[&] {
- node.MaybeSetAddrName(fuzzed_data_provider.ConsumeRandomLengthString(32));
- },
- [&] {
const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
if (!SanityCheckASMap(asmap)) {
return;
}
CNodeStats stats;
- node.copyStats(stats, asmap);
+ node.CopyStats(stats, asmap);
},
[&] {
const CNode* add_ref_node = node.AddRef();
@@ -82,7 +79,6 @@ FUZZ_TARGET_INIT(net, initialize_net)
}
(void)node.GetAddrLocal();
- (void)node.GetAddrName();
(void)node.GetId();
(void)node.GetLocalNonce();
(void)node.GetLocalServices();
diff --git a/src/test/fuzz/netaddress.cpp b/src/test/fuzz/netaddress.cpp
index f9d8129ca9..6cb81901cb 100644
--- a/src/test/fuzz/netaddress.cpp
+++ b/src/test/fuzz/netaddress.cpp
@@ -54,7 +54,7 @@ FUZZ_TARGET(netaddress)
(void)net_addr.IsRFC3927();
(void)net_addr.IsRFC3964();
if (net_addr.IsRFC4193()) {
- assert(net_addr.GetNetwork() == Network::NET_ONION || net_addr.GetNetwork() == Network::NET_INTERNAL || net_addr.GetNetwork() == Network::NET_UNROUTABLE);
+ assert(net_addr.GetNetwork() == Network::NET_INTERNAL || net_addr.GetNetwork() == Network::NET_UNROUTABLE);
}
(void)net_addr.IsRFC4380();
(void)net_addr.IsRFC4843();
diff --git a/src/test/fuzz/parse_numbers.cpp b/src/test/fuzz/parse_numbers.cpp
index 2c546e9b4a..69e58c3f63 100644
--- a/src/test/fuzz/parse_numbers.cpp
+++ b/src/test/fuzz/parse_numbers.cpp
@@ -12,8 +12,7 @@ FUZZ_TARGET(parse_numbers)
{
const std::string random_string(buffer.begin(), buffer.end());
- CAmount amount;
- (void)ParseMoney(random_string, amount);
+ (void)ParseMoney(random_string);
double d;
(void)ParseDouble(random_string, &d);
diff --git a/src/test/fuzz/prevector.cpp b/src/test/fuzz/prevector.cpp
index 51956bbe9e..d4b3ed501f 100644
--- a/src/test/fuzz/prevector.cpp
+++ b/src/test/fuzz/prevector.cpp
@@ -209,7 +209,8 @@ FUZZ_TARGET(prevector)
FuzzedDataProvider prov(buffer.data(), buffer.size());
prevector_tester<8, int> test;
- while (prov.remaining_bytes()) {
+ LIMITED_WHILE(prov.remaining_bytes(), 3000)
+ {
switch (prov.ConsumeIntegralInRange<int>(0, 13 + 3 * (test.size() > 0))) {
case 0:
test.insert(prov.ConsumeIntegralInRange<size_t>(0, test.size()), prov.ConsumeIntegral<int>());
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp
index c4e4d4c785..7b99193ad0 100644
--- a/src/test/fuzz/process_message.cpp
+++ b/src/test/fuzz/process_message.cpp
@@ -58,19 +58,7 @@ void initialize_process_message()
static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
g_setup = testing_setup.get();
-
- // Temporary debug for https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=35027
- {
- LOCK(::cs_main);
- assert(CheckDiskSpace(gArgs.GetDataDirNet()));
- assert(CheckDiskSpace(gArgs.GetDataDirNet(), 48 * 2 * 2 * g_setup->m_node.chainman->ActiveChainstate().CoinsTip().GetCacheSize()));
- }
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
- {
- LOCK(::cs_main);
- assert(CheckDiskSpace(gArgs.GetDataDirNet()));
- assert(CheckDiskSpace(gArgs.GetDataDirNet(), 48 * 2 * 2 * g_setup->m_node.chainman->ActiveChainstate().CoinsTip().GetCacheSize()));
- }
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
}
SyncWithValidationInterfaceQueue();
diff --git a/src/test/fuzz/rolling_bloom_filter.cpp b/src/test/fuzz/rolling_bloom_filter.cpp
index 07059cce76..b9ed497e68 100644
--- a/src/test/fuzz/rolling_bloom_filter.cpp
+++ b/src/test/fuzz/rolling_bloom_filter.cpp
@@ -21,7 +21,8 @@ FUZZ_TARGET(rolling_bloom_filter)
CRollingBloomFilter rolling_bloom_filter{
fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, 1000),
0.999 / fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(1, std::numeric_limits<unsigned int>::max())};
- while (fuzzed_data_provider.remaining_bytes() > 0) {
+ LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 3000)
+ {
CallOneOf(
fuzzed_data_provider,
[&] {
@@ -32,13 +33,10 @@ FUZZ_TARGET(rolling_bloom_filter)
assert(present);
},
[&] {
- const std::optional<uint256> u256 = ConsumeDeserializable<uint256>(fuzzed_data_provider);
- if (!u256) {
- return;
- }
- (void)rolling_bloom_filter.contains(*u256);
- rolling_bloom_filter.insert(*u256);
- const bool present = rolling_bloom_filter.contains(*u256);
+ const uint256 u256{ConsumeUInt256(fuzzed_data_provider)};
+ (void)rolling_bloom_filter.contains(u256);
+ rolling_bloom_filter.insert(u256);
+ const bool present = rolling_bloom_filter.contains(u256);
assert(present);
},
[&] {
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
index b87bcf2ef5..950ee45d1d 100644
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -6,8 +6,10 @@
#include <compressor.h>
#include <core_io.h>
#include <core_memusage.h>
+#include <key_io.h>
#include <policy/policy.h>
#include <pubkey.h>
+#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/interpreter.h>
#include <script/script.h>
@@ -184,26 +186,26 @@ FUZZ_TARGET_INIT(script, initialize_script)
}
{
- WitnessUnknown witness_unknown_1{};
- witness_unknown_1.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
- const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
- witness_unknown_1.length = witness_unknown_program_1.size();
- std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown_1.program);
-
- WitnessUnknown witness_unknown_2{};
- witness_unknown_2.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
- const std::vector<uint8_t> witness_unknown_program_2 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
- witness_unknown_2.length = witness_unknown_program_2.size();
- std::copy(witness_unknown_program_2.begin(), witness_unknown_program_2.end(), witness_unknown_2.program);
-
- (void)(witness_unknown_1 == witness_unknown_2);
- (void)(witness_unknown_1 < witness_unknown_2);
- }
+ const CTxDestination tx_destination_1{
+ fuzzed_data_provider.ConsumeBool() ?
+ DecodeDestination(fuzzed_data_provider.ConsumeRandomLengthString()) :
+ ConsumeTxDestination(fuzzed_data_provider)};
+ const CTxDestination tx_destination_2{ConsumeTxDestination(fuzzed_data_provider)};
+ const std::string encoded_dest{EncodeDestination(tx_destination_1)};
+ const UniValue json_dest{DescribeAddress(tx_destination_1)};
+ Assert(tx_destination_1 == DecodeDestination(encoded_dest));
+ (void)GetKeyForDestination(/* store */ {}, tx_destination_1);
+ const CScript dest{GetScriptForDestination(tx_destination_1)};
+ const bool valid{IsValidDestination(tx_destination_1)};
+ Assert(dest.empty() != valid);
+
+ Assert(valid == IsValidDestinationString(encoded_dest));
- {
- const CTxDestination tx_destination_1 = ConsumeTxDestination(fuzzed_data_provider);
- const CTxDestination tx_destination_2 = ConsumeTxDestination(fuzzed_data_provider);
- (void)(tx_destination_1 == tx_destination_2);
(void)(tx_destination_1 < tx_destination_2);
+ if (tx_destination_1 == tx_destination_2) {
+ Assert(encoded_dest == EncodeDestination(tx_destination_2));
+ Assert(json_dest.write() == DescribeAddress(tx_destination_2).write());
+ Assert(dest == GetScriptForDestination(tx_destination_2));
+ }
}
}
diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp
index fe850a6959..684324c36e 100644
--- a/src/test/fuzz/script_sign.cpp
+++ b/src/test/fuzz/script_sign.cpp
@@ -13,6 +13,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
+#include <util/translation.h>
#include <cassert>
#include <cstdint>
@@ -135,7 +136,7 @@ FUZZ_TARGET_INIT(script_sign, initialize_script_sign)
}
coins[*outpoint] = *coin;
}
- std::map<int, std::string> input_errors;
+ std::map<int, bilingual_str> input_errors;
(void)SignTransaction(sign_transaction_tx_to, &provider, coins, fuzzed_data_provider.ConsumeIntegral<int>(), input_errors);
}
}
diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp
index 286375f7ae..0c1b45b86c 100644
--- a/src/test/fuzz/string.cpp
+++ b/src/test/fuzz/string.cpp
@@ -66,8 +66,7 @@ FUZZ_TARGET(string)
(void)ParseNonRFCJSONValue(random_string_1);
} catch (const std::runtime_error&) {
}
- OutputType output_type;
- (void)ParseOutputType(random_string_1, output_type);
+ (void)ParseOutputType(random_string_1);
(void)RemovePrefix(random_string_1, random_string_2);
(void)ResolveErrMsg(random_string_1, random_string_2);
try {
diff --git a/src/test/fuzz/system.cpp b/src/test/fuzz/system.cpp
index b25dcfcd3b..0f53939eac 100644
--- a/src/test/fuzz/system.cpp
+++ b/src/test/fuzz/system.cpp
@@ -31,7 +31,8 @@ FUZZ_TARGET(system)
SetupHelpOptions(args_manager);
}
- while (fuzzed_data_provider.ConsumeBool()) {
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 3000)
+ {
CallOneOf(
fuzzed_data_provider,
[&] {
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index bab34ea340..6201cc813c 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -142,7 +142,8 @@ FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool)
return c.out.nValue;
};
- while (fuzzed_data_provider.ConsumeBool()) {
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
+ {
{
// Total supply is the mempool fee + all outpoints
CAmount supply_now{WITH_LOCK(tx_pool.cs, return tx_pool.GetTotalFee())};
@@ -305,7 +306,8 @@ FUZZ_TARGET_INIT(tx_pool, initialize_tx_pool)
CTxMemPool tx_pool_{/* estimator */ nullptr, /* check_ratio */ 1};
MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_);
- while (fuzzed_data_provider.ConsumeBool()) {
+ LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
+ {
const auto mut_tx = ConsumeTransaction(fuzzed_data_provider, txids);
if (fuzzed_data_provider.ConsumeBool()) {
diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp
index bcf0b0ce72..0d87f687d3 100644
--- a/src/test/fuzz/util.cpp
+++ b/src/test/fuzz/util.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <pubkey.h>
#include <test/fuzz/util.h>
#include <test/util/script.h>
#include <util/rbf.h>
@@ -304,3 +305,196 @@ uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept
}) :
fuzzed_data_provider.ConsumeIntegral<uint32_t>();
}
+
+CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ CTxDestination tx_destination;
+ const size_t call_size{CallOneOf(
+ fuzzed_data_provider,
+ [&] {
+ tx_destination = CNoDestination{};
+ },
+ [&] {
+ tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
+ },
+ [&] {
+ tx_destination = WitnessV1Taproot{XOnlyPubKey{ConsumeUInt256(fuzzed_data_provider)}};
+ },
+ [&] {
+ WitnessUnknown witness_unknown{};
+ witness_unknown.version = fuzzed_data_provider.ConsumeIntegralInRange(2, 16);
+ std::vector<uint8_t> witness_unknown_program_1{fuzzed_data_provider.ConsumeBytes<uint8_t>(40)};
+ if (witness_unknown_program_1.size() < 2) {
+ witness_unknown_program_1 = {0, 0};
+ }
+ witness_unknown.length = witness_unknown_program_1.size();
+ std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
+ tx_destination = witness_unknown;
+ })};
+ Assert(call_size == std::variant_size_v<CTxDestination>);
+ return tx_destination;
+}
+
+CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
+{
+ // Avoid:
+ // policy/feerate.cpp:28:34: runtime error: signed integer overflow: 34873208148477500 * 1000 cannot be represented in type 'long'
+ //
+ // Reproduce using CFeeRate(348732081484775, 10).GetFeePerK()
+ const CAmount fee = std::min<CAmount>(ConsumeMoney(fuzzed_data_provider), std::numeric_limits<CAmount>::max() / static_cast<CAmount>(100000));
+ assert(MoneyRange(fee));
+ const int64_t time = fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ const unsigned int entry_height = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
+ const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
+ return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
+}
+
+bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept
+{
+ for (const CTxIn& tx_in : tx.vin) {
+ const Coin& coin = inputs.AccessCoin(tx_in.prevout);
+ if (coin.IsSpent()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ const Network network = fuzzed_data_provider.PickValueInArray({Network::NET_IPV4, Network::NET_IPV6, Network::NET_INTERNAL, Network::NET_ONION});
+ CNetAddr net_addr;
+ if (network == Network::NET_IPV4) {
+ in_addr v4_addr = {};
+ v4_addr.s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
+ net_addr = CNetAddr{v4_addr};
+ } else if (network == Network::NET_IPV6) {
+ if (fuzzed_data_provider.remaining_bytes() >= 16) {
+ in6_addr v6_addr = {};
+ memcpy(v6_addr.s6_addr, fuzzed_data_provider.ConsumeBytes<uint8_t>(16).data(), 16);
+ net_addr = CNetAddr{v6_addr, fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
+ }
+ } else if (network == Network::NET_INTERNAL) {
+ net_addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32));
+ } else if (network == Network::NET_ONION) {
+ net_addr.SetSpecial(fuzzed_data_provider.ConsumeBytesAsString(32));
+ }
+ return net_addr;
+}
+
+FILE* FuzzedFileProvider::open()
+{
+ SetFuzzedErrNo(m_fuzzed_data_provider);
+ if (m_fuzzed_data_provider.ConsumeBool()) {
+ return nullptr;
+ }
+ std::string mode;
+ CallOneOf(
+ m_fuzzed_data_provider,
+ [&] {
+ mode = "r";
+ },
+ [&] {
+ mode = "r+";
+ },
+ [&] {
+ mode = "w";
+ },
+ [&] {
+ mode = "w+";
+ },
+ [&] {
+ mode = "a";
+ },
+ [&] {
+ mode = "a+";
+ });
+#if defined _GNU_SOURCE && !defined __ANDROID__
+ const cookie_io_functions_t io_hooks = {
+ FuzzedFileProvider::read,
+ FuzzedFileProvider::write,
+ FuzzedFileProvider::seek,
+ FuzzedFileProvider::close,
+ };
+ return fopencookie(this, mode.c_str(), io_hooks);
+#else
+ (void)mode;
+ return nullptr;
+#endif
+}
+
+ssize_t FuzzedFileProvider::read(void* cookie, char* buf, size_t size)
+{
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
+ if (buf == nullptr || size == 0 || fuzzed_file->m_fuzzed_data_provider.ConsumeBool()) {
+ return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
+ }
+ const std::vector<uint8_t> random_bytes = fuzzed_file->m_fuzzed_data_provider.ConsumeBytes<uint8_t>(size);
+ if (random_bytes.empty()) {
+ return 0;
+ }
+ std::memcpy(buf, random_bytes.data(), random_bytes.size());
+ if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)random_bytes.size())) {
+ return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
+ }
+ fuzzed_file->m_offset += random_bytes.size();
+ return random_bytes.size();
+}
+
+ssize_t FuzzedFileProvider::write(void* cookie, const char* buf, size_t size)
+{
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
+ const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size);
+ if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)n)) {
+ return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
+ }
+ fuzzed_file->m_offset += n;
+ return n;
+}
+
+int FuzzedFileProvider::seek(void* cookie, int64_t* offset, int whence)
+{
+ assert(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END);
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
+ int64_t new_offset = 0;
+ if (whence == SEEK_SET) {
+ new_offset = *offset;
+ } else if (whence == SEEK_CUR) {
+ if (AdditionOverflow(fuzzed_file->m_offset, *offset)) {
+ return -1;
+ }
+ new_offset = fuzzed_file->m_offset + *offset;
+ } else if (whence == SEEK_END) {
+ const int64_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 4096);
+ if (AdditionOverflow(n, *offset)) {
+ return -1;
+ }
+ new_offset = n + *offset;
+ }
+ if (new_offset < 0) {
+ return -1;
+ }
+ fuzzed_file->m_offset = new_offset;
+ *offset = new_offset;
+ return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
+}
+
+int FuzzedFileProvider::close(void* cookie)
+{
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
+ return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
+}
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 023dcdb3e5..bb017b3497 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -37,7 +37,7 @@
#include <vector>
template <typename... Callables>
-void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
+size_t CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
{
constexpr size_t call_size{sizeof...(callables)};
static_assert(call_size >= 1);
@@ -45,6 +45,7 @@ void CallOneOf(FuzzedDataProvider& fuzzed_data_provider, Callables... callables)
size_t i{0};
((i++ == call_index ? callables() : void()), ...);
+ return call_size;
}
template <typename Collection>
@@ -163,51 +164,9 @@ template <typename WeakEnumType, size_t size>
return UintToArith256(ConsumeUInt256(fuzzed_data_provider));
}
-[[nodiscard]] inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
-{
- // Avoid:
- // policy/feerate.cpp:28:34: runtime error: signed integer overflow: 34873208148477500 * 1000 cannot be represented in type 'long'
- //
- // Reproduce using CFeeRate(348732081484775, 10).GetFeePerK()
- const CAmount fee = std::min<CAmount>(ConsumeMoney(fuzzed_data_provider), std::numeric_limits<CAmount>::max() / static_cast<CAmount>(100000));
- assert(MoneyRange(fee));
- const int64_t time = fuzzed_data_provider.ConsumeIntegral<int64_t>();
- const unsigned int entry_height = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
- const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
- const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
- return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
-}
+[[nodiscard]] CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept;
-[[nodiscard]] inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
-{
- CTxDestination tx_destination;
- CallOneOf(
- fuzzed_data_provider,
- [&] {
- tx_destination = CNoDestination{};
- },
- [&] {
- tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
- },
- [&] {
- tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
- },
- [&] {
- tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
- },
- [&] {
- tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
- },
- [&] {
- WitnessUnknown witness_unknown{};
- witness_unknown.version = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
- const std::vector<uint8_t> witness_unknown_program_1 = fuzzed_data_provider.ConsumeBytes<uint8_t>(40);
- witness_unknown.length = witness_unknown_program_1.size();
- std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
- tx_destination = witness_unknown;
- });
- return tx_destination;
-}
+[[nodiscard]] CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept;
template <typename T>
[[nodiscard]] bool MultiplicationOverflow(const T i, const T j) noexcept
@@ -243,16 +202,7 @@ template <class T>
return std::numeric_limits<T>::max() - i < j;
}
-[[nodiscard]] inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept
-{
- for (const CTxIn& tx_in : tx.vin) {
- const Coin& coin = inputs.AccessCoin(tx_in.prevout);
- if (coin.IsSpent()) {
- return true;
- }
- }
- return false;
-}
+[[nodiscard]] bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept;
/**
* Sets errno to a value selected from the given std::array `errnos`.
@@ -287,27 +237,7 @@ inline void SetFuzzedErrNo(FuzzedDataProvider& fuzzed_data_provider) noexcept
return result;
}
-inline CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
-{
- const Network network = fuzzed_data_provider.PickValueInArray({Network::NET_IPV4, Network::NET_IPV6, Network::NET_INTERNAL, Network::NET_ONION});
- CNetAddr net_addr;
- if (network == Network::NET_IPV4) {
- in_addr v4_addr = {};
- v4_addr.s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
- net_addr = CNetAddr{v4_addr};
- } else if (network == Network::NET_IPV6) {
- if (fuzzed_data_provider.remaining_bytes() >= 16) {
- in6_addr v6_addr = {};
- memcpy(v6_addr.s6_addr, fuzzed_data_provider.ConsumeBytes<uint8_t>(16).data(), 16);
- net_addr = CNetAddr{v6_addr, fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
- }
- } else if (network == Network::NET_INTERNAL) {
- net_addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32));
- } else if (network == Network::NET_ONION) {
- net_addr.SetSpecial(fuzzed_data_provider.ConsumeBytesAsString(32));
- }
- return net_addr;
-}
+CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept;
inline CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
@@ -357,112 +287,15 @@ public:
{
}
- FILE* open()
- {
- SetFuzzedErrNo(m_fuzzed_data_provider);
- if (m_fuzzed_data_provider.ConsumeBool()) {
- return nullptr;
- }
- std::string mode;
- CallOneOf(
- m_fuzzed_data_provider,
- [&] {
- mode = "r";
- },
- [&] {
- mode = "r+";
- },
- [&] {
- mode = "w";
- },
- [&] {
- mode = "w+";
- },
- [&] {
- mode = "a";
- },
- [&] {
- mode = "a+";
- });
-#if defined _GNU_SOURCE && !defined __ANDROID__
- const cookie_io_functions_t io_hooks = {
- FuzzedFileProvider::read,
- FuzzedFileProvider::write,
- FuzzedFileProvider::seek,
- FuzzedFileProvider::close,
- };
- return fopencookie(this, mode.c_str(), io_hooks);
-#else
- (void)mode;
- return nullptr;
-#endif
- }
+ FILE* open();
- static ssize_t read(void* cookie, char* buf, size_t size)
- {
- FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
- SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
- if (buf == nullptr || size == 0 || fuzzed_file->m_fuzzed_data_provider.ConsumeBool()) {
- return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
- }
- const std::vector<uint8_t> random_bytes = fuzzed_file->m_fuzzed_data_provider.ConsumeBytes<uint8_t>(size);
- if (random_bytes.empty()) {
- return 0;
- }
- std::memcpy(buf, random_bytes.data(), random_bytes.size());
- if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)random_bytes.size())) {
- return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
- }
- fuzzed_file->m_offset += random_bytes.size();
- return random_bytes.size();
- }
+ static ssize_t read(void* cookie, char* buf, size_t size);
- static ssize_t write(void* cookie, const char* buf, size_t size)
- {
- FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
- SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
- const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size);
- if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)n)) {
- return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
- }
- fuzzed_file->m_offset += n;
- return n;
- }
+ static ssize_t write(void* cookie, const char* buf, size_t size);
- static int seek(void* cookie, int64_t* offset, int whence)
- {
- assert(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END);
- FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
- SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
- int64_t new_offset = 0;
- if (whence == SEEK_SET) {
- new_offset = *offset;
- } else if (whence == SEEK_CUR) {
- if (AdditionOverflow(fuzzed_file->m_offset, *offset)) {
- return -1;
- }
- new_offset = fuzzed_file->m_offset + *offset;
- } else if (whence == SEEK_END) {
- const int64_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 4096);
- if (AdditionOverflow(n, *offset)) {
- return -1;
- }
- new_offset = n + *offset;
- }
- if (new_offset < 0) {
- return -1;
- }
- fuzzed_file->m_offset = new_offset;
- *offset = new_offset;
- return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
- }
+ static int seek(void* cookie, int64_t* offset, int whence);
- static int close(void* cookie)
- {
- FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
- SetFuzzedErrNo(fuzzed_file->m_fuzzed_data_provider);
- return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
- }
+ static int close(void* cookie);
};
[[nodiscard]] inline FuzzedFileProvider ConsumeFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp
index e99c6e0fc8..e2e31c62d7 100644
--- a/src/test/logging_tests.cpp
+++ b/src/test/logging_tests.cpp
@@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(logging_timer)
SetMockTime(1);
auto micro_timer = BCLog::Timer<std::chrono::microseconds>("tests", "end_msg");
SetMockTime(2);
- BOOST_CHECK_EQUAL(micro_timer.LogMsg("test micros"), "tests: test micros (1000000.00μs)");
+ BOOST_CHECK_EQUAL(micro_timer.LogMsg("test micros"), "tests: test micros (1000000μs)");
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index e20c5e4e8f..7f44dcf20e 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2011-2020 The Bitcoin Core developers
+// Copyright (c) 2011-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.
@@ -16,6 +16,7 @@
#include <util/system.h>
#include <util/time.h>
#include <validation.h>
+#include <versionbits.h>
#include <test/util/setup_common.h>
@@ -51,36 +52,25 @@ BlockAssembler MinerTestingSetup::AssemblerForTest(const CChainParams& params)
constexpr static struct {
unsigned char extranonce;
unsigned int nonce;
-} blockinfo[] = {
- {4, 0xa4a3e223}, {2, 0x15c32f9e}, {1, 0x0375b547}, {1, 0x7004a8a5},
- {2, 0xce440296}, {2, 0x52cfe198}, {1, 0x77a72cd0}, {2, 0xbb5d6f84},
- {2, 0x83f30c2c}, {1, 0x48a73d5b}, {1, 0xef7dcd01}, {2, 0x6809c6c4},
- {2, 0x0883ab3c}, {1, 0x087bbbe2}, {2, 0x2104a814}, {2, 0xdffb6daa},
- {1, 0xee8a0a08}, {2, 0xba4237c1}, {1, 0xa70349dc}, {1, 0x344722bb},
- {3, 0xd6294733}, {2, 0xec9f5c94}, {2, 0xca2fbc28}, {1, 0x6ba4f406},
- {2, 0x015d4532}, {1, 0x6e119b7c}, {2, 0x43e8f314}, {2, 0x27962f38},
- {2, 0xb571b51b}, {2, 0xb36bee23}, {2, 0xd17924a8}, {2, 0x6bc212d9},
- {1, 0x630d4948}, {2, 0x9a4c4ebb}, {2, 0x554be537}, {1, 0xd63ddfc7},
- {2, 0xa10acc11}, {1, 0x759a8363}, {2, 0xfb73090d}, {1, 0xe82c6a34},
- {1, 0xe33e92d7}, {3, 0x658ef5cb}, {2, 0xba32ff22}, {5, 0x0227a10c},
- {1, 0xa9a70155}, {5, 0xd096d809}, {1, 0x37176174}, {1, 0x830b8d0f},
- {1, 0xc6e3910e}, {2, 0x823f3ca8}, {1, 0x99850849}, {1, 0x7521fb81},
- {1, 0xaacaabab}, {1, 0xd645a2eb}, {5, 0x7aea1781}, {5, 0x9d6e4b78},
- {1, 0x4ce90fd8}, {1, 0xabdc832d}, {6, 0x4a34f32a}, {2, 0xf2524c1c},
- {2, 0x1bbeb08a}, {1, 0xad47f480}, {1, 0x9f026aeb}, {1, 0x15a95049},
- {2, 0xd1cb95b2}, {2, 0xf84bbda5}, {1, 0x0fa62cd1}, {1, 0xe05f9169},
- {1, 0x78d194a9}, {5, 0x3e38147b}, {5, 0x737ba0d4}, {1, 0x63378e10},
- {1, 0x6d5f91cf}, {2, 0x88612eb8}, {2, 0xe9639484}, {1, 0xb7fabc9d},
- {2, 0x19b01592}, {1, 0x5a90dd31}, {2, 0x5bd7e028}, {2, 0x94d00323},
- {1, 0xa9b9c01a}, {1, 0x3a40de61}, {1, 0x56e7eec7}, {5, 0x859f7ef6},
- {1, 0xfd8e5630}, {1, 0x2b0c9f7f}, {1, 0xba700e26}, {1, 0x7170a408},
- {1, 0x70de86a8}, {1, 0x74d64cd5}, {1, 0x49e738a1}, {2, 0x6910b602},
- {0, 0x643c565f}, {1, 0x54264b3f}, {2, 0x97ea6396}, {2, 0x55174459},
- {2, 0x03e8779a}, {1, 0x98f34d8f}, {1, 0xc07b2b07}, {1, 0xdfe29668},
- {1, 0x3141c7c1}, {1, 0xb3b595f4}, {1, 0x735abf08}, {5, 0x623bfbce},
- {2, 0xd351e722}, {1, 0xf4ca48c9}, {1, 0x5b19c670}, {1, 0xa164bf0e},
- {2, 0xbbbeb305}, {2, 0xfe1c810a},
-};
+} BLOCKINFO[]{{8, 582909131}, {0, 971462344}, {2, 1169481553}, {6, 66147495}, {7, 427785981}, {8, 80538907},
+ {8, 207348013}, {2, 1951240923}, {4, 215054351}, {1, 491520534}, {8, 1282281282}, {4, 639565734},
+ {3, 248274685}, {8, 1160085976}, {6, 396349768}, {5, 393780549}, {5, 1096899528}, {4, 965381630},
+ {0, 728758712}, {5, 318638310}, {3, 164591898}, {2, 274234550}, {2, 254411237}, {7, 561761812},
+ {2, 268342573}, {0, 402816691}, {1, 221006382}, {6, 538872455}, {7, 393315655}, {4, 814555937},
+ {7, 504879194}, {6, 467769648}, {3, 925972193}, {2, 200581872}, {3, 168915404}, {8, 430446262},
+ {5, 773507406}, {3, 1195366164}, {0, 433361157}, {3, 297051771}, {0, 558856551}, {2, 501614039},
+ {3, 528488272}, {2, 473587734}, {8, 230125274}, {2, 494084400}, {4, 357314010}, {8, 60361686},
+ {7, 640624687}, {3, 480441695}, {8, 1424447925}, {4, 752745419}, {1, 288532283}, {6, 669170574},
+ {5, 1900907591}, {3, 555326037}, {3, 1121014051}, {0, 545835650}, {8, 189196651}, {5, 252371575},
+ {0, 199163095}, {6, 558895874}, {6, 1656839784}, {6, 815175452}, {6, 718677851}, {5, 544000334},
+ {0, 340113484}, {6, 850744437}, {4, 496721063}, {8, 524715182}, {6, 574361898}, {6, 1642305743},
+ {6, 355110149}, {5, 1647379658}, {8, 1103005356}, {7, 556460625}, {3, 1139533992}, {5, 304736030},
+ {2, 361539446}, {2, 143720360}, {6, 201939025}, {7, 423141476}, {4, 574633709}, {3, 1412254823},
+ {4, 873254135}, {0, 341817335}, {6, 53501687}, {3, 179755410}, {5, 172209688}, {8, 516810279},
+ {4, 1228391489}, {8, 325372589}, {6, 550367589}, {0, 876291812}, {7, 412454120}, {7, 717202854},
+ {2, 222677843}, {6, 251778867}, {7, 842004420}, {7, 194762829}, {4, 96668841}, {1, 925485796},
+ {0, 792342903}, {6, 678455063}, {6, 773251385}, {5, 186617471}, {6, 883189502}, {7, 396077336},
+ {8, 254702874}, {0, 455592851}};
static CBlockIndex CreateBlockIndex(int nHeight, CBlockIndex* active_chain_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
@@ -220,20 +210,18 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
// We can't make transactions until we have inputs
// Therefore, load 110 blocks :)
- static_assert(std::size(blockinfo) == 110, "Should have 110 blocks to import");
+ static_assert(std::size(BLOCKINFO) == 110, "Should have 110 blocks to import");
int baseheight = 0;
std::vector<CTransactionRef> txFirst;
- for (const auto& bi : blockinfo) {
+ for (const auto& bi : BLOCKINFO) {
CBlock *pblock = &pblocktemplate->block; // pointer for convenience
{
LOCK(cs_main);
- pblock->nVersion = 1;
+ pblock->nVersion = VERSIONBITS_TOP_BITS;
pblock->nTime = m_node.chainman->ActiveChain().Tip()->GetMedianTimePast()+1;
CMutableTransaction txCoinbase(*pblock->vtx[0]);
txCoinbase.nVersion = 1;
- txCoinbase.vin[0].scriptSig = CScript();
- txCoinbase.vin[0].scriptSig.push_back(bi.extranonce);
- txCoinbase.vin[0].scriptSig.push_back(m_node.chainman->ActiveChain().Height());
+ txCoinbase.vin[0].scriptSig = CScript{} << (m_node.chainman->ActiveChain().Height() + 1) << bi.extranonce;
txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
txCoinbase.vout[0].scriptPubKey = CScript();
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
diff --git a/src/test/net_peer_eviction_tests.cpp b/src/test/net_peer_eviction_tests.cpp
index 4bfd487b86..5eb280b498 100644
--- a/src/test/net_peer_eviction_tests.cpp
+++ b/src/test/net_peer_eviction_tests.cpp
@@ -17,28 +17,6 @@
BOOST_FIXTURE_TEST_SUITE(net_peer_eviction_tests, BasicTestingSetup)
-std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(const int n_candidates, FastRandomContext& random_context)
-{
- std::vector<NodeEvictionCandidate> candidates;
- for (int id = 0; id < n_candidates; ++id) {
- candidates.push_back({
- /* id */ id,
- /* nTimeConnected */ static_cast<int64_t>(random_context.randrange(100)),
- /* m_min_ping_time */ std::chrono::microseconds{random_context.randrange(100)},
- /* nLastBlockTime */ static_cast<int64_t>(random_context.randrange(100)),
- /* nLastTXTime */ static_cast<int64_t>(random_context.randrange(100)),
- /* fRelevantServices */ random_context.randbool(),
- /* fRelayTxes */ random_context.randbool(),
- /* fBloomFilter */ random_context.randbool(),
- /* nKeyedNetGroup */ random_context.randrange(100),
- /* prefer_evict */ random_context.randbool(),
- /* m_is_local */ random_context.randbool(),
- /* m_network */ ALL_NETWORKS[random_context.randrange(ALL_NETWORKS.size())],
- });
- }
- return candidates;
-}
-
// Create `num_peers` random nodes, apply setup function `candidate_setup_fn`,
// call ProtectEvictionCandidatesByRatio() to apply protection logic, and then
// return true if all of `protected_peer_ids` and none of `unprotected_peer_ids`
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index 46f88c1282..29938d4ede 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -2,8 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <addrdb.h>
-#include <addrman.h>
#include <chainparams.h>
#include <clientversion.h>
#include <cstdint>
@@ -29,64 +27,6 @@
using namespace std::literals;
-class CAddrManSerializationMock : public CAddrMan
-{
-public:
- virtual void Serialize(CDataStream& s) const = 0;
-
- //! Ensure that bucket placement is always the same for testing purposes.
- void MakeDeterministic()
- {
- nKey.SetNull();
- insecure_rand = FastRandomContext(true);
- }
-};
-
-class CAddrManUncorrupted : public CAddrManSerializationMock
-{
-public:
- void Serialize(CDataStream& s) const override
- {
- CAddrMan::Serialize(s);
- }
-};
-
-class CAddrManCorrupted : public CAddrManSerializationMock
-{
-public:
- void Serialize(CDataStream& s) const override
- {
- // Produces corrupt output that claims addrman has 20 addrs when it only has one addr.
- unsigned char nVersion = 1;
- s << nVersion;
- s << ((unsigned char)32);
- s << nKey;
- s << 10; // nNew
- s << 10; // nTried
-
- int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30);
- s << nUBuckets;
-
- CService serv;
- BOOST_CHECK(Lookup("252.1.1.1", serv, 7777, false));
- CAddress addr = CAddress(serv, NODE_NONE);
- CNetAddr resolved;
- BOOST_CHECK(LookupHost("252.2.2.2", resolved, false));
- CAddrInfo info = CAddrInfo(addr, resolved);
- s << info;
- }
-};
-
-static CDataStream AddrmanToStream(const CAddrManSerializationMock& _addrman)
-{
- CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION);
- ssPeersIn << Params().MessageStart();
- ssPeersIn << _addrman;
- std::string str = ssPeersIn.str();
- std::vector<unsigned char> vchData(str.begin(), str.end());
- return CDataStream(vchData, SER_DISK, CLIENT_VERSION);
-}
-
BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(cnode_listen_port)
@@ -101,82 +41,6 @@ BOOST_AUTO_TEST_CASE(cnode_listen_port)
BOOST_CHECK(port == altPort);
}
-BOOST_AUTO_TEST_CASE(caddrdb_read)
-{
- CAddrManUncorrupted addrmanUncorrupted;
- addrmanUncorrupted.MakeDeterministic();
-
- CService addr1, addr2, addr3;
- BOOST_CHECK(Lookup("250.7.1.1", addr1, 8333, false));
- BOOST_CHECK(Lookup("250.7.2.2", addr2, 9999, false));
- BOOST_CHECK(Lookup("250.7.3.3", addr3, 9999, false));
- BOOST_CHECK(Lookup("250.7.3.3"s, addr3, 9999, false));
- BOOST_CHECK(!Lookup("250.7.3.3\0example.com"s, addr3, 9999, false));
-
- // Add three addresses to new table.
- CService source;
- BOOST_CHECK(Lookup("252.5.1.1", source, 8333, false));
- BOOST_CHECK(addrmanUncorrupted.Add(CAddress(addr1, NODE_NONE), source));
- BOOST_CHECK(addrmanUncorrupted.Add(CAddress(addr2, NODE_NONE), source));
- BOOST_CHECK(addrmanUncorrupted.Add(CAddress(addr3, NODE_NONE), source));
-
- // Test that the de-serialization does not throw an exception.
- CDataStream ssPeers1 = AddrmanToStream(addrmanUncorrupted);
- bool exceptionThrown = false;
- CAddrMan addrman1;
-
- BOOST_CHECK(addrman1.size() == 0);
- try {
- unsigned char pchMsgTmp[4];
- ssPeers1 >> pchMsgTmp;
- ssPeers1 >> addrman1;
- } catch (const std::exception&) {
- exceptionThrown = true;
- }
-
- BOOST_CHECK(addrman1.size() == 3);
- BOOST_CHECK(exceptionThrown == false);
-
- // Test that CAddrDB::Read creates an addrman with the correct number of addrs.
- CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted);
-
- CAddrMan addrman2;
- BOOST_CHECK(addrman2.size() == 0);
- BOOST_CHECK(CAddrDB::Read(addrman2, ssPeers2));
- BOOST_CHECK(addrman2.size() == 3);
-}
-
-
-BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
-{
- CAddrManCorrupted addrmanCorrupted;
- addrmanCorrupted.MakeDeterministic();
-
- // Test that the de-serialization of corrupted addrman throws an exception.
- CDataStream ssPeers1 = AddrmanToStream(addrmanCorrupted);
- bool exceptionThrown = false;
- CAddrMan addrman1;
- BOOST_CHECK(addrman1.size() == 0);
- try {
- unsigned char pchMsgTmp[4];
- ssPeers1 >> pchMsgTmp;
- ssPeers1 >> addrman1;
- } catch (const std::exception&) {
- exceptionThrown = true;
- }
- // Even through de-serialization failed addrman is not left in a clean state.
- BOOST_CHECK(addrman1.size() == 1);
- BOOST_CHECK(exceptionThrown);
-
- // Test that CAddrDB::Read leaves addrman in a clean state if de-serialization fails.
- CDataStream ssPeers2 = AddrmanToStream(addrmanCorrupted);
-
- CAddrMan addrman2;
- BOOST_CHECK(addrman2.size() == 0);
- BOOST_CHECK(!CAddrDB::Read(addrman2, ssPeers2));
- BOOST_CHECK(addrman2.size() == 0);
-}
-
BOOST_AUTO_TEST_CASE(cnode_simple_test)
{
SOCKET hSocket = INVALID_SOCKET;
@@ -763,37 +627,42 @@ BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
{
- BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), true);
- BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), true);
- BOOST_CHECK_EQUAL(IsReachable(NET_ONION), true);
+ BOOST_CHECK(IsReachable(NET_IPV4));
+ BOOST_CHECK(IsReachable(NET_IPV6));
+ BOOST_CHECK(IsReachable(NET_ONION));
+ BOOST_CHECK(IsReachable(NET_I2P));
SetReachable(NET_IPV4, false);
SetReachable(NET_IPV6, false);
SetReachable(NET_ONION, false);
+ SetReachable(NET_I2P, false);
- BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), false);
- BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), false);
- BOOST_CHECK_EQUAL(IsReachable(NET_ONION), false);
+ BOOST_CHECK(!IsReachable(NET_IPV4));
+ BOOST_CHECK(!IsReachable(NET_IPV6));
+ BOOST_CHECK(!IsReachable(NET_ONION));
+ BOOST_CHECK(!IsReachable(NET_I2P));
SetReachable(NET_IPV4, true);
SetReachable(NET_IPV6, true);
SetReachable(NET_ONION, true);
+ SetReachable(NET_I2P, true);
- BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), true);
- BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), true);
- BOOST_CHECK_EQUAL(IsReachable(NET_ONION), true);
+ BOOST_CHECK(IsReachable(NET_IPV4));
+ BOOST_CHECK(IsReachable(NET_IPV6));
+ BOOST_CHECK(IsReachable(NET_ONION));
+ BOOST_CHECK(IsReachable(NET_I2P));
}
BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
{
- BOOST_CHECK_EQUAL(IsReachable(NET_UNROUTABLE), true);
- BOOST_CHECK_EQUAL(IsReachable(NET_INTERNAL), true);
+ BOOST_CHECK(IsReachable(NET_UNROUTABLE));
+ BOOST_CHECK(IsReachable(NET_INTERNAL));
SetReachable(NET_UNROUTABLE, false);
SetReachable(NET_INTERNAL, false);
- BOOST_CHECK_EQUAL(IsReachable(NET_UNROUTABLE), true); // Ignored for both networks
- BOOST_CHECK_EQUAL(IsReachable(NET_INTERNAL), true);
+ BOOST_CHECK(IsReachable(NET_UNROUTABLE)); // Ignored for both networks
+ BOOST_CHECK(IsReachable(NET_INTERNAL));
}
CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
@@ -812,10 +681,10 @@ BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
SetReachable(NET_IPV4, true);
- BOOST_CHECK_EQUAL(IsReachable(addr), true);
+ BOOST_CHECK(IsReachable(addr));
SetReachable(NET_IPV4, false);
- BOOST_CHECK_EQUAL(IsReachable(addr), false);
+ BOOST_CHECK(!IsReachable(addr));
SetReachable(NET_IPV4, true); // have to reset this, because this is stateful.
}
@@ -827,12 +696,12 @@ BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
SetReachable(NET_IPV4, true);
- BOOST_CHECK_EQUAL(IsLocal(addr), false);
- BOOST_CHECK_EQUAL(AddLocal(addr, 1000), true);
- BOOST_CHECK_EQUAL(IsLocal(addr), true);
+ BOOST_CHECK(!IsLocal(addr));
+ BOOST_CHECK(AddLocal(addr, 1000));
+ BOOST_CHECK(IsLocal(addr));
RemoveLocal(addr);
- BOOST_CHECK_EQUAL(IsLocal(addr), false);
+ BOOST_CHECK(!IsLocal(addr));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 62fd81673d..2c39cbffb9 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -123,7 +123,7 @@ static ScriptError_t ParseScriptError(const std::string& name)
BOOST_FIXTURE_TEST_SUITE(script_tests, BasicTestingSetup)
-void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, int flags, const std::string& message, int scriptError, CAmount nValue = 0)
+void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScriptWitness& scriptWitness, uint32_t flags, const std::string& message, int scriptError, CAmount nValue = 0)
{
bool expect = (scriptError == SCRIPT_ERR_OK);
if (flags & SCRIPT_VERIFY_CLEANSTACK) {
@@ -139,8 +139,8 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
// Verify that removing flags from a passing test or adding flags to a failing test does not change the result.
for (int i = 0; i < 16; ++i) {
- int extra_flags = InsecureRandBits(16);
- int combined_flags = expect ? (flags & ~extra_flags) : (flags | extra_flags);
+ uint32_t extra_flags(InsecureRandBits(16));
+ uint32_t combined_flags{expect ? (flags & ~extra_flags) : (flags | extra_flags)};
// Weed out some invalid flag combinations.
if (combined_flags & SCRIPT_VERIFY_CLEANSTACK && ~combined_flags & (SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS)) continue;
if (combined_flags & SCRIPT_VERIFY_WITNESS && ~combined_flags & SCRIPT_VERIFY_P2SH) continue;
@@ -150,7 +150,7 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, const CScript
#if defined(HAVE_CONSENSUS_LIB)
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
stream << tx2;
- int libconsensus_flags = flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL;
+ uint32_t libconsensus_flags{flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL};
if (libconsensus_flags == flags) {
int expectedSuccessCode = expect ? 1 : 0;
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
@@ -258,7 +258,7 @@ private:
bool havePush;
std::vector<unsigned char> push;
std::string comment;
- int flags;
+ uint32_t flags;
int scriptError;
CAmount nValue;
@@ -278,7 +278,7 @@ private:
}
public:
- TestBuilder(const CScript& script_, const std::string& comment_, int flags_, bool P2SH = false, WitnessMode wm = WitnessMode::NONE, int witnessversion = 0, CAmount nValue_ = 0) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK), nValue(nValue_)
+ TestBuilder(const CScript& script_, const std::string& comment_, uint32_t flags_, bool P2SH = false, WitnessMode wm = WitnessMode::NONE, int witnessversion = 0, CAmount nValue_ = 0) : script(script_), havePush(false), comment(comment_), flags(flags_), scriptError(SCRIPT_ERR_OK), nValue(nValue_)
{
CScript scriptPubKey = script;
if (wm == WitnessMode::PKH) {
@@ -1160,7 +1160,7 @@ SignatureData CombineSignatures(const CTxOut& txout, const CMutableTransaction&
SignatureData data;
data.MergeSignatureData(scriptSig1);
data.MergeSignatureData(scriptSig2);
- ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&tx, 0, txout.nValue), txout.scriptPubKey, data);
+ ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&tx, 0, txout.nValue, SIGHASH_DEFAULT), txout.scriptPubKey, data);
return data;
}
@@ -1677,7 +1677,7 @@ static void AssetTest(const UniValue& test)
const std::vector<CTxOut> prevouts = TxOutsFromJSON(test["prevouts"]);
BOOST_CHECK(prevouts.size() == mtx.vin.size());
size_t idx = test["index"].get_int64();
- unsigned int test_flags = ParseScriptFlags(test["flags"].get_str());
+ uint32_t test_flags{ParseScriptFlags(test["flags"].get_str())};
bool fin = test.exists("final") && test["final"].get_bool();
if (test.exists("success")) {
diff --git a/src/test/serfloat_tests.cpp b/src/test/serfloat_tests.cpp
index 54e07b0f61..15612e2950 100644
--- a/src/test/serfloat_tests.cpp
+++ b/src/test/serfloat_tests.cpp
@@ -36,9 +36,9 @@ uint64_t TestDouble(double f) {
} // namespace
BOOST_AUTO_TEST_CASE(double_serfloat_tests) {
- BOOST_CHECK_EQUAL(TestDouble(0.0), 0);
+ BOOST_CHECK_EQUAL(TestDouble(0.0), 0U);
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()), 0x7ff0000000000000U);
BOOST_CHECK_EQUAL(TestDouble(-std::numeric_limits<double>::infinity()), 0xfff0000000000000);
BOOST_CHECK_EQUAL(TestDouble(0.5), 0x3fe0000000000000ULL);
BOOST_CHECK_EQUAL(TestDouble(1.0), 0x3ff0000000000000ULL);
@@ -48,8 +48,8 @@ BOOST_AUTO_TEST_CASE(double_serfloat_tests) {
// 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);
+ BOOST_CHECK_EQUAL(sizeof(double), 8U);
+ BOOST_CHECK_EQUAL(sizeof(uint64_t), 8U);
// Test extreme values
TestDouble(std::numeric_limits<double>::min());
TestDouble(-std::numeric_limits<double>::min());
@@ -102,11 +102,12 @@ BOOST_AUTO_TEST_CASE(double_serfloat_tests) {
Python code to generate the below hashes:
def reversed_hex(x):
- return binascii.hexlify(''.join(reversed(x)))
+ return bytes(reversed(x)).hex()
+
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'
+ reversed_hex(dsha256(b''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96'
*/
BOOST_AUTO_TEST_CASE(doubles)
{
diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp
index 12fc575c1e..db96fd4940 100644
--- a/src/test/sigopcount_tests.cpp
+++ b/src/test/sigopcount_tests.cpp
@@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount)
* Verifies script execution of the zeroth scriptPubKey of tx output and
* zeroth scriptSig and witness of tx input.
*/
-static ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction& input, int flags)
+static ScriptError VerifyWithFlag(const CTransaction& output, const CMutableTransaction& input, uint32_t flags)
{
ScriptError error;
CTransaction inputi(input);
@@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(GetTxSigOpCost)
key.MakeNewKey(true);
CPubKey pubkey = key.GetPubKey();
// Default flags
- int flags = SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH;
+ const uint32_t flags{SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH};
// Multisig script (legacy counting)
{
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index 7af2b79f37..acd0151e1a 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(streams_vector_reader_rvalue)
uint32_t varint = 0;
// Deserialize into r-value
reader >> VARINT(varint);
- BOOST_CHECK_EQUAL(varint, 54321);
+ BOOST_CHECK_EQUAL(varint, 54321U);
BOOST_CHECK(reader.empty());
}
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 40c53cb2ec..24029ea02e 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -446,7 +446,7 @@ static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const
assert(input.vin[0].scriptWitness.stack == inputm.vin[0].scriptWitness.stack);
}
-static void CheckWithFlag(const CTransactionRef& output, const CMutableTransaction& input, int flags, bool success)
+static void CheckWithFlag(const CTransactionRef& output, const CMutableTransaction& input, uint32_t flags, bool success)
{
ScriptError error;
CTransaction inputi(input);
@@ -561,7 +561,7 @@ SignatureData CombineSignatures(const CMutableTransaction& input1, const CMutabl
SignatureData sigdata;
sigdata = DataFromTransaction(input1, 0, tx->vout[0]);
sigdata.MergeSignatureData(DataFromTransaction(input2, 0, tx->vout[0]));
- ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&input1, 0, tx->vout[0].nValue), tx->vout[0].scriptPubKey, sigdata);
+ ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(&input1, 0, tx->vout[0].nValue, SIGHASH_ALL), tx->vout[0].scriptPubKey, sigdata);
return sigdata;
}
@@ -765,95 +765,89 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
key.MakeNewKey(true);
t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
- std::string reason;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ constexpr auto CheckIsStandard = [](const auto& t) {
+ std::string reason;
+ BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ BOOST_CHECK(reason.empty());
+ };
+ constexpr auto CheckIsNotStandard = [](const auto& t, const std::string& reason_in) {
+ std::string reason;
+ BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
+ BOOST_CHECK_EQUAL(reason_in, reason);
+ };
+
+ CheckIsStandard(t);
// Check dust with default relay fee:
- CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK()/1000;
+ CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK() / 1000;
BOOST_CHECK_EQUAL(nDustThreshold, 546);
// dust:
t.vout[0].nValue = nDustThreshold - 1;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "dust");
+ CheckIsNotStandard(t, "dust");
// not dust:
t.vout[0].nValue = nDustThreshold;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
// Disallowed nVersion
t.nVersion = -1;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "version");
+ CheckIsNotStandard(t, "version");
t.nVersion = 0;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "version");
+ CheckIsNotStandard(t, "version");
t.nVersion = 3;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "version");
+ CheckIsNotStandard(t, "version");
// Allowed nVersion
t.nVersion = 1;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
t.nVersion = 2;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
// Check dust with odd relay fee to verify rounding:
// nDustThreshold = 182 * 3702 / 1000
dustRelayFee = CFeeRate(3702);
// dust:
t.vout[0].nValue = 673 - 1;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "dust");
+ CheckIsNotStandard(t, "dust");
// not dust:
t.vout[0].nValue = 673;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
t.vout[0].scriptPubKey = CScript() << OP_1;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "scriptpubkey");
+ CheckIsNotStandard(t, "scriptpubkey");
// MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
// MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "scriptpubkey");
+ CheckIsNotStandard(t, "scriptpubkey");
// Data payload can be encoded in any way...
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("00") << ParseHex("01");
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
// OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()!
t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0 << ParseHex("01") << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12 << 13 << 14 << 15 << 16;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
t.vout[0].scriptPubKey = CScript() << OP_RETURN << 0 << ParseHex("01") << 2 << ParseHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
// ...so long as it only contains PUSHDATA's
t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RETURN;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "scriptpubkey");
+ CheckIsNotStandard(t, "scriptpubkey");
// TxoutType::NULL_DATA w/o PUSHDATA
t.vout.resize(1);
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
// Only one TxoutType::NULL_DATA permitted in all cases
t.vout.resize(2);
@@ -861,21 +855,15 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
t.vout[0].nValue = 0;
t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
t.vout[1].nValue = 0;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "multi-op-return");
+ CheckIsNotStandard(t, "multi-op-return");
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
t.vout[1].scriptPubKey = CScript() << OP_RETURN;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "multi-op-return");
+ CheckIsNotStandard(t, "multi-op-return");
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
t.vout[1].scriptPubKey = CScript() << OP_RETURN;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "multi-op-return");
+ CheckIsNotStandard(t, "multi-op-return");
// Check large scriptSig (non-standard if size is >1650 bytes)
t.vout.resize(1);
@@ -883,12 +871,10 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
// OP_PUSHDATA2 with len (3 bytes) + data (1647 bytes) = 1650 bytes
t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(1647, 0); // 1650
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(1648, 0); // 1651
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "scriptsig-size");
+ CheckIsNotStandard(t, "scriptsig-size");
// Check scriptSig format (non-standard if there are any other ops than just PUSHs)
t.vin[0].scriptSig = CScript()
@@ -897,7 +883,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
<< std::vector<unsigned char>(235, 0) // OP_PUSHDATA1 x [...x bytes...]
<< std::vector<unsigned char>(1234, 0) // OP_PUSHDATA2 x [...x bytes...]
<< OP_9;
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
const std::vector<unsigned char> non_push_ops = { // arbitrary set of non-push operations
OP_NOP, OP_VERIFY, OP_IF, OP_ROT, OP_3DUP, OP_SIZE, OP_EQUAL, OP_ADD, OP_SUB,
@@ -917,11 +903,10 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
// replace current push-op with each non-push-op
for (auto op : non_push_ops) {
t.vin[0].scriptSig[index] = op;
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "scriptsig-not-pushonly");
+ CheckIsNotStandard(t, "scriptsig-not-pushonly");
}
t.vin[0].scriptSig[index] = orig_op; // restore op
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
}
// Check tx-size (non-standard if transaction weight is > MAX_STANDARD_TX_WEIGHT)
@@ -934,27 +919,47 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
// ===============================
// total: 400000 vbytes
BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400000);
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
// increase output size by one byte, so we end up with 400004 vbytes
t.vout[0].scriptPubKey = CScript() << OP_RETURN << std::vector<unsigned char>(20, 0); // output size: 31 bytes
BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004);
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "tx-size");
+ CheckIsNotStandard(t, "tx-size");
// Check bare multisig (standard if policy flag fIsBareMultisigStd is set)
fIsBareMultisigStd = true;
t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); // simple 1-of-1
t.vin.resize(1);
t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(65, 0);
- BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ CheckIsStandard(t);
fIsBareMultisigStd = false;
- reason.clear();
- BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
- BOOST_CHECK_EQUAL(reason, "bare-multisig");
+ CheckIsNotStandard(t, "bare-multisig");
fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
+
+ // Check P2WPKH outputs dust threshold
+ t.vout[0].scriptPubKey = CScript() << OP_0 << ParseHex("ffffffffffffffffffffffffffffffffffffffff");
+ t.vout[0].nValue = 294;
+ CheckIsStandard(t);
+ t.vout[0].nValue = 293;
+ CheckIsNotStandard(t, "dust");
+
+ // Check P2WSH outputs dust threshold
+ t.vout[0].scriptPubKey = CScript() << OP_0 << ParseHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
+ t.vout[0].nValue = 330;
+ CheckIsStandard(t);
+ t.vout[0].nValue = 329;
+ CheckIsNotStandard(t, "dust");
+
+ // Check future Witness Program versions dust threshold
+ for (int op = OP_2; op <= OP_16; op += 1) {
+ t.vout[0].scriptPubKey = CScript() << (opcodetype)op << ParseHex("ffff");
+ t.vout[0].nValue = 240;
+ CheckIsStandard(t);
+
+ t.vout[0].nValue = 239;
+ CheckIsNotStandard(t, "dust");
+ }
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp
index 23195c0a26..1924ea55b1 100644
--- a/src/test/txvalidationcache_tests.cpp
+++ b/src/test/txvalidationcache_tests.cpp
@@ -112,10 +112,15 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t failing_flags, bool add_to_cache, CCoinsViewCache& active_coins_tip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
PrecomputedTransactionData txdata;
- // If we add many more flags, this loop can get too expensive, but we can
- // rewrite in the future to randomly pick a set of flags to evaluate.
- for (uint32_t test_flags=0; test_flags < (1U << 16); test_flags += 1) {
+
+ FastRandomContext insecure_rand(true);
+
+ for (int count = 0; count < 10000; ++count) {
TxValidationState state;
+
+ // Randomly selects flag combinations
+ uint32_t test_flags = (uint32_t) insecure_rand.randrange((SCRIPT_VERIFY_END_MARKER - 1) << 1);
+
// Filter out incompatible flag choices
if ((test_flags & SCRIPT_VERIFY_CLEANSTACK)) {
// CLEANSTACK requires P2SH and WITNESS, see VerifyScript() in
diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp
index 847a490e03..28d7967078 100644
--- a/src/test/util/net.cpp
+++ b/src/test/util/net.cpp
@@ -6,6 +6,9 @@
#include <chainparams.h>
#include <net.h>
+#include <span.h>
+
+#include <vector>
void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_bytes, bool& complete) const
{
@@ -37,3 +40,25 @@ bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) con
NodeReceiveMsgBytes(node, ser_msg.data, complete);
return complete;
}
+
+std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context)
+{
+ std::vector<NodeEvictionCandidate> candidates;
+ for (int id = 0; id < n_candidates; ++id) {
+ candidates.push_back({
+ /* id */ id,
+ /* nTimeConnected */ static_cast<int64_t>(random_context.randrange(100)),
+ /* m_min_ping_time */ std::chrono::microseconds{random_context.randrange(100)},
+ /* nLastBlockTime */ static_cast<int64_t>(random_context.randrange(100)),
+ /* nLastTXTime */ static_cast<int64_t>(random_context.randrange(100)),
+ /* fRelevantServices */ random_context.randbool(),
+ /* fRelayTxes */ random_context.randbool(),
+ /* fBloomFilter */ random_context.randbool(),
+ /* nKeyedNetGroup */ random_context.randrange(100),
+ /* prefer_evict */ random_context.randbool(),
+ /* m_is_local */ random_context.randbool(),
+ /* m_network */ ALL_NETWORKS[random_context.randrange(ALL_NETWORKS.size())],
+ });
+ }
+ return candidates;
+}
diff --git a/src/test/util/net.h b/src/test/util/net.h
index 1b49a671bd..939ec322ed 100644
--- a/src/test/util/net.h
+++ b/src/test/util/net.h
@@ -141,4 +141,6 @@ private:
mutable size_t m_consumed;
};
+std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context);
+
#endif // BITCOIN_TEST_UTIL_NET_H
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 748272bb1d..ba6b3e32ea 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -141,12 +141,11 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
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));
-
m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>();
m_node.mempool = std::make_unique<CTxMemPool>(m_node.fee_estimator.get(), 1);
m_node.chainman = std::make_unique<ChainstateManager>();
+ m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true);
// Start script-checking threads. Set g_parallel_script_checks to true so they are used.
constexpr int script_check_threads = 2;
@@ -169,7 +168,6 @@ ChainTestingSetup::~ChainTestingSetup()
m_node.scheduler.reset();
m_node.chainman->Reset();
m_node.chainman.reset();
- pblocktree.reset();
}
TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const char*>& extra_args)
@@ -180,7 +178,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
// instead of unit tests, but for now we need these here.
RegisterAllCoreRPCCommands(tableRPC);
- m_node.chainman->InitializeChainstate(*m_node.mempool);
+ m_node.chainman->InitializeChainstate(m_node.mempool.get());
m_node.chainman->ActiveChainstate().InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
assert(!m_node.chainman->ActiveChainstate().CanFlushToDisk());
@@ -195,11 +193,11 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
}
- m_node.addrman = std::make_unique<CAddrMan>();
+ m_node.addrman = std::make_unique<CAddrMan>(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 0);
m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", 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,
+ m_node.banman.get(), *m_node.chainman,
*m_node.mempool, false);
{
CConnman::Options options;
@@ -294,7 +292,7 @@ CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactio
input_coins.insert({outpoint_to_spend, utxo_to_spend});
// - Default signature hashing type
int nHashType = SIGHASH_ALL;
- std::map<int, std::string> input_errors;
+ std::map<int, bilingual_str> input_errors;
assert(SignTransaction(mempool_txn, &keystore, input_coins, nHashType, input_errors));
// If submit=true, add transaction to the mempool.
diff --git a/src/test/util/wallet.cpp b/src/test/util/wallet.cpp
index fd6012e9fe..061659818f 100644
--- a/src/test/util/wallet.cpp
+++ b/src/test/util/wallet.cpp
@@ -8,6 +8,7 @@
#include <outputtype.h>
#include <script/standard.h>
#ifdef ENABLE_WALLET
+#include <util/translation.h>
#include <wallet/wallet.h>
#endif
@@ -18,7 +19,7 @@ std::string getnewaddress(CWallet& w)
{
constexpr auto output_type = OutputType::BECH32;
CTxDestination dest;
- std::string error;
+ bilingual_str error;
if (!w.GetNewDestination(output_type, "", dest, error)) assert(false);
return EncodeDestination(dest);
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 7ce38519cf..a62abf9b9c 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -173,6 +173,22 @@ BOOST_AUTO_TEST_CASE(util_Join)
BOOST_CHECK_EQUAL(Join<std::string>({"foo", "bar"}, ", ", op_upper), "FOO, BAR");
}
+BOOST_AUTO_TEST_CASE(util_TrimString)
+{
+ BOOST_CHECK_EQUAL(TrimString(" foo bar "), "foo bar");
+ BOOST_CHECK_EQUAL(TrimString("\t \n \n \f\n\r\t\v\tfoo \n \f\n\r\t\v\tbar\t \n \f\n\r\t\v\t\n "), "foo \n \f\n\r\t\v\tbar");
+ BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n "), "foo \n\tbar");
+ BOOST_CHECK_EQUAL(TrimString("\t \n foo \n\tbar\t \n ", "fobar"), "\t \n foo \n\tbar\t \n ");
+ BOOST_CHECK_EQUAL(TrimString("foo bar"), "foo bar");
+ BOOST_CHECK_EQUAL(TrimString("foo bar", "fobar"), " ");
+ BOOST_CHECK_EQUAL(TrimString(std::string("\0 foo \0 ", 8)), std::string("\0 foo \0", 7));
+ BOOST_CHECK_EQUAL(TrimString(std::string(" foo ", 5)), std::string("foo", 3));
+ BOOST_CHECK_EQUAL(TrimString(std::string("\t\t\0\0\n\n", 6)), std::string("\0\0", 2));
+ BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6)), std::string("\x05\x04\x03\x02\x01\x00", 6));
+ BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01", 5)), std::string("\0", 1));
+ BOOST_CHECK_EQUAL(TrimString(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), "");
+}
+
BOOST_AUTO_TEST_CASE(util_FormatParseISO8601DateTime)
{
BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z");
@@ -1222,86 +1238,59 @@ BOOST_AUTO_TEST_CASE(util_FormatMoney)
BOOST_AUTO_TEST_CASE(util_ParseMoney)
{
- CAmount ret = 0;
- BOOST_CHECK(ParseMoney("0.0", ret));
- BOOST_CHECK_EQUAL(ret, 0);
-
- BOOST_CHECK(ParseMoney("12345.6789", ret));
- BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789);
-
- BOOST_CHECK(ParseMoney("100000000.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*100000000);
- BOOST_CHECK(ParseMoney("10000000.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*10000000);
- BOOST_CHECK(ParseMoney("1000000.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*1000000);
- BOOST_CHECK(ParseMoney("100000.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*100000);
- BOOST_CHECK(ParseMoney("10000.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*10000);
- BOOST_CHECK(ParseMoney("1000.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*1000);
- BOOST_CHECK(ParseMoney("100.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*100);
- BOOST_CHECK(ParseMoney("10.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN*10);
- BOOST_CHECK(ParseMoney("1.00", ret));
- BOOST_CHECK_EQUAL(ret, COIN);
- BOOST_CHECK(ParseMoney("1", ret));
- BOOST_CHECK_EQUAL(ret, COIN);
- BOOST_CHECK(ParseMoney(" 1", ret));
- BOOST_CHECK_EQUAL(ret, COIN);
- BOOST_CHECK(ParseMoney("1 ", ret));
- BOOST_CHECK_EQUAL(ret, COIN);
- BOOST_CHECK(ParseMoney(" 1 ", ret));
- BOOST_CHECK_EQUAL(ret, COIN);
- BOOST_CHECK(ParseMoney("0.1", ret));
- BOOST_CHECK_EQUAL(ret, COIN/10);
- BOOST_CHECK(ParseMoney("0.01", ret));
- BOOST_CHECK_EQUAL(ret, COIN/100);
- BOOST_CHECK(ParseMoney("0.001", ret));
- BOOST_CHECK_EQUAL(ret, COIN/1000);
- BOOST_CHECK(ParseMoney("0.0001", ret));
- BOOST_CHECK_EQUAL(ret, COIN/10000);
- BOOST_CHECK(ParseMoney("0.00001", ret));
- BOOST_CHECK_EQUAL(ret, COIN/100000);
- BOOST_CHECK(ParseMoney("0.000001", ret));
- BOOST_CHECK_EQUAL(ret, COIN/1000000);
- BOOST_CHECK(ParseMoney("0.0000001", ret));
- BOOST_CHECK_EQUAL(ret, COIN/10000000);
- BOOST_CHECK(ParseMoney("0.00000001", ret));
- BOOST_CHECK_EQUAL(ret, COIN/100000000);
- BOOST_CHECK(ParseMoney(" 0.00000001 ", ret));
- BOOST_CHECK_EQUAL(ret, COIN/100000000);
- BOOST_CHECK(ParseMoney("0.00000001 ", ret));
- BOOST_CHECK_EQUAL(ret, COIN/100000000);
- BOOST_CHECK(ParseMoney(" 0.00000001", ret));
- BOOST_CHECK_EQUAL(ret, COIN/100000000);
-
- // Parsing amount that can not be represented in ret should fail
- BOOST_CHECK(!ParseMoney("0.000000001", ret));
+ BOOST_CHECK_EQUAL(ParseMoney("0.0").value(), 0);
+
+ BOOST_CHECK_EQUAL(ParseMoney("12345.6789").value(), (COIN/10000)*123456789);
+
+ BOOST_CHECK_EQUAL(ParseMoney("10000000.00").value(), COIN*10000000);
+ BOOST_CHECK_EQUAL(ParseMoney("1000000.00").value(), COIN*1000000);
+ BOOST_CHECK_EQUAL(ParseMoney("100000.00").value(), COIN*100000);
+ BOOST_CHECK_EQUAL(ParseMoney("10000.00").value(), COIN*10000);
+ BOOST_CHECK_EQUAL(ParseMoney("1000.00").value(), COIN*1000);
+ BOOST_CHECK_EQUAL(ParseMoney("100.00").value(), COIN*100);
+ BOOST_CHECK_EQUAL(ParseMoney("10.00").value(), COIN*10);
+ BOOST_CHECK_EQUAL(ParseMoney("1.00").value(), COIN);
+ BOOST_CHECK_EQUAL(ParseMoney("1").value(), COIN);
+ BOOST_CHECK_EQUAL(ParseMoney(" 1").value(), COIN);
+ BOOST_CHECK_EQUAL(ParseMoney("1 ").value(), COIN);
+ BOOST_CHECK_EQUAL(ParseMoney(" 1 ").value(), COIN);
+ BOOST_CHECK_EQUAL(ParseMoney("0.1").value(), COIN/10);
+ BOOST_CHECK_EQUAL(ParseMoney("0.01").value(), COIN/100);
+ BOOST_CHECK_EQUAL(ParseMoney("0.001").value(), COIN/1000);
+ BOOST_CHECK_EQUAL(ParseMoney("0.0001").value(), COIN/10000);
+ BOOST_CHECK_EQUAL(ParseMoney("0.00001").value(), COIN/100000);
+ BOOST_CHECK_EQUAL(ParseMoney("0.000001").value(), COIN/1000000);
+ BOOST_CHECK_EQUAL(ParseMoney("0.0000001").value(), COIN/10000000);
+ BOOST_CHECK_EQUAL(ParseMoney("0.00000001").value(), COIN/100000000);
+ BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001 ").value(), COIN/100000000);
+ BOOST_CHECK_EQUAL(ParseMoney("0.00000001 ").value(), COIN/100000000);
+ BOOST_CHECK_EQUAL(ParseMoney(" 0.00000001").value(), COIN/100000000);
+
+ // Parsing amount that can not be represented should fail
+ BOOST_CHECK(!ParseMoney("100000000.00"));
+ BOOST_CHECK(!ParseMoney("0.000000001"));
// Parsing empty string should fail
- BOOST_CHECK(!ParseMoney("", ret));
- BOOST_CHECK(!ParseMoney(" ", ret));
- BOOST_CHECK(!ParseMoney(" ", ret));
+ BOOST_CHECK(!ParseMoney(""));
+ BOOST_CHECK(!ParseMoney(" "));
+ BOOST_CHECK(!ParseMoney(" "));
// Parsing two numbers should fail
- BOOST_CHECK(!ParseMoney("1 2", ret));
- BOOST_CHECK(!ParseMoney(" 1 2 ", ret));
- BOOST_CHECK(!ParseMoney(" 1.2 3 ", ret));
- BOOST_CHECK(!ParseMoney(" 1 2.3 ", ret));
+ BOOST_CHECK(!ParseMoney("1 2"));
+ BOOST_CHECK(!ParseMoney(" 1 2 "));
+ BOOST_CHECK(!ParseMoney(" 1.2 3 "));
+ BOOST_CHECK(!ParseMoney(" 1 2.3 "));
// Attempted 63 bit overflow should fail
- BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
+ BOOST_CHECK(!ParseMoney("92233720368.54775808"));
// Parsing negative amounts must fail
- BOOST_CHECK(!ParseMoney("-1", ret));
+ BOOST_CHECK(!ParseMoney("-1"));
// Parsing strings with embedded NUL characters should fail
- BOOST_CHECK(!ParseMoney("\0-1"s, ret));
- BOOST_CHECK(!ParseMoney(STRING_WITH_EMBEDDED_NULL_CHAR, ret));
- BOOST_CHECK(!ParseMoney("1\0"s, ret));
+ BOOST_CHECK(!ParseMoney("\0-1"s));
+ BOOST_CHECK(!ParseMoney(STRING_WITH_EMBEDDED_NULL_CHAR));
+ BOOST_CHECK(!ParseMoney("1\0"s));
}
BOOST_AUTO_TEST_CASE(util_IsHex)
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index e0bc10d660..8f4ff6815b 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -77,6 +77,8 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
txCoinbase.vout[1].nValue = txCoinbase.vout[0].nValue;
txCoinbase.vout[0].nValue = 0;
txCoinbase.vin[0].scriptWitness.SetNull();
+ // Always pad with OP_0 at the end to avoid bad-cb-length error
+ txCoinbase.vin[0].scriptSig = CScript{} << WITH_LOCK(::cs_main, return m_node.chainman->m_blockman.LookupBlockIndex(prev_hash)->nHeight + 1) << OP_0;
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
return pblock;
@@ -84,8 +86,8 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock> pblock)
{
- LOCK(cs_main); // For m_node.chainman->m_blockman.LookupBlockIndex
- GenerateCoinbaseCommitment(*pblock, m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock), Params().GetConsensus());
+ const CBlockIndex* prev_block{WITH_LOCK(::cs_main, return m_node.chainman->m_blockman.LookupBlockIndex(pblock->hashPrevBlock))};
+ GenerateCoinbaseCommitment(*pblock, prev_block, Params().GetConsensus());
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
@@ -93,6 +95,11 @@ std::shared_ptr<CBlock> MinerTestingSetup::FinalizeBlock(std::shared_ptr<CBlock>
++(pblock->nNonce);
}
+ // submit block header, so that miner can get the block height from the
+ // global state and the node has the topology of the chain
+ BlockValidationState ignored;
+ BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders({pblock->GetBlockHeader()}, ignored, Params()));
+
return pblock;
}
@@ -147,13 +154,6 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
}
bool ignored;
- BlockValidationState state;
- std::vector<CBlockHeader> headers;
- std::transform(blocks.begin(), blocks.end(), std::back_inserter(headers), [](std::shared_ptr<const CBlock> b) { return b->GetBlockHeader(); });
-
- // Process all the headers so we understand the toplogy of the chain
- BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders(headers, state, Params()));
-
// Connect the genesis block and drain any outstanding events
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
SyncWithValidationInterfaceQueue();
diff --git a/src/test/validation_chainstate_tests.cpp b/src/test/validation_chainstate_tests.cpp
index 92d8cf2e7d..315ef22599 100644
--- a/src/test/validation_chainstate_tests.cpp
+++ b/src/test/validation_chainstate_tests.cpp
@@ -20,6 +20,7 @@ BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, TestingSetup)
BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
{
ChainstateManager manager;
+ WITH_LOCK(::cs_main, manager.m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(1 << 20, true));
CTxMemPool mempool;
//! Create and add a Coin with DynamicMemoryUsage of 80 bytes to the given view.
@@ -35,7 +36,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
return outp;
};
- CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(mempool));
+ CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool));
c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
diff --git a/src/test/validation_chainstatemanager_tests.cpp b/src/test/validation_chainstatemanager_tests.cpp
index 7c1db9d4b9..0bd378631b 100644
--- a/src/test/validation_chainstatemanager_tests.cpp
+++ b/src/test/validation_chainstatemanager_tests.cpp
@@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
// Create a legacy (IBD) chainstate.
//
- CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(mempool));
+ CChainState& c1 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(&mempool));
chainstates.push_back(&c1);
c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
//
const uint256 snapshot_blockhash = GetRandHash();
CChainState& c2 = WITH_LOCK(::cs_main, return manager.InitializeChainstate(
- mempool, snapshot_blockhash));
+ &mempool, snapshot_blockhash));
chainstates.push_back(&c2);
BOOST_CHECK_EQUAL(manager.SnapshotBlockhash().value(), snapshot_blockhash);
@@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
// Create a legacy (IBD) chainstate.
//
- CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(mempool));
+ CChainState& c1 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool));
chainstates.push_back(&c1);
c1.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
@@ -147,7 +147,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
// Create a snapshot-based chainstate.
//
- CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(mempool, GetRandHash()));
+ CChainState& c2 = WITH_LOCK(cs_main, return manager.InitializeChainstate(&mempool, GetRandHash()));
chainstates.push_back(&c2);
c2.InitCoinsDB(
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
diff --git a/src/test/validation_flush_tests.cpp b/src/test/validation_flush_tests.cpp
index a3b344d2c9..22aafcaa6c 100644
--- a/src/test/validation_flush_tests.cpp
+++ b/src/test/validation_flush_tests.cpp
@@ -20,10 +20,9 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
{
CTxMemPool mempool;
BlockManager blockman{};
- CChainState chainstate{mempool, blockman};
+ CChainState chainstate{&mempool, blockman};
chainstate.InitCoinsDB(/*cache_size_bytes*/ 1 << 10, /*in_memory*/ true, /*should_wipe*/ false);
WITH_LOCK(::cs_main, chainstate.InitCoinsCache(1 << 10));
- CTxMemPool tx_pool{};
constexpr bool is_64_bit = sizeof(void*) == 8;
@@ -57,7 +56,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
// Without any coins in the cache, we shouldn't need to flush.
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
CoinsCacheSizeState::OK);
// If the initial memory allocations of cacheCoins don't match these common
@@ -72,7 +71,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
}
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
CoinsCacheSizeState::CRITICAL);
BOOST_TEST_MESSAGE("Exiting cache flush tests early due to unsupported arch");
@@ -93,7 +92,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
print_view_mem_usage(view);
BOOST_CHECK_EQUAL(view.AccessCoin(res).DynamicMemoryUsage(), COIN_SIZE);
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
CoinsCacheSizeState::OK);
}
@@ -101,26 +100,26 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
for (int i{0}; i < 4; ++i) {
add_coin(view);
print_view_mem_usage(view);
- if (chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0) ==
+ if (chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0) ==
CoinsCacheSizeState::CRITICAL) {
break;
}
}
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 0),
CoinsCacheSizeState::CRITICAL);
// Passing non-zero max mempool usage should allow us more headroom.
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 1 << 10),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 1 << 10),
CoinsCacheSizeState::OK);
for (int i{0}; i < 3; ++i) {
add_coin(view);
print_view_mem_usage(view);
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 1 << 10),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, /*max_mempool_size_bytes*/ 1 << 10),
CoinsCacheSizeState::OK);
}
@@ -136,7 +135,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
BOOST_CHECK(usage_percentage >= 0.9);
BOOST_CHECK(usage_percentage < 1);
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, 1 << 10),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, 1 << 10),
CoinsCacheSizeState::LARGE);
}
@@ -144,7 +143,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
for (int i{0}; i < 1000; ++i) {
add_coin(view);
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool),
+ chainstate.GetCoinsCacheSizeState(),
CoinsCacheSizeState::OK);
}
@@ -152,7 +151,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
// preallocated memory that doesn't get reclaimed even after flush.
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, 0),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, 0),
CoinsCacheSizeState::CRITICAL);
view.SetBestBlock(InsecureRand256());
@@ -160,7 +159,7 @@ BOOST_AUTO_TEST_CASE(getcoinscachesizestate)
print_view_mem_usage(view);
BOOST_CHECK_EQUAL(
- chainstate.GetCoinsCacheSizeState(&tx_pool, MAX_COINS_CACHE_BYTES, 0),
+ chainstate.GetCoinsCacheSizeState(MAX_COINS_CACHE_BYTES, 0),
CoinsCacheSizeState::CRITICAL);
}