aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/blockfilter_index_tests.cpp8
-rw-r--r--src/test/checkqueue_tests.cpp2
-rw-r--r--src/test/coins_tests.cpp2
-rw-r--r--src/test/data/script_tests.json2
-rw-r--r--src/test/denialofservice_tests.cpp114
-rw-r--r--src/test/descriptor_tests.cpp4
-rw-r--r--src/test/fuzz/addrdb.cpp14
-rw-r--r--src/test/fuzz/autofile.cpp72
-rw-r--r--src/test/fuzz/banman.cpp88
-rw-r--r--src/test/fuzz/buffered_file.cpp74
-rw-r--r--src/test/fuzz/coins_view.cpp2
-rw-r--r--src/test/fuzz/crypto.cpp124
-rw-r--r--src/test/fuzz/crypto_aes256.cpp30
-rw-r--r--src/test/fuzz/crypto_aes256cbc.cpp34
-rw-r--r--src/test/fuzz/crypto_chacha20.cpp50
-rw-r--r--src/test/fuzz/crypto_chacha20_poly1305_aead.cpp72
-rw-r--r--src/test/fuzz/crypto_common.cpp70
-rw-r--r--src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp25
-rw-r--r--src/test/fuzz/crypto_poly1305.cpp22
-rw-r--r--src/test/fuzz/decode_tx.cpp2
-rw-r--r--src/test/fuzz/fuzz.cpp16
-rw-r--r--src/test/fuzz/http_request.cpp10
-rw-r--r--src/test/fuzz/key.cpp18
-rw-r--r--src/test/fuzz/kitchen_sink.cpp1
-rw-r--r--src/test/fuzz/load_external_block_file.cpp31
-rw-r--r--src/test/fuzz/net_permissions.cpp5
-rw-r--r--src/test/fuzz/netaddress.cpp30
-rw-r--r--src/test/fuzz/p2p_transport_deserializer.cpp2
-rw-r--r--src/test/fuzz/policy_estimator.cpp11
-rw-r--r--src/test/fuzz/policy_estimator_io.cpp28
-rw-r--r--src/test/fuzz/process_message.cpp24
-rw-r--r--src/test/fuzz/process_messages.cpp5
-rw-r--r--src/test/fuzz/psbt.cpp2
-rw-r--r--src/test/fuzz/script.cpp45
-rw-r--r--src/test/fuzz/script_bitcoin_consensus.cpp31
-rw-r--r--src/test/fuzz/script_descriptor_cache.cpp42
-rw-r--r--src/test/fuzz/script_interpreter.cpp41
-rw-r--r--src/test/fuzz/script_sigcache.cpp45
-rw-r--r--src/test/fuzz/script_sign.cpp149
-rw-r--r--src/test/fuzz/scriptnum_ops.cpp2
-rw-r--r--src/test/fuzz/signature_checker.cpp6
-rw-r--r--src/test/fuzz/span.cpp4
-rw-r--r--src/test/fuzz/spanparsing.cpp2
-rw-r--r--src/test/fuzz/string.cpp5
-rw-r--r--src/test/fuzz/util.h313
-rw-r--r--src/test/getarg_tests.cpp133
-rw-r--r--src/test/key_tests.cpp44
-rw-r--r--src/test/miner_tests.cpp6
-rw-r--r--src/test/multisig_tests.cpp2
-rw-r--r--src/test/net_tests.cpp5
-rw-r--r--src/test/netbase_tests.cpp19
-rw-r--r--src/test/policy_fee_tests.cpp34
-rw-r--r--src/test/raii_event_tests.cpp19
-rw-r--r--src/test/scheduler_tests.cpp8
-rw-r--r--src/test/script_standard_tests.cpp106
-rw-r--r--src/test/settings_tests.cpp80
-rw-r--r--src/test/sighash_tests.cpp2
-rw-r--r--src/test/sync_tests.cpp2
-rw-r--r--src/test/timedata_tests.cpp3
-rw-r--r--src/test/transaction_tests.cpp8
-rw-r--r--src/test/util/mining.cpp6
-rw-r--r--src/test/util/setup_common.cpp7
-rw-r--r--src/test/util/setup_common.h4
-rw-r--r--src/test/util/transaction_utils.h4
-rw-r--r--src/test/util_tests.cpp55
-rw-r--r--src/test/util_threadnames_tests.cpp2
-rw-r--r--src/test/validation_block_tests.cpp10
67 files changed, 1906 insertions, 332 deletions
diff --git a/src/test/blockfilter_index_tests.cpp b/src/test/blockfilter_index_tests.cpp
index 7dff2e6e86..00c4bdc14e 100644
--- a/src/test/blockfilter_index_tests.cpp
+++ b/src/test/blockfilter_index_tests.cpp
@@ -94,7 +94,7 @@ bool BuildChainTestingSetup::BuildChain(const CBlockIndex* pindex,
CBlockHeader header = block->GetBlockHeader();
BlockValidationState state;
- if (!EnsureChainman(m_node).ProcessNewBlockHeaders({header}, state, Params(), &pindex)) {
+ if (!Assert(m_node.chainman)->ProcessNewBlockHeaders({header}, state, Params(), &pindex)) {
return false;
}
}
@@ -171,7 +171,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainA_last_header = last_header;
for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i];
- BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
}
for (size_t i = 0; i < 2; i++) {
const auto& block = chainA[i];
@@ -189,7 +189,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
uint256 chainB_last_header = last_header;
for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i];
- BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
}
for (size_t i = 0; i < 3; i++) {
const auto& block = chainB[i];
@@ -220,7 +220,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
// Reorg back to chain A.
for (size_t i = 2; i < 4; i++) {
const auto& block = chainA[i];
- BOOST_REQUIRE(EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, nullptr));
+ BOOST_REQUIRE(Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, nullptr));
}
// Check that chain A and B blocks can be retrieved.
diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp
index 35750b2ebc..8348810ac1 100644
--- a/src/test/checkqueue_tests.cpp
+++ b/src/test/checkqueue_tests.cpp
@@ -10,7 +10,7 @@
#include <util/time.h>
#include <boost/test/unit_test.hpp>
-#include <boost/thread.hpp>
+#include <boost/thread/thread.hpp>
#include <atomic>
#include <condition_variable>
diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp
index 60196c36a5..173ec5e3d9 100644
--- a/src/test/coins_tests.cpp
+++ b/src/test/coins_tests.cpp
@@ -538,7 +538,7 @@ BOOST_AUTO_TEST_CASE(ccoins_serialization)
CDataStream tmp(SER_DISK, CLIENT_VERSION);
uint64_t x = 3000000000ULL;
tmp << VARINT(x);
- BOOST_CHECK_EQUAL(HexStr(tmp.begin(), tmp.end()), "8a95c0bb00");
+ BOOST_CHECK_EQUAL(HexStr(tmp), "8a95c0bb00");
CDataStream ss5(ParseHex("00008a95c0bb00"), SER_DISK, CLIENT_VERSION);
try {
Coin cc5;
diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json
index c01ef307b7..724789bbf9 100644
--- a/src/test/data/script_tests.json
+++ b/src/test/data/script_tests.json
@@ -678,7 +678,7 @@
["0 0x02 0x0000 0", "CHECKMULTISIGVERIFY 1", "", "OK"],
["While not really correctly DER encoded, the empty signature is allowed by"],
-["STRICTENC to provide a compact way to provide a delibrately invalid signature."],
+["STRICTENC to provide a compact way to provide a deliberately invalid signature."],
["0", "0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 CHECKSIG NOT", "STRICTENC", "OK"],
["0 0", "1 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 1 CHECKMULTISIG NOT", "STRICTENC", "OK"],
diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp
index 348b170536..b1a635d9da 100644
--- a/src/test/denialofservice_tests.cpp
+++ b/src/test/denialofservice_tests.cpp
@@ -4,10 +4,12 @@
// Unit tests for denial-of-service detection/prevention code
+#include <arith_uint256.h>
#include <banman.h>
#include <chainparams.h>
#include <net.h>
#include <net_processing.h>
+#include <pubkey.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
@@ -98,11 +100,11 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
// Test starts here
{
- LOCK2(cs_main, dummyNode1.cs_sendProcessing);
+ LOCK(dummyNode1.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); // should result in getheaders
}
{
- LOCK2(cs_main, dummyNode1.cs_vSend);
+ LOCK(dummyNode1.cs_vSend);
BOOST_CHECK(dummyNode1.vSendMsg.size() > 0);
dummyNode1.vSendMsg.clear();
}
@@ -111,17 +113,17 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
// Wait 21 minutes
SetMockTime(nStartTime+21*60);
{
- LOCK2(cs_main, dummyNode1.cs_sendProcessing);
+ LOCK(dummyNode1.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); // should result in getheaders
}
{
- LOCK2(cs_main, dummyNode1.cs_vSend);
+ LOCK(dummyNode1.cs_vSend);
BOOST_CHECK(dummyNode1.vSendMsg.size() > 0);
}
// Wait 3 more minutes
SetMockTime(nStartTime+24*60);
{
- LOCK2(cs_main, dummyNode1.cs_sendProcessing);
+ LOCK(dummyNode1.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1)); // should result in disconnect
}
BOOST_CHECK(dummyNode1.fDisconnect == true);
@@ -217,7 +219,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
connman->ClearNodes();
}
-BOOST_AUTO_TEST_CASE(DoS_banning)
+BOOST_AUTO_TEST_CASE(peer_discouragement)
{
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
@@ -232,14 +234,14 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
dummyNode1.fSuccessfullyConnected = true;
{
LOCK(cs_main);
- Misbehaving(dummyNode1.GetId(), 100); // Should get banned
+ Misbehaving(dummyNode1.GetId(), DISCOURAGEMENT_THRESHOLD); // Should be discouraged
}
{
- LOCK2(cs_main, dummyNode1.cs_sendProcessing);
+ LOCK(dummyNode1.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode1));
}
- BOOST_CHECK(banman->IsBanned(addr1));
- BOOST_CHECK(!banman->IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned
+ BOOST_CHECK(banman->IsDiscouraged(addr1));
+ BOOST_CHECK(!banman->IsDiscouraged(ip(0xa0b0c001|0x0000ff00))); // Different IP, not discouraged
CAddress addr2(ip(0xa0b0c002), NODE_NONE);
CNode dummyNode2(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr2, 1, 1, CAddress(), "", true);
@@ -249,76 +251,30 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
dummyNode2.fSuccessfullyConnected = true;
{
LOCK(cs_main);
- Misbehaving(dummyNode2.GetId(), 50);
+ Misbehaving(dummyNode2.GetId(), DISCOURAGEMENT_THRESHOLD - 1);
}
{
- LOCK2(cs_main, dummyNode2.cs_sendProcessing);
+ LOCK(dummyNode2.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
}
- BOOST_CHECK(!banman->IsBanned(addr2)); // 2 not banned yet...
- BOOST_CHECK(banman->IsBanned(addr1)); // ... but 1 still should be
+ BOOST_CHECK(!banman->IsDiscouraged(addr2)); // 2 not discouraged yet...
+ BOOST_CHECK(banman->IsDiscouraged(addr1)); // ... but 1 still should be
{
LOCK(cs_main);
- Misbehaving(dummyNode2.GetId(), 50);
+ Misbehaving(dummyNode2.GetId(), 1); // 2 reaches discouragement threshold
}
{
- LOCK2(cs_main, dummyNode2.cs_sendProcessing);
+ LOCK(dummyNode2.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode2));
}
- BOOST_CHECK(banman->IsBanned(addr2));
+ BOOST_CHECK(banman->IsDiscouraged(addr1)); // Expect both 1 and 2
+ BOOST_CHECK(banman->IsDiscouraged(addr2)); // to be discouraged now
bool dummy;
peerLogic->FinalizeNode(dummyNode1.GetId(), dummy);
peerLogic->FinalizeNode(dummyNode2.GetId(), dummy);
}
-BOOST_AUTO_TEST_CASE(DoS_banscore)
-{
- auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
- auto connman = MakeUnique<CConnman>(0x1337, 0x1337);
- auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), banman.get(), *m_node.scheduler, *m_node.chainman, *m_node.mempool);
-
- banman->ClearBanned();
- gArgs.ForceSetArg("-banscore", "111"); // because 11 is my favorite number
- CAddress addr1(ip(0xa0b0c001), NODE_NONE);
- CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, CAddress(), "", true);
- dummyNode1.SetSendVersion(PROTOCOL_VERSION);
- peerLogic->InitializeNode(&dummyNode1);
- dummyNode1.nVersion = 1;
- dummyNode1.fSuccessfullyConnected = true;
- {
- LOCK(cs_main);
- Misbehaving(dummyNode1.GetId(), 100);
- }
- {
- LOCK2(cs_main, dummyNode1.cs_sendProcessing);
- BOOST_CHECK(peerLogic->SendMessages(&dummyNode1));
- }
- BOOST_CHECK(!banman->IsBanned(addr1));
- {
- LOCK(cs_main);
- Misbehaving(dummyNode1.GetId(), 10);
- }
- {
- LOCK2(cs_main, dummyNode1.cs_sendProcessing);
- BOOST_CHECK(peerLogic->SendMessages(&dummyNode1));
- }
- BOOST_CHECK(!banman->IsBanned(addr1));
- {
- LOCK(cs_main);
- Misbehaving(dummyNode1.GetId(), 1);
- }
- {
- LOCK2(cs_main, dummyNode1.cs_sendProcessing);
- BOOST_CHECK(peerLogic->SendMessages(&dummyNode1));
- }
- BOOST_CHECK(banman->IsBanned(addr1));
- gArgs.ForceSetArg("-banscore", ToString(DEFAULT_BANSCORE_THRESHOLD));
-
- bool dummy;
- peerLogic->FinalizeNode(dummyNode1.GetId(), dummy);
-}
-
BOOST_AUTO_TEST_CASE(DoS_bantime)
{
auto banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
@@ -338,19 +294,13 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
{
LOCK(cs_main);
- Misbehaving(dummyNode.GetId(), 100);
+ Misbehaving(dummyNode.GetId(), DISCOURAGEMENT_THRESHOLD);
}
{
- LOCK2(cs_main, dummyNode.cs_sendProcessing);
+ LOCK(dummyNode.cs_sendProcessing);
BOOST_CHECK(peerLogic->SendMessages(&dummyNode));
}
- BOOST_CHECK(banman->IsBanned(addr));
-
- SetMockTime(nStartTime+60*60);
- BOOST_CHECK(banman->IsBanned(addr));
-
- SetMockTime(nStartTime+60*60*24+1);
- BOOST_CHECK(!banman->IsBanned(addr));
+ BOOST_CHECK(banman->IsDiscouraged(addr));
bool dummy;
peerLogic->FinalizeNode(dummyNode.GetId(), dummy);
@@ -366,10 +316,26 @@ static CTransactionRef RandomOrphan()
return it->second.tx;
}
+static void MakeNewKeyWithFastRandomContext(CKey& key)
+{
+ std::vector<unsigned char> keydata;
+ keydata = g_insecure_rand_ctx.randbytes(32);
+ key.Set(keydata.data(), keydata.data() + keydata.size(), /*fCompressedIn*/ true);
+ assert(key.IsValid());
+}
+
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
{
+ // This test had non-deterministic coverage due to
+ // randomly selected seeds.
+ // This seed is chosen so that all branches of the function
+ // ecdsa_signature_parse_der_lax are executed during this test.
+ // Specifically branches that run only when an ECDSA
+ // signature's R and S values have leading zeros.
+ g_insecure_rand_ctx = FastRandomContext(ArithToUint256(arith_uint256(33)));
+
CKey key;
- key.MakeNewKey(true);
+ MakeNewKeyWithFastRandomContext(key);
FillableSigningProvider keystore;
BOOST_CHECK(keystore.AddKey(key));
diff --git a/src/test/descriptor_tests.cpp b/src/test/descriptor_tests.cpp
index 5f9a78ceb2..20132d5782 100644
--- a/src/test/descriptor_tests.cpp
+++ b/src/test/descriptor_tests.cpp
@@ -135,7 +135,7 @@ void DoCheck(const std::string& prv, const std::string& pub, int flags, const st
// When the descriptor is hardened, evaluate with access to the private keys inside.
const FlatSigningProvider& key_provider = (flags & HARDENED) ? keys_priv : keys_pub;
- // Evaluate the descriptor selected by `t` in poisition `i`.
+ // Evaluate the descriptor selected by `t` in position `i`.
FlatSigningProvider script_provider, script_provider_cached;
std::vector<CScript> spks, spks_cached;
DescriptorCache desc_cache;
@@ -216,7 +216,7 @@ void DoCheck(const std::string& prv, const std::string& pub, int flags, const st
// For each of the produced scripts, verify solvability, and when possible, try to sign a transaction spending it.
for (size_t n = 0; n < spks.size(); ++n) {
- BOOST_CHECK_EQUAL(ref[n], HexStr(spks[n].begin(), spks[n].end()));
+ BOOST_CHECK_EQUAL(ref[n], HexStr(spks[n]));
BOOST_CHECK_EQUAL(IsSolvable(Merge(key_provider, script_provider), spks[n]), (flags & UNSOLVABLE) == 0);
if (flags & SIGNABLE) {
diff --git a/src/test/fuzz/addrdb.cpp b/src/test/fuzz/addrdb.cpp
index 524cea83fe..16b1cb755a 100644
--- a/src/test/fuzz/addrdb.cpp
+++ b/src/test/fuzz/addrdb.cpp
@@ -17,19 +17,13 @@ void test_one_input(const std::vector<uint8_t>& buffer)
{
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, 3)) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 2)) {
case 0:
return CBanEntry{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
break;
- case 1:
- return CBanEntry{fuzzed_data_provider.ConsumeIntegral<int64_t>(), fuzzed_data_provider.PickValueInArray<BanReason>({
- BanReason::BanReasonUnknown,
- BanReason::BanReasonNodeMisbehaving,
- BanReason::BanReasonManuallyAdded,
- })};
- break;
- case 2: {
+ case 1: {
const std::optional<CBanEntry> ban_entry = ConsumeDeserializable<CBanEntry>(fuzzed_data_provider);
if (ban_entry) {
return *ban_entry;
@@ -39,5 +33,5 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
return CBanEntry{};
}();
- assert(!ban_entry.banReasonToString().empty());
+ (void)ban_entry; // currently unused
}
diff --git a/src/test/fuzz/autofile.cpp b/src/test/fuzz/autofile.cpp
new file mode 100644
index 0000000000..7ea0bdd2a7
--- /dev/null
+++ b/src/test/fuzz/autofile.cpp
@@ -0,0 +1,72 @@
+// 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 <optional.h>
+#include <streams.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <array>
+#include <cstdint>
+#include <iostream>
+#include <optional>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
+ CAutoFile auto_file = fuzzed_auto_file_provider.open();
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
+ case 0: {
+ std::array<uint8_t, 4096> arr{};
+ try {
+ auto_file.read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ } catch (const std::ios_base::failure&) {
+ }
+ break;
+ }
+ case 1: {
+ const std::array<uint8_t, 4096> arr{};
+ try {
+ auto_file.write((const char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ } catch (const std::ios_base::failure&) {
+ }
+ break;
+ }
+ case 2: {
+ try {
+ auto_file.ignore(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ } catch (const std::ios_base::failure&) {
+ }
+ break;
+ }
+ case 3: {
+ auto_file.fclose();
+ break;
+ }
+ case 4: {
+ ReadFromStream(fuzzed_data_provider, auto_file);
+ break;
+ }
+ case 5: {
+ WriteToStream(fuzzed_data_provider, auto_file);
+ break;
+ }
+ }
+ }
+ (void)auto_file.Get();
+ (void)auto_file.GetType();
+ (void)auto_file.GetVersion();
+ (void)auto_file.IsNull();
+ if (fuzzed_data_provider.ConsumeBool()) {
+ FILE* f = auto_file.release();
+ if (f != nullptr) {
+ fclose(f);
+ }
+ }
+}
diff --git a/src/test/fuzz/banman.cpp b/src/test/fuzz/banman.cpp
new file mode 100644
index 0000000000..fc4a1d9261
--- /dev/null
+++ b/src/test/fuzz/banman.cpp
@@ -0,0 +1,88 @@
+// 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 <banman.h>
+#include <fs.h>
+#include <netaddress.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/system.h>
+
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <vector>
+
+namespace {
+int64_t ConsumeBanTimeOffset(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ // Avoid signed integer overflow by capping to int32_t max:
+ // banman.cpp:137:73: runtime error: signed integer overflow: 1591700817 + 9223372036854775807 cannot be represented in type 'long'
+ return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(std::numeric_limits<int64_t>::min(), std::numeric_limits<int32_t>::max());
+}
+} // namespace
+
+void initialize()
+{
+ InitializeFuzzingContext();
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ const fs::path banlist_file = GetDataDir() / "fuzzed_banlist.dat";
+ fs::remove(banlist_file);
+ {
+ BanMan ban_man{banlist_file, nullptr, ConsumeBanTimeOffset(fuzzed_data_provider)};
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
+ case 0: {
+ ban_man.Ban(ConsumeNetAddr(fuzzed_data_provider),
+ ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 1: {
+ ban_man.Ban(ConsumeSubNet(fuzzed_data_provider),
+ ConsumeBanTimeOffset(fuzzed_data_provider), fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 2: {
+ ban_man.ClearBanned();
+ break;
+ }
+ case 4: {
+ ban_man.IsBanned(ConsumeNetAddr(fuzzed_data_provider));
+ break;
+ }
+ case 5: {
+ ban_man.IsBanned(ConsumeSubNet(fuzzed_data_provider));
+ break;
+ }
+ case 6: {
+ ban_man.Unban(ConsumeNetAddr(fuzzed_data_provider));
+ break;
+ }
+ case 7: {
+ ban_man.Unban(ConsumeSubNet(fuzzed_data_provider));
+ break;
+ }
+ case 8: {
+ banmap_t banmap;
+ ban_man.GetBanned(banmap);
+ break;
+ }
+ case 9: {
+ ban_man.DumpBanlist();
+ break;
+ }
+ case 11: {
+ ban_man.Discourage(ConsumeNetAddr(fuzzed_data_provider));
+ break;
+ }
+ }
+ }
+ }
+ fs::remove(banlist_file);
+}
diff --git a/src/test/fuzz/buffered_file.cpp b/src/test/fuzz/buffered_file.cpp
new file mode 100644
index 0000000000..e575640be5
--- /dev/null
+++ b/src/test/fuzz/buffered_file.cpp
@@ -0,0 +1,74 @@
+// 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 <optional.h>
+#include <streams.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <array>
+#include <cstdint>
+#include <iostream>
+#include <optional>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
+ std::optional<CBufferedFile> opt_buffered_file;
+ FILE* fuzzed_file = fuzzed_file_provider.open();
+ try {
+ opt_buffered_file.emplace(fuzzed_file, fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096), fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeIntegral<int>());
+ } catch (const std::ios_base::failure&) {
+ if (fuzzed_file != nullptr) {
+ fclose(fuzzed_file);
+ }
+ }
+ if (opt_buffered_file && fuzzed_file != nullptr) {
+ bool setpos_fail = false;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 4)) {
+ case 0: {
+ std::array<uint8_t, 4096> arr{};
+ try {
+ opt_buffered_file->read((char*)arr.data(), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ } catch (const std::ios_base::failure&) {
+ }
+ break;
+ }
+ case 1: {
+ opt_buffered_file->SetLimit(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096));
+ break;
+ }
+ case 2: {
+ if (!opt_buffered_file->SetPos(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(0, 4096))) {
+ setpos_fail = true;
+ }
+ break;
+ }
+ case 3: {
+ if (setpos_fail) {
+ // Calling FindByte(...) after a failed SetPos(...) call may result in an infinite loop.
+ break;
+ }
+ try {
+ opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<char>());
+ } catch (const std::ios_base::failure&) {
+ }
+ break;
+ }
+ case 4: {
+ ReadFromStream(fuzzed_data_provider, *opt_buffered_file);
+ break;
+ }
+ }
+ }
+ opt_buffered_file->GetPos();
+ opt_buffered_file->GetType();
+ opt_buffered_file->GetVersion();
+ }
+}
diff --git a/src/test/fuzz/coins_view.cpp b/src/test/fuzz/coins_view.cpp
index 52dd62a145..c186bef7ae 100644
--- a/src/test/fuzz/coins_view.cpp
+++ b/src/test/fuzz/coins_view.cpp
@@ -278,7 +278,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CCoinsStats stats;
bool expected_code_path = false;
try {
- (void)GetUTXOStats(&coins_view_cache, stats);
+ (void)GetUTXOStats(&coins_view_cache, stats, CoinStatsHashType::HASH_SERIALIZED);
} catch (const std::logic_error&) {
expected_code_path = true;
}
diff --git a/src/test/fuzz/crypto.cpp b/src/test/fuzz/crypto.cpp
new file mode 100644
index 0000000000..595cdf9abb
--- /dev/null
+++ b/src/test/fuzz/crypto.cpp
@@ -0,0 +1,124 @@
+// 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 <crypto/hmac_sha256.h>
+#include <crypto/hmac_sha512.h>
+#include <crypto/ripemd160.h>
+#include <crypto/sha1.h>
+#include <crypto/sha256.h>
+#include <crypto/sha512.h>
+#include <hash.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ std::vector<uint8_t> data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ if (data.empty()) {
+ data.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
+
+ CHash160 hash160;
+ CHash256 hash256;
+ CHMAC_SHA256 hmac_sha256{data.data(), data.size()};
+ CHMAC_SHA512 hmac_sha512{data.data(), data.size()};
+ CRIPEMD160 ripemd160;
+ CSHA1 sha1;
+ CSHA256 sha256;
+ CSHA512 sha512;
+ CSipHasher sip_hasher{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
+
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 2)) {
+ case 0: {
+ if (fuzzed_data_provider.ConsumeBool()) {
+ data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ if (data.empty()) {
+ data.resize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 4096), fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
+ }
+
+ (void)hash160.Write(data.data(), data.size());
+ (void)hash256.Write(data.data(), data.size());
+ (void)hmac_sha256.Write(data.data(), data.size());
+ (void)hmac_sha512.Write(data.data(), data.size());
+ (void)ripemd160.Write(data.data(), data.size());
+ (void)sha1.Write(data.data(), data.size());
+ (void)sha256.Write(data.data(), data.size());
+ (void)sha512.Write(data.data(), data.size());
+ (void)sip_hasher.Write(data.data(), data.size());
+
+ (void)Hash(data.begin(), data.end());
+ (void)Hash160(data);
+ (void)Hash160(data.begin(), data.end());
+ (void)sha512.Size();
+ break;
+ }
+ case 1: {
+ (void)hash160.Reset();
+ (void)hash256.Reset();
+ (void)ripemd160.Reset();
+ (void)sha1.Reset();
+ (void)sha256.Reset();
+ (void)sha512.Reset();
+ break;
+ }
+ case 2: {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 8)) {
+ case 0: {
+ data.resize(CHash160::OUTPUT_SIZE);
+ hash160.Finalize(data.data());
+ break;
+ }
+ case 1: {
+ data.resize(CHash256::OUTPUT_SIZE);
+ hash256.Finalize(data.data());
+ break;
+ }
+ case 2: {
+ data.resize(CHMAC_SHA256::OUTPUT_SIZE);
+ hmac_sha256.Finalize(data.data());
+ break;
+ }
+ case 3: {
+ data.resize(CHMAC_SHA512::OUTPUT_SIZE);
+ hmac_sha512.Finalize(data.data());
+ break;
+ }
+ case 4: {
+ data.resize(CRIPEMD160::OUTPUT_SIZE);
+ ripemd160.Finalize(data.data());
+ break;
+ }
+ case 5: {
+ data.resize(CSHA1::OUTPUT_SIZE);
+ sha1.Finalize(data.data());
+ break;
+ }
+ case 6: {
+ data.resize(CSHA256::OUTPUT_SIZE);
+ sha256.Finalize(data.data());
+ break;
+ }
+ case 7: {
+ data.resize(CSHA512::OUTPUT_SIZE);
+ sha512.Finalize(data.data());
+ break;
+ }
+ case 8: {
+ data.resize(1);
+ data[0] = sip_hasher.Finalize() % 256;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/src/test/fuzz/crypto_aes256.cpp b/src/test/fuzz/crypto_aes256.cpp
new file mode 100644
index 0000000000..ae14073c96
--- /dev/null
+++ b/src/test/fuzz/crypto_aes256.cpp
@@ -0,0 +1,30 @@
+// 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 <crypto/aes.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE);
+
+ AES256Encrypt encrypt{key.data()};
+ AES256Decrypt decrypt{key.data()};
+
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::vector<uint8_t> plaintext = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES_BLOCKSIZE);
+ std::vector<uint8_t> ciphertext(AES_BLOCKSIZE);
+ encrypt.Encrypt(ciphertext.data(), plaintext.data());
+ std::vector<uint8_t> decrypted_plaintext(AES_BLOCKSIZE);
+ decrypt.Decrypt(decrypted_plaintext.data(), ciphertext.data());
+ assert(decrypted_plaintext == plaintext);
+ }
+}
diff --git a/src/test/fuzz/crypto_aes256cbc.cpp b/src/test/fuzz/crypto_aes256cbc.cpp
new file mode 100644
index 0000000000..52983c7e79
--- /dev/null
+++ b/src/test/fuzz/crypto_aes256cbc.cpp
@@ -0,0 +1,34 @@
+// 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 <crypto/aes.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES256_KEYSIZE);
+ const std::vector<uint8_t> iv = ConsumeFixedLengthByteVector(fuzzed_data_provider, AES_BLOCKSIZE);
+ const bool pad = fuzzed_data_provider.ConsumeBool();
+
+ AES256CBCEncrypt encrypt{key.data(), iv.data(), pad};
+ AES256CBCDecrypt decrypt{key.data(), iv.data(), pad};
+
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::vector<uint8_t> plaintext = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ std::vector<uint8_t> ciphertext(plaintext.size() + AES_BLOCKSIZE);
+ const int encrypt_ret = encrypt.Encrypt(plaintext.data(), plaintext.size(), ciphertext.data());
+ ciphertext.resize(encrypt_ret);
+ std::vector<uint8_t> decrypted_plaintext(ciphertext.size());
+ const int decrypt_ret = decrypt.Decrypt(ciphertext.data(), ciphertext.size(), decrypted_plaintext.data());
+ decrypted_plaintext.resize(decrypt_ret);
+ assert(decrypted_plaintext == plaintext || (!pad && plaintext.size() % AES_BLOCKSIZE != 0 && encrypt_ret == 0 && decrypt_ret == 0));
+ }
+}
diff --git a/src/test/fuzz/crypto_chacha20.cpp b/src/test/fuzz/crypto_chacha20.cpp
new file mode 100644
index 0000000000..b7438d312d
--- /dev/null
+++ b/src/test/fuzz/crypto_chacha20.cpp
@@ -0,0 +1,50 @@
+// 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 <crypto/chacha20.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+
+ ChaCha20 chacha20;
+ if (fuzzed_data_provider.ConsumeBool()) {
+ const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, fuzzed_data_provider.ConsumeIntegralInRange<size_t>(16, 32));
+ chacha20 = ChaCha20{key.data(), key.size()};
+ }
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 4)) {
+ case 0: {
+ const std::vector<unsigned char> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, fuzzed_data_provider.ConsumeIntegralInRange<size_t>(16, 32));
+ chacha20.SetKey(key.data(), key.size());
+ break;
+ }
+ case 1: {
+ chacha20.SetIV(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ break;
+ }
+ case 2: {
+ chacha20.Seek(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ break;
+ }
+ case 3: {
+ std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ chacha20.Keystream(output.data(), output.size());
+ break;
+ }
+ case 4: {
+ std::vector<uint8_t> output(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ const std::vector<uint8_t> input = ConsumeFixedLengthByteVector(fuzzed_data_provider, output.size());
+ chacha20.Crypt(input.data(), output.data(), input.size());
+ break;
+ }
+ }
+ }
+}
diff --git a/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp b/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp
new file mode 100644
index 0000000000..48e4263f27
--- /dev/null
+++ b/src/test/fuzz/crypto_chacha20_poly1305_aead.cpp
@@ -0,0 +1,72 @@
+// 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 <crypto/chacha_poly_aead.h>
+#include <crypto/poly1305.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cassert>
+#include <cstdint>
+#include <limits>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+
+ const std::vector<uint8_t> k1 = ConsumeFixedLengthByteVector(fuzzed_data_provider, CHACHA20_POLY1305_AEAD_KEY_LEN);
+ const std::vector<uint8_t> k2 = ConsumeFixedLengthByteVector(fuzzed_data_provider, CHACHA20_POLY1305_AEAD_KEY_LEN);
+
+ ChaCha20Poly1305AEAD aead(k1.data(), k1.size(), k2.data(), k2.size());
+ uint64_t seqnr_payload = 0;
+ uint64_t seqnr_aad = 0;
+ int aad_pos = 0;
+ size_t buffer_size = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096);
+ std::vector<uint8_t> in(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
+ std::vector<uint8_t> out(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
+ bool is_encrypt = fuzzed_data_provider.ConsumeBool();
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 6)) {
+ case 0: {
+ buffer_size = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(64, 4096);
+ in = std::vector<uint8_t>(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
+ out = std::vector<uint8_t>(buffer_size + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0);
+ break;
+ }
+ case 1: {
+ (void)aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, out.data(), out.size(), in.data(), buffer_size, is_encrypt);
+ break;
+ }
+ case 2: {
+ uint32_t len = 0;
+ const bool ok = aead.GetLength(&len, seqnr_aad, aad_pos, in.data());
+ assert(ok);
+ break;
+ }
+ case 3: {
+ seqnr_payload += 1;
+ aad_pos += CHACHA20_POLY1305_AEAD_AAD_LEN;
+ if (aad_pos + CHACHA20_POLY1305_AEAD_AAD_LEN > CHACHA20_ROUND_OUTPUT) {
+ aad_pos = 0;
+ seqnr_aad += 1;
+ }
+ break;
+ }
+ case 4: {
+ seqnr_payload = fuzzed_data_provider.ConsumeIntegral<int>();
+ break;
+ }
+ case 5: {
+ seqnr_aad = fuzzed_data_provider.ConsumeIntegral<int>();
+ break;
+ }
+ case 6: {
+ is_encrypt = fuzzed_data_provider.ConsumeBool();
+ break;
+ }
+ }
+ }
+}
diff --git a/src/test/fuzz/crypto_common.cpp b/src/test/fuzz/crypto_common.cpp
new file mode 100644
index 0000000000..7ccb125216
--- /dev/null
+++ b/src/test/fuzz/crypto_common.cpp
@@ -0,0 +1,70 @@
+// 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 <crypto/common.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <array>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ const uint16_t random_u16 = fuzzed_data_provider.ConsumeIntegral<uint16_t>();
+ const uint32_t random_u32 = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
+ const uint64_t random_u64 = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
+ const std::vector<uint8_t> random_bytes_2 = ConsumeFixedLengthByteVector(fuzzed_data_provider, 2);
+ const std::vector<uint8_t> random_bytes_4 = ConsumeFixedLengthByteVector(fuzzed_data_provider, 4);
+ const std::vector<uint8_t> random_bytes_8 = ConsumeFixedLengthByteVector(fuzzed_data_provider, 8);
+
+ std::array<uint8_t, 2> writele16_arr;
+ WriteLE16(writele16_arr.data(), random_u16);
+ assert(ReadLE16(writele16_arr.data()) == random_u16);
+
+ std::array<uint8_t, 4> writele32_arr;
+ WriteLE32(writele32_arr.data(), random_u32);
+ assert(ReadLE32(writele32_arr.data()) == random_u32);
+
+ std::array<uint8_t, 8> writele64_arr;
+ WriteLE64(writele64_arr.data(), random_u64);
+ assert(ReadLE64(writele64_arr.data()) == random_u64);
+
+ std::array<uint8_t, 4> writebe32_arr;
+ WriteBE32(writebe32_arr.data(), random_u32);
+ assert(ReadBE32(writebe32_arr.data()) == random_u32);
+
+ std::array<uint8_t, 8> writebe64_arr;
+ WriteBE64(writebe64_arr.data(), random_u64);
+ assert(ReadBE64(writebe64_arr.data()) == random_u64);
+
+ const uint16_t readle16_result = ReadLE16(random_bytes_2.data());
+ std::array<uint8_t, 2> readle16_arr;
+ WriteLE16(readle16_arr.data(), readle16_result);
+ assert(std::memcmp(random_bytes_2.data(), readle16_arr.data(), 2) == 0);
+
+ const uint32_t readle32_result = ReadLE32(random_bytes_4.data());
+ std::array<uint8_t, 4> readle32_arr;
+ WriteLE32(readle32_arr.data(), readle32_result);
+ assert(std::memcmp(random_bytes_4.data(), readle32_arr.data(), 4) == 0);
+
+ const uint64_t readle64_result = ReadLE64(random_bytes_8.data());
+ std::array<uint8_t, 8> readle64_arr;
+ WriteLE64(readle64_arr.data(), readle64_result);
+ assert(std::memcmp(random_bytes_8.data(), readle64_arr.data(), 8) == 0);
+
+ const uint32_t readbe32_result = ReadBE32(random_bytes_4.data());
+ std::array<uint8_t, 4> readbe32_arr;
+ WriteBE32(readbe32_arr.data(), readbe32_result);
+ assert(std::memcmp(random_bytes_4.data(), readbe32_arr.data(), 4) == 0);
+
+ const uint64_t readbe64_result = ReadBE64(random_bytes_8.data());
+ std::array<uint8_t, 8> readbe64_arr;
+ WriteBE64(readbe64_arr.data(), readbe64_result);
+ assert(std::memcmp(random_bytes_8.data(), readbe64_arr.data(), 8) == 0);
+}
diff --git a/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp b/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp
new file mode 100644
index 0000000000..e0a4e90c10
--- /dev/null
+++ b/src/test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp
@@ -0,0 +1,25 @@
+// 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 <crypto/hkdf_sha256_32.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+
+ const std::vector<uint8_t> initial_key_material = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+
+ CHKDF_HMAC_SHA256_L32 hkdf_hmac_sha256_l32(initial_key_material.data(), initial_key_material.size(), fuzzed_data_provider.ConsumeRandomLengthString(1024));
+ while (fuzzed_data_provider.ConsumeBool()) {
+ std::vector<uint8_t> out(32);
+ hkdf_hmac_sha256_l32.Expand32(fuzzed_data_provider.ConsumeRandomLengthString(128), out.data());
+ }
+}
diff --git a/src/test/fuzz/crypto_poly1305.cpp b/src/test/fuzz/crypto_poly1305.cpp
new file mode 100644
index 0000000000..5681e6a693
--- /dev/null
+++ b/src/test/fuzz/crypto_poly1305.cpp
@@ -0,0 +1,22 @@
+// 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 <crypto/poly1305.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+
+ const std::vector<uint8_t> key = ConsumeFixedLengthByteVector(fuzzed_data_provider, POLY1305_KEYLEN);
+ const std::vector<uint8_t> in = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+
+ std::vector<uint8_t> tag_out(POLY1305_TAGLEN);
+ poly1305_auth(tag_out.data(), in.data(), in.size(), key.data());
+}
diff --git a/src/test/fuzz/decode_tx.cpp b/src/test/fuzz/decode_tx.cpp
index 09c4ff05df..0d89d4228a 100644
--- a/src/test/fuzz/decode_tx.cpp
+++ b/src/test/fuzz/decode_tx.cpp
@@ -14,7 +14,7 @@
void test_one_input(const std::vector<uint8_t>& buffer)
{
- const std::string tx_hex = HexStr(std::string{buffer.begin(), buffer.end()});
+ const std::string tx_hex = HexStr(buffer);
CMutableTransaction mtx;
const bool result_none = DecodeHexTx(mtx, tx_hex, false, false);
const bool result_try_witness = DecodeHexTx(mtx, tx_hex, false, true);
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 82e1d55c0b..1e1807d734 100644
--- a/src/test/fuzz/fuzz.cpp
+++ b/src/test/fuzz/fuzz.cpp
@@ -12,7 +12,16 @@
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
-#if defined(__AFL_COMPILER)
+// Decide if main(...) should be provided:
+// * AFL needs main(...) regardless of platform.
+// * macOS handles __attribute__((weak)) main(...) poorly when linking
+// against libFuzzer. See https://github.com/bitcoin/bitcoin/pull/18008
+// for details.
+#if defined(__AFL_COMPILER) || !defined(MAC_OSX)
+#define PROVIDE_MAIN_FUNCTION
+#endif
+
+#if defined(PROVIDE_MAIN_FUNCTION)
static bool read_stdin(std::vector<uint8_t>& data)
{
uint8_t buffer[1024];
@@ -44,9 +53,8 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
return 0;
}
-// Generally, the fuzzer will provide main(), except for AFL
-#if defined(__AFL_COMPILER)
-int main(int argc, char** argv)
+#if defined(PROVIDE_MAIN_FUNCTION)
+__attribute__((weak)) int main(int argc, char** argv)
{
initialize();
#ifdef __AFL_INIT
diff --git a/src/test/fuzz/http_request.cpp b/src/test/fuzz/http_request.cpp
index ebf89749e9..36d44e361f 100644
--- a/src/test/fuzz/http_request.cpp
+++ b/src/test/fuzz/http_request.cpp
@@ -7,6 +7,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
+#include <util/strencodings.h>
#include <event2/buffer.h>
#include <event2/event.h>
@@ -48,7 +49,14 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(evbuf != nullptr);
const std::vector<uint8_t> http_buffer = ConsumeRandomLengthByteVector(fuzzed_data_provider, 4096);
evbuffer_add(evbuf, http_buffer.data(), http_buffer.size());
- if (evhttp_parse_firstline_(evreq, evbuf) != 1 || evhttp_parse_headers_(evreq, evbuf) != 1) {
+ // Avoid constructing requests that will be interpreted by libevent as PROXY requests to avoid triggering
+ // a nullptr dereference. The dereference (req->evcon->http_server) takes place in evhttp_parse_request_line
+ // and is a consequence of our hacky but necessary use of the internal function evhttp_parse_firstline_ in
+ // this fuzzing harness. The workaround is not aesthetically pleasing, but it successfully avoids the troublesome
+ // code path. " http:// HTTP/1.1\n" was a crashing input prior to this workaround.
+ const std::string http_buffer_str = ToLower({http_buffer.begin(), http_buffer.end()});
+ if (http_buffer_str.find(" http://") != std::string::npos || http_buffer_str.find(" https://") != std::string::npos ||
+ evhttp_parse_firstline_(evreq, evbuf) != 1 || evhttp_parse_headers_(evreq, evbuf) != 1) {
evbuffer_free(evbuf);
evhttp_request_free(evreq);
return;
diff --git a/src/test/fuzz/key.cpp b/src/test/fuzz/key.cpp
index 1919a5f881..c746374c61 100644
--- a/src/test/fuzz/key.cpp
+++ b/src/test/fuzz/key.cpp
@@ -108,7 +108,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(pubkey.IsCompressed());
assert(pubkey.IsValid());
assert(pubkey.IsFullyValid());
- assert(HexToPubKey(HexStr(pubkey.begin(), pubkey.end())) == pubkey);
+ assert(HexToPubKey(HexStr(pubkey)) == pubkey);
assert(GetAllDestinationsForKey(pubkey).size() == 3);
}
@@ -157,25 +157,25 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(ok_add_key_pubkey);
assert(fillable_signing_provider_pub.HaveKey(pubkey.GetID()));
- txnouttype which_type_tx_pubkey;
+ TxoutType which_type_tx_pubkey;
const bool is_standard_tx_pubkey = IsStandard(tx_pubkey_script, which_type_tx_pubkey);
assert(is_standard_tx_pubkey);
- assert(which_type_tx_pubkey == txnouttype::TX_PUBKEY);
+ assert(which_type_tx_pubkey == TxoutType::PUBKEY);
- txnouttype which_type_tx_multisig;
+ TxoutType which_type_tx_multisig;
const bool is_standard_tx_multisig = IsStandard(tx_multisig_script, which_type_tx_multisig);
assert(is_standard_tx_multisig);
- assert(which_type_tx_multisig == txnouttype::TX_MULTISIG);
+ assert(which_type_tx_multisig == TxoutType::MULTISIG);
std::vector<std::vector<unsigned char>> v_solutions_ret_tx_pubkey;
- const txnouttype outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);
- assert(outtype_tx_pubkey == txnouttype::TX_PUBKEY);
+ const TxoutType outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);
+ assert(outtype_tx_pubkey == TxoutType::PUBKEY);
assert(v_solutions_ret_tx_pubkey.size() == 1);
assert(v_solutions_ret_tx_pubkey[0].size() == 33);
std::vector<std::vector<unsigned char>> v_solutions_ret_tx_multisig;
- const txnouttype outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);
- assert(outtype_tx_multisig == txnouttype::TX_MULTISIG);
+ const TxoutType outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);
+ assert(outtype_tx_multisig == TxoutType::MULTISIG);
assert(v_solutions_ret_tx_multisig.size() == 3);
assert(v_solutions_ret_tx_multisig[0].size() == 1);
assert(v_solutions_ret_tx_multisig[1].size() == 33);
diff --git a/src/test/fuzz/kitchen_sink.cpp b/src/test/fuzz/kitchen_sink.cpp
index af6dc71322..82cbc00a3a 100644
--- a/src/test/fuzz/kitchen_sink.cpp
+++ b/src/test/fuzz/kitchen_sink.cpp
@@ -7,6 +7,7 @@
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <util/error.h>
+#include <util/translation.h>
#include <cstdint>
#include <vector>
diff --git a/src/test/fuzz/load_external_block_file.cpp b/src/test/fuzz/load_external_block_file.cpp
new file mode 100644
index 0000000000..d9de9d9866
--- /dev/null
+++ b/src/test/fuzz/load_external_block_file.cpp
@@ -0,0 +1,31 @@
+// 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 <chainparams.h>
+#include <flatfile.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <test/util/setup_common.h>
+#include <validation.h>
+
+#include <cstdint>
+#include <vector>
+
+void initialize()
+{
+ InitializeFuzzingContext();
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
+ FuzzedFileProvider fuzzed_file_provider = ConsumeFile(fuzzed_data_provider);
+ FILE* fuzzed_block_file = fuzzed_file_provider.open();
+ if (fuzzed_block_file == nullptr) {
+ return;
+ }
+ FlatFilePos flat_file_pos;
+ LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
+}
diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp
index c071283467..ae531f4462 100644
--- a/src/test/fuzz/net_permissions.cpp
+++ b/src/test/fuzz/net_permissions.cpp
@@ -6,6 +6,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
+#include <util/translation.h>
#include <cassert>
#include <cstdint>
@@ -29,7 +30,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
static_cast<NetPermissionFlags>(fuzzed_data_provider.ConsumeIntegral<uint32_t>());
NetWhitebindPermissions net_whitebind_permissions;
- std::string error_net_whitebind_permissions;
+ bilingual_str error_net_whitebind_permissions;
if (NetWhitebindPermissions::TryParse(s, net_whitebind_permissions, error_net_whitebind_permissions)) {
(void)NetPermissions::ToStrings(net_whitebind_permissions.m_flags);
(void)NetPermissions::AddFlag(net_whitebind_permissions.m_flags, net_permission_flags);
@@ -39,7 +40,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
NetWhitelistPermissions net_whitelist_permissions;
- std::string error_net_whitelist_permissions;
+ bilingual_str error_net_whitelist_permissions;
if (NetWhitelistPermissions::TryParse(s, net_whitelist_permissions, error_net_whitelist_permissions)) {
(void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags);
(void)NetPermissions::AddFlag(net_whitelist_permissions.m_flags, net_permission_flags);
diff --git a/src/test/fuzz/netaddress.cpp b/src/test/fuzz/netaddress.cpp
index d8d53566c7..2901c704f6 100644
--- a/src/test/fuzz/netaddress.cpp
+++ b/src/test/fuzz/netaddress.cpp
@@ -5,41 +5,13 @@
#include <netaddress.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
#include <cassert>
#include <cstdint>
#include <netinet/in.h>
#include <vector>
-namespace {
-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});
- if (network == Network::NET_IPV4) {
- const in_addr v4_addr = {
- .s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
- return CNetAddr{v4_addr};
- } else if (network == Network::NET_IPV6) {
- if (fuzzed_data_provider.remaining_bytes() < 16) {
- return CNetAddr{};
- }
- in6_addr v6_addr = {};
- memcpy(v6_addr.s6_addr, fuzzed_data_provider.ConsumeBytes<uint8_t>(16).data(), 16);
- return CNetAddr{v6_addr, fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
- } else if (network == Network::NET_INTERNAL) {
- CNetAddr net_addr;
- net_addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32));
- return net_addr;
- } else if (network == Network::NET_ONION) {
- CNetAddr net_addr;
- net_addr.SetSpecial(fuzzed_data_provider.ConsumeBytesAsString(32));
- return net_addr;
- } else {
- assert(false);
- }
-}
-}; // namespace
-
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
diff --git a/src/test/fuzz/p2p_transport_deserializer.cpp b/src/test/fuzz/p2p_transport_deserializer.cpp
index 57393fed45..6fba2bfaba 100644
--- a/src/test/fuzz/p2p_transport_deserializer.cpp
+++ b/src/test/fuzz/p2p_transport_deserializer.cpp
@@ -30,7 +30,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
pch += handled;
n_bytes -= handled;
if (deserializer.Complete()) {
- const int64_t m_time = std::numeric_limits<int64_t>::max();
+ const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()};
const CNetMessage msg = deserializer.GetMessage(Params().MessageStart(), m_time);
assert(msg.m_command.size() <= CMessageHeader::COMMAND_SIZE);
assert(msg.m_raw_message_size <= buffer.size());
diff --git a/src/test/fuzz/policy_estimator.cpp b/src/test/fuzz/policy_estimator.cpp
index 1cbf9b347f..6c94a47f3c 100644
--- a/src/test/fuzz/policy_estimator.cpp
+++ b/src/test/fuzz/policy_estimator.cpp
@@ -14,6 +14,11 @@
#include <string>
#include <vector>
+void initialize()
+{
+ InitializeFuzzingContext();
+}
+
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
@@ -66,4 +71,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)block_policy_estimator.estimateSmartFee(fuzzed_data_provider.ConsumeIntegral<int>(), fuzzed_data_provider.ConsumeBool() ? &fee_calculation : nullptr, fuzzed_data_provider.ConsumeBool());
(void)block_policy_estimator.HighestTargetTracked(fuzzed_data_provider.PickValueInArray({FeeEstimateHorizon::SHORT_HALFLIFE, FeeEstimateHorizon::MED_HALFLIFE, FeeEstimateHorizon::LONG_HALFLIFE}));
}
+ {
+ FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
+ CAutoFile fuzzed_auto_file = fuzzed_auto_file_provider.open();
+ block_policy_estimator.Write(fuzzed_auto_file);
+ block_policy_estimator.Read(fuzzed_auto_file);
+ }
}
diff --git a/src/test/fuzz/policy_estimator_io.cpp b/src/test/fuzz/policy_estimator_io.cpp
new file mode 100644
index 0000000000..0edcf201c7
--- /dev/null
+++ b/src/test/fuzz/policy_estimator_io.cpp
@@ -0,0 +1,28 @@
+// 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 <policy/fees.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <vector>
+
+void initialize()
+{
+ InitializeFuzzingContext();
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ FuzzedAutoFileProvider fuzzed_auto_file_provider = ConsumeAutoFile(fuzzed_data_provider);
+ CAutoFile fuzzed_auto_file = fuzzed_auto_file_provider.open();
+ // Re-using block_policy_estimator across runs to avoid costly creation of CBlockPolicyEstimator object.
+ static CBlockPolicyEstimator block_policy_estimator;
+ if (block_policy_estimator.Read(fuzzed_auto_file)) {
+ block_policy_estimator.Write(fuzzed_auto_file);
+ }
+}
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp
index 665a6224b4..9e40d5cd55 100644
--- a/src/test/fuzz/process_message.cpp
+++ b/src/test/fuzz/process_message.cpp
@@ -14,6 +14,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/util/mining.h>
+#include <test/util/net.h>
#include <test/util/setup_common.h>
#include <util/memory.h>
#include <validationinterface.h>
@@ -29,7 +30,17 @@
#include <string>
#include <vector>
-bool ProcessMessage(CNode* pfrom, const std::string& msg_type, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, ChainstateManager& chainman, CTxMemPool& mempool, CConnman* connman, BanMan* banman, const std::atomic<bool>& interruptMsgProc);
+void ProcessMessage(
+ CNode& pfrom,
+ const std::string& msg_type,
+ CDataStream& vRecv,
+ const std::chrono::microseconds time_received,
+ const CChainParams& chainparams,
+ ChainstateManager& chainman,
+ CTxMemPool& mempool,
+ CConnman& connman,
+ BanMan* banman,
+ const std::atomic<bool>& interruptMsgProc);
namespace {
@@ -63,19 +74,26 @@ void initialize()
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get();
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) {
return;
}
CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION};
- CNode p2p_node{0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, false};
+ CNode& p2p_node = *MakeUnique<CNode>(0, ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BLOOM), 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, false).release();
p2p_node.fSuccessfullyConnected = true;
p2p_node.nVersion = PROTOCOL_VERSION;
p2p_node.SetSendVersion(PROTOCOL_VERSION);
+ connman.AddTestNode(p2p_node);
g_setup->m_node.peer_logic->InitializeNode(&p2p_node);
try {
- (void)ProcessMessage(&p2p_node, random_message_type, random_bytes_data_stream, GetTimeMillis(), Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool, g_setup->m_node.connman.get(), g_setup->m_node.banman.get(), std::atomic<bool>{false});
+ ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream, GetTime<std::chrono::microseconds>(),
+ Params(), *g_setup->m_node.chainman, *g_setup->m_node.mempool,
+ *g_setup->m_node.connman, g_setup->m_node.banman.get(),
+ std::atomic<bool>{false});
} catch (const std::ios_base::failure&) {
}
SyncWithValidationInterfaceQueue();
+ LOCK2(::cs_main, g_cs_orphans); // See init.cpp for rationale for implicit locking order requirement
+ g_setup->m_node.connman->StopNodes();
}
diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp
index bcbf65bdca..91ebf9fb1b 100644
--- a/src/test/fuzz/process_messages.cpp
+++ b/src/test/fuzz/process_messages.cpp
@@ -62,7 +62,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
CSerializedNetMsg net_msg;
- net_msg.command = random_message_type;
+ net_msg.m_type = random_message_type;
net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
CNode& random_node = *peers.at(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, peers.size() - 1));
@@ -75,6 +75,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
} catch (const std::ios_base::failure&) {
}
}
- connman.ClearTestNodes();
SyncWithValidationInterfaceQueue();
+ LOCK2(::cs_main, g_cs_orphans); // See init.cpp for rationale for implicit locking order requirement
+ g_setup->m_node.connman->StopNodes();
}
diff --git a/src/test/fuzz/psbt.cpp b/src/test/fuzz/psbt.cpp
index 64328fb66e..908e2b16f2 100644
--- a/src/test/fuzz/psbt.cpp
+++ b/src/test/fuzz/psbt.cpp
@@ -39,7 +39,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
(void)psbt.IsNull();
- (void)psbt.IsSane();
Optional<CMutableTransaction> tx = psbt.tx;
if (tx) {
@@ -50,7 +49,6 @@ void test_one_input(const std::vector<uint8_t>& buffer)
for (const PSBTInput& input : psbt.inputs) {
(void)PSBTInputSigned(input);
(void)input.IsNull();
- (void)input.IsSane();
}
for (const PSBTOutput& output : psbt.outputs) {
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp
index e0c4ad7eb7..85aac6ac7a 100644
--- a/src/test/fuzz/script.cpp
+++ b/src/test/fuzz/script.cpp
@@ -11,6 +11,7 @@
#include <script/descriptor.h>
#include <script/interpreter.h>
#include <script/script.h>
+#include <script/script_error.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
@@ -21,6 +22,8 @@
#include <univalue.h>
#include <util/memory.h>
+#include <algorithm>
+#include <cassert>
#include <cstdint>
#include <optional>
#include <string>
@@ -45,7 +48,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
if (CompressScript(script, compressed)) {
const unsigned int size = compressed[0];
compressed.erase(compressed.begin());
- assert(size >= 0 && size <= 5);
+ assert(size <= 5);
CScript decompressed_script;
const bool ok = DecompressScript(decompressed_script, size, compressed);
assert(ok);
@@ -55,7 +58,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CTxDestination address;
(void)ExtractDestination(script, address);
- txnouttype type_ret;
+ TxoutType type_ret;
std::vector<CTxDestination> addresses;
int required_ret;
(void)ExtractDestinations(script, type_ret, addresses, required_ret);
@@ -69,7 +72,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)IsSolvable(signing_provider, script);
- txnouttype which_type;
+ TxoutType which_type;
(void)IsStandard(script, which_type);
(void)RecursiveDynamicUsage(script);
@@ -124,4 +127,40 @@ void test_one_input(const std::vector<uint8_t>& buffer)
wit.SetNull();
}
}
+
+ (void)GetOpName(ConsumeOpcodeType(fuzzed_data_provider));
+ (void)ScriptErrorString(static_cast<ScriptError>(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, SCRIPT_ERR_ERROR_COUNT)));
+
+ {
+ const std::vector<uint8_t> bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ CScript append_script{bytes.begin(), bytes.end()};
+ append_script << fuzzed_data_provider.ConsumeIntegral<int64_t>();
+ append_script << ConsumeOpcodeType(fuzzed_data_provider);
+ append_script << CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
+ append_script << ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ }
+
+ {
+ WitnessUnknown witness_unknown_1{};
+ witness_unknown_1.version = fuzzed_data_provider.ConsumeIntegral<int>();
+ 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<int>();
+ 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 = 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);
+ }
}
diff --git a/src/test/fuzz/script_bitcoin_consensus.cpp b/src/test/fuzz/script_bitcoin_consensus.cpp
new file mode 100644
index 0000000000..22f4b4f44a
--- /dev/null
+++ b/src/test/fuzz/script_bitcoin_consensus.cpp
@@ -0,0 +1,31 @@
+// 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 <script/bitcoinconsensus.h>
+#include <script/interpreter.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ const std::vector<uint8_t> random_bytes_1 = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ const std::vector<uint8_t> random_bytes_2 = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ const CAmount money = ConsumeMoney(fuzzed_data_provider);
+ bitcoinconsensus_error err;
+ bitcoinconsensus_error* err_p = fuzzed_data_provider.ConsumeBool() ? &err : nullptr;
+ const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ assert(bitcoinconsensus_version() == BITCOINCONSENSUS_API_VER);
+ if ((flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
+ return;
+ }
+ (void)bitcoinconsensus_verify_script(random_bytes_1.data(), random_bytes_1.size(), random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p);
+ (void)bitcoinconsensus_verify_script_with_amount(random_bytes_1.data(), random_bytes_1.size(), money, random_bytes_2.data(), random_bytes_2.size(), n_in, flags, err_p);
+}
diff --git a/src/test/fuzz/script_descriptor_cache.cpp b/src/test/fuzz/script_descriptor_cache.cpp
new file mode 100644
index 0000000000..4bfe61cec7
--- /dev/null
+++ b/src/test/fuzz/script_descriptor_cache.cpp
@@ -0,0 +1,42 @@
+// 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 <optional.h>
+#include <pubkey.h>
+#include <script/descriptor.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ DescriptorCache descriptor_cache;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::vector<uint8_t> code = fuzzed_data_provider.ConsumeBytes<uint8_t>(BIP32_EXTKEY_SIZE);
+ if (code.size() == BIP32_EXTKEY_SIZE) {
+ CExtPubKey xpub;
+ xpub.Decode(code.data());
+ const uint32_t key_exp_pos = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
+ CExtPubKey xpub_fetched;
+ if (fuzzed_data_provider.ConsumeBool()) {
+ (void)descriptor_cache.GetCachedParentExtPubKey(key_exp_pos, xpub_fetched);
+ descriptor_cache.CacheParentExtPubKey(key_exp_pos, xpub);
+ assert(descriptor_cache.GetCachedParentExtPubKey(key_exp_pos, xpub_fetched));
+ } else {
+ const uint32_t der_index = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
+ (void)descriptor_cache.GetCachedDerivedExtPubKey(key_exp_pos, der_index, xpub_fetched);
+ descriptor_cache.CacheDerivedExtPubKey(key_exp_pos, der_index, xpub);
+ assert(descriptor_cache.GetCachedDerivedExtPubKey(key_exp_pos, der_index, xpub_fetched));
+ }
+ assert(xpub == xpub_fetched);
+ }
+ (void)descriptor_cache.GetCachedParentExtPubKeys();
+ (void)descriptor_cache.GetCachedDerivedExtPubKeys();
+ }
+}
diff --git a/src/test/fuzz/script_interpreter.cpp b/src/test/fuzz/script_interpreter.cpp
new file mode 100644
index 0000000000..26d5732f24
--- /dev/null
+++ b/src/test/fuzz/script_interpreter.cpp
@@ -0,0 +1,41 @@
+// 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 <primitives/transaction.h>
+#include <script/interpreter.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <optional>
+#include <string>
+#include <vector>
+
+bool CastToBool(const std::vector<unsigned char>& vch);
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ {
+ const CScript script_code = ConsumeScript(fuzzed_data_provider);
+ const std::optional<CMutableTransaction> mtx = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (mtx) {
+ const CTransaction tx_to{*mtx};
+ const unsigned int in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ if (in < tx_to.vin.size()) {
+ (void)SignatureHash(script_code, tx_to, in, fuzzed_data_provider.ConsumeIntegral<int>(), ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0}), nullptr);
+ const std::optional<CMutableTransaction> mtx_precomputed = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (mtx_precomputed) {
+ const CTransaction tx_precomputed{*mtx_precomputed};
+ const PrecomputedTransactionData precomputed_transaction_data{tx_precomputed};
+ (void)SignatureHash(script_code, tx_to, in, fuzzed_data_provider.ConsumeIntegral<int>(), ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0}), &precomputed_transaction_data);
+ }
+ }
+ }
+ }
+ {
+ (void)CastToBool(ConsumeRandomLengthByteVector(fuzzed_data_provider));
+ }
+}
diff --git a/src/test/fuzz/script_sigcache.cpp b/src/test/fuzz/script_sigcache.cpp
new file mode 100644
index 0000000000..434a47b702
--- /dev/null
+++ b/src/test/fuzz/script_sigcache.cpp
@@ -0,0 +1,45 @@
+// 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 <chainparams.h>
+#include <chainparamsbase.h>
+#include <key.h>
+#include <pubkey.h>
+#include <script/sigcache.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cstdint>
+#include <optional>
+#include <string>
+#include <vector>
+
+void initialize()
+{
+ static const ECCVerifyHandle ecc_verify_handle;
+ ECC_Start();
+ SelectParams(CBaseChainParams::REGTEST);
+ InitSignatureCache();
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
+ const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ const CTransaction tx = mutable_transaction ? CTransaction{*mutable_transaction} : CTransaction{};
+ const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ const CAmount amount = ConsumeMoney(fuzzed_data_provider);
+ const bool store = fuzzed_data_provider.ConsumeBool();
+ PrecomputedTransactionData tx_data;
+ CachingTransactionSignatureChecker caching_transaction_signature_checker{mutable_transaction ? &tx : nullptr, n_in, amount, store, tx_data};
+ const std::optional<CPubKey> pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider);
+ if (pub_key) {
+ const std::vector<uint8_t> random_bytes = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ if (!random_bytes.empty()) {
+ (void)caching_transaction_signature_checker.VerifySignature(random_bytes, *pub_key, ConsumeUInt256(fuzzed_data_provider));
+ }
+ }
+}
diff --git a/src/test/fuzz/script_sign.cpp b/src/test/fuzz/script_sign.cpp
new file mode 100644
index 0000000000..c626f950e7
--- /dev/null
+++ b/src/test/fuzz/script_sign.cpp
@@ -0,0 +1,149 @@
+// 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 <chainparams.h>
+#include <chainparamsbase.h>
+#include <key.h>
+#include <pubkey.h>
+#include <script/keyorigin.h>
+#include <script/sign.h>
+#include <script/signingprovider.h>
+#include <streams.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+
+#include <cassert>
+#include <cstdint>
+#include <iostream>
+#include <map>
+#include <optional>
+#include <string>
+#include <vector>
+
+void initialize()
+{
+ static const ECCVerifyHandle ecc_verify_handle;
+ ECC_Start();
+ SelectParams(CBaseChainParams::REGTEST);
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+ const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128);
+
+ {
+ CDataStream random_data_stream = ConsumeDataStream(fuzzed_data_provider);
+ std::map<CPubKey, KeyOriginInfo> hd_keypaths;
+ try {
+ DeserializeHDKeypaths(random_data_stream, key, hd_keypaths);
+ } catch (const std::ios_base::failure&) {
+ }
+ CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION};
+ SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ }
+
+ {
+ std::map<CPubKey, KeyOriginInfo> hd_keypaths;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::optional<CPubKey> pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider);
+ if (!pub_key) {
+ break;
+ }
+ const std::optional<KeyOriginInfo> key_origin_info = ConsumeDeserializable<KeyOriginInfo>(fuzzed_data_provider);
+ if (!key_origin_info) {
+ break;
+ }
+ hd_keypaths[*pub_key] = *key_origin_info;
+ }
+ CDataStream serialized{SER_NETWORK, PROTOCOL_VERSION};
+ try {
+ SerializeHDKeypaths(serialized, hd_keypaths, fuzzed_data_provider.ConsumeIntegral<uint8_t>());
+ } catch (const std::ios_base::failure&) {
+ }
+ std::map<CPubKey, KeyOriginInfo> deserialized_hd_keypaths;
+ try {
+ DeserializeHDKeypaths(serialized, key, hd_keypaths);
+ } catch (const std::ios_base::failure&) {
+ }
+ assert(hd_keypaths.size() >= deserialized_hd_keypaths.size());
+ }
+
+ {
+ SignatureData signature_data_1{ConsumeScript(fuzzed_data_provider)};
+ SignatureData signature_data_2{ConsumeScript(fuzzed_data_provider)};
+ signature_data_1.MergeSignatureData(signature_data_2);
+ }
+
+ FillableSigningProvider provider;
+ CKey k;
+ const std::vector<uint8_t> key_data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ k.Set(key_data.begin(), key_data.end(), fuzzed_data_provider.ConsumeBool());
+ if (k.IsValid()) {
+ provider.AddKey(k);
+ }
+
+ {
+ const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ const std::optional<CTxOut> tx_out = ConsumeDeserializable<CTxOut>(fuzzed_data_provider);
+ const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
+ if (mutable_transaction && tx_out && mutable_transaction->vin.size() > n_in) {
+ SignatureData signature_data_1 = DataFromTransaction(*mutable_transaction, n_in, *tx_out);
+ CTxIn input;
+ UpdateInput(input, signature_data_1);
+ const CScript script = ConsumeScript(fuzzed_data_provider);
+ SignatureData signature_data_2{script};
+ signature_data_1.MergeSignatureData(signature_data_2);
+ }
+ if (mutable_transaction) {
+ CTransaction tx_from{*mutable_transaction};
+ CMutableTransaction tx_to;
+ const std::optional<CMutableTransaction> opt_tx_to = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider);
+ if (opt_tx_to) {
+ tx_to = *opt_tx_to;
+ }
+ CMutableTransaction script_tx_to = tx_to;
+ CMutableTransaction sign_transaction_tx_to = tx_to;
+ if (n_in < tx_to.vin.size() && tx_to.vin[n_in].prevout.n < tx_from.vout.size()) {
+ (void)SignSignature(provider, tx_from, tx_to, n_in, fuzzed_data_provider.ConsumeIntegral<int>());
+ }
+ if (n_in < script_tx_to.vin.size()) {
+ (void)SignSignature(provider, ConsumeScript(fuzzed_data_provider), script_tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>());
+ MutableTransactionSignatureCreator signature_creator{&tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()};
+ std::vector<unsigned char> vch_sig;
+ CKeyID address;
+ if (fuzzed_data_provider.ConsumeBool()) {
+ if (k.IsValid()) {
+ address = k.GetPubKey().GetID();
+ }
+ } else {
+ address = CKeyID{ConsumeUInt160(fuzzed_data_provider)};
+ }
+ (void)signature_creator.CreateSig(provider, vch_sig, address, ConsumeScript(fuzzed_data_provider), fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0}));
+ }
+ std::map<COutPoint, Coin> coins;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::optional<COutPoint> outpoint = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
+ if (!outpoint) {
+ break;
+ }
+ const std::optional<Coin> coin = ConsumeDeserializable<Coin>(fuzzed_data_provider);
+ if (!coin) {
+ break;
+ }
+ coins[*outpoint] = *coin;
+ }
+ std::map<int, std::string> input_errors;
+ (void)SignTransaction(sign_transaction_tx_to, &provider, coins, fuzzed_data_provider.ConsumeIntegral<int>(), input_errors);
+ }
+ }
+
+ {
+ SignatureData signature_data_1;
+ (void)ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_1);
+ SignatureData signature_data_2;
+ (void)ProduceSignature(provider, DUMMY_MAXIMUM_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_2);
+ }
+}
diff --git a/src/test/fuzz/scriptnum_ops.cpp b/src/test/fuzz/scriptnum_ops.cpp
index f4e079fb89..68c1ae58ca 100644
--- a/src/test/fuzz/scriptnum_ops.cpp
+++ b/src/test/fuzz/scriptnum_ops.cpp
@@ -33,7 +33,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
case 0: {
const int64_t i = fuzzed_data_provider.ConsumeIntegral<int64_t>();
assert((script_num == i) != (script_num != i));
- assert((script_num <= i) != script_num > i);
+ assert((script_num <= i) != (script_num > i));
assert((script_num >= i) != (script_num < i));
// Avoid signed integer overflow:
// script/script.h:264:93: runtime error: signed integer overflow: -2261405121394637306 + -9223372036854775802 cannot be represented in type 'long'
diff --git a/src/test/fuzz/signature_checker.cpp b/src/test/fuzz/signature_checker.cpp
index 4a8c7a63af..3aaeb66649 100644
--- a/src/test/fuzz/signature_checker.cpp
+++ b/src/test/fuzz/signature_checker.cpp
@@ -28,17 +28,17 @@ public:
{
}
- virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
+ bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override
{
return m_fuzzed_data_provider.ConsumeBool();
}
- virtual bool CheckLockTime(const CScriptNum& nLockTime) const
+ bool CheckLockTime(const CScriptNum& nLockTime) const override
{
return m_fuzzed_data_provider.ConsumeBool();
}
- virtual bool CheckSequence(const CScriptNum& nSequence) const
+ bool CheckSequence(const CScriptNum& nSequence) const override
{
return m_fuzzed_data_provider.ConsumeBool();
}
diff --git a/src/test/fuzz/span.cpp b/src/test/fuzz/span.cpp
index 4aea530ef2..f6b6e8f6f0 100644
--- a/src/test/fuzz/span.cpp
+++ b/src/test/fuzz/span.cpp
@@ -18,7 +18,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
std::string str = fuzzed_data_provider.ConsumeBytesAsString(32);
- const Span<const char> span = MakeSpan(str);
+ const Span<const char> span{str};
(void)span.data();
(void)span.begin();
(void)span.end();
@@ -32,7 +32,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
std::string another_str = fuzzed_data_provider.ConsumeBytesAsString(32);
- const Span<const char> another_span = MakeSpan(another_str);
+ const Span<const char> another_span{another_str};
assert((span <= another_span) != (span > another_span));
assert((span == another_span) != (span != another_span));
assert((span >= another_span) != (span < another_span));
diff --git a/src/test/fuzz/spanparsing.cpp b/src/test/fuzz/spanparsing.cpp
index 8e5e7dad11..e5bf5dd608 100644
--- a/src/test/fuzz/spanparsing.cpp
+++ b/src/test/fuzz/spanparsing.cpp
@@ -12,7 +12,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
const size_t query_size = fuzzed_data_provider.ConsumeIntegral<size_t>();
const std::string query = fuzzed_data_provider.ConsumeBytesAsString(std::min<size_t>(query_size, 1024 * 1024));
const std::string span_str = fuzzed_data_provider.ConsumeRemainingBytesAsString();
- const Span<const char> const_span = MakeSpan(span_str);
+ const Span<const char> const_span{span_str};
Span<const char> mut_span = const_span;
(void)spanparsing::Const(query, mut_span);
diff --git a/src/test/fuzz/string.cpp b/src/test/fuzz/string.cpp
index 50984b1aef..271062dc95 100644
--- a/src/test/fuzz/string.cpp
+++ b/src/test/fuzz/string.cpp
@@ -12,6 +12,7 @@
#include <rpc/server.h>
#include <rpc/util.h>
#include <script/descriptor.h>
+#include <script/script.h>
#include <serialize.h>
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
@@ -89,6 +90,10 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)urlDecode(random_string_1);
(void)ValidAsCString(random_string_1);
(void)_(random_string_1.c_str());
+ try {
+ throw scriptnum_error{random_string_1};
+ } catch (const std::runtime_error&) {
+ }
{
CDataStream data_stream{SER_NETWORK, INIT_PROTO_VERSION};
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 9d0fb02128..9f9552edb9 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -8,19 +8,26 @@
#include <amount.h>
#include <arith_uint256.h>
#include <attributes.h>
+#include <chainparamsbase.h>
#include <coins.h>
#include <consensus/consensus.h>
+#include <netaddress.h>
+#include <netbase.h>
#include <primitives/transaction.h>
#include <script/script.h>
+#include <script/standard.h>
#include <serialize.h>
#include <streams.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
+#include <test/util/setup_common.h>
#include <txmempool.h>
#include <uint256.h>
#include <version.h>
+#include <algorithm>
#include <cstdint>
+#include <cstdio>
#include <optional>
#include <string>
#include <vector>
@@ -31,6 +38,11 @@ NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataPr
return {s.begin(), s.end()};
}
+NODISCARD inline CDataStream ConsumeDataStream(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+{
+ return {ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length), SER_NETWORK, INIT_PROTO_VERSION};
+}
+
NODISCARD inline std::vector<std::string> ConsumeRandomLengthStringVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_vector_size = 16, const size_t max_string_length = 16) noexcept
{
const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
@@ -87,10 +99,19 @@ NODISCARD inline CScriptNum ConsumeScriptNum(FuzzedDataProvider& fuzzed_data_pro
return CScriptNum{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
}
+NODISCARD inline uint160 ConsumeUInt160(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ const std::vector<uint8_t> v160 = fuzzed_data_provider.ConsumeBytes<uint8_t>(160 / 8);
+ if (v160.size() != 160 / 8) {
+ return {};
+ }
+ return uint160{v160};
+}
+
NODISCARD inline uint256 ConsumeUInt256(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
- const std::vector<unsigned char> v256 = fuzzed_data_provider.ConsumeBytes<unsigned char>(sizeof(uint256));
- if (v256.size() != sizeof(uint256)) {
+ const std::vector<uint8_t> v256 = fuzzed_data_provider.ConsumeBytes<uint8_t>(256 / 8);
+ if (v256.size() != 256 / 8) {
return {};
}
return uint256{v256};
@@ -116,6 +137,43 @@ NODISCARD inline CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzze
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
}
+NODISCARD inline CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ CTxDestination tx_destination;
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
+ case 0: {
+ tx_destination = CNoDestination{};
+ break;
+ }
+ case 1: {
+ tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
+ break;
+ }
+ case 2: {
+ tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
+ break;
+ }
+ case 3: {
+ tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
+ break;
+ }
+ case 4: {
+ tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
+ break;
+ }
+ case 5: {
+ WitnessUnknown witness_unknown{};
+ witness_unknown.version = fuzzed_data_provider.ConsumeIntegral<int>();
+ 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;
+ break;
+ }
+ }
+ return tx_destination;
+}
+
template <typename T>
NODISCARD bool MultiplicationOverflow(const T i, const T j) noexcept
{
@@ -161,4 +219,255 @@ NODISCARD inline bool ContainsSpentInput(const CTransaction& tx, const CCoinsVie
return false;
}
+/**
+ * Returns a byte vector of specified size regardless of the number of remaining bytes available
+ * from the fuzzer. Pads with zero value bytes if needed to achieve the specified size.
+ */
+NODISCARD inline std::vector<uint8_t> ConsumeFixedLengthByteVector(FuzzedDataProvider& fuzzed_data_provider, const size_t length) noexcept
+{
+ std::vector<uint8_t> result(length);
+ const std::vector<uint8_t> random_bytes = fuzzed_data_provider.ConsumeBytes<uint8_t>(length);
+ if (!random_bytes.empty()) {
+ std::memcpy(result.data(), random_bytes.data(), random_bytes.size());
+ }
+ return result;
+}
+
+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) {
+ const in_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;
+}
+
+CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int32_t>()};
+}
+
+void InitializeFuzzingContext(const std::string& chain_name = CBaseChainParams::REGTEST)
+{
+ static const BasicTestingSetup basic_testing_setup{chain_name, {"-nodebuglogfile"}};
+}
+
+class FuzzedFileProvider
+{
+ FuzzedDataProvider& m_fuzzed_data_provider;
+ int64_t m_offset = 0;
+
+public:
+ FuzzedFileProvider(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider{fuzzed_data_provider}
+ {
+ }
+
+ FILE* open()
+ {
+ if (m_fuzzed_data_provider.ConsumeBool()) {
+ return nullptr;
+ }
+ std::string mode;
+ switch (m_fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 5)) {
+ case 0: {
+ mode = "r";
+ break;
+ }
+ case 1: {
+ mode = "r+";
+ break;
+ }
+ case 2: {
+ mode = "w";
+ break;
+ }
+ case 3: {
+ mode = "w+";
+ break;
+ }
+ case 4: {
+ mode = "a";
+ break;
+ }
+ case 5: {
+ mode = "a+";
+ break;
+ }
+ }
+#ifdef _GNU_SOURCE
+ 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
+ }
+
+ static ssize_t read(void* cookie, char* buf, size_t size)
+ {
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ 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 write(void* cookie, const char* buf, size_t size)
+ {
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ 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 int seek(void* cookie, int64_t* offset, int whence)
+ {
+ assert(whence == SEEK_SET || whence == SEEK_CUR); // SEEK_END not implemented yet.
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ 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;
+ }
+ 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 close(void* cookie)
+ {
+ FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
+ return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
+ }
+};
+
+NODISCARD inline FuzzedFileProvider ConsumeFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ return {fuzzed_data_provider};
+}
+
+class FuzzedAutoFileProvider
+{
+ FuzzedDataProvider& m_fuzzed_data_provider;
+ FuzzedFileProvider m_fuzzed_file_provider;
+
+public:
+ FuzzedAutoFileProvider(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider{fuzzed_data_provider}, m_fuzzed_file_provider{fuzzed_data_provider}
+ {
+ }
+
+ CAutoFile open()
+ {
+ return {m_fuzzed_file_provider.open(), m_fuzzed_data_provider.ConsumeIntegral<int>(), m_fuzzed_data_provider.ConsumeIntegral<int>()};
+ }
+};
+
+NODISCARD inline FuzzedAutoFileProvider ConsumeAutoFile(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ return {fuzzed_data_provider};
+}
+
+#define WRITE_TO_STREAM_CASE(id, type, consume) \
+ case id: { \
+ type o = consume; \
+ stream << o; \
+ break; \
+ }
+template <typename Stream>
+void WriteToStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noexcept
+{
+ while (fuzzed_data_provider.ConsumeBool()) {
+ try {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 13)) {
+ WRITE_TO_STREAM_CASE(0, bool, fuzzed_data_provider.ConsumeBool())
+ WRITE_TO_STREAM_CASE(1, char, fuzzed_data_provider.ConsumeIntegral<char>())
+ WRITE_TO_STREAM_CASE(2, int8_t, fuzzed_data_provider.ConsumeIntegral<int8_t>())
+ WRITE_TO_STREAM_CASE(3, uint8_t, fuzzed_data_provider.ConsumeIntegral<uint8_t>())
+ WRITE_TO_STREAM_CASE(4, int16_t, fuzzed_data_provider.ConsumeIntegral<int16_t>())
+ WRITE_TO_STREAM_CASE(5, uint16_t, fuzzed_data_provider.ConsumeIntegral<uint16_t>())
+ WRITE_TO_STREAM_CASE(6, int32_t, fuzzed_data_provider.ConsumeIntegral<int32_t>())
+ WRITE_TO_STREAM_CASE(7, uint32_t, fuzzed_data_provider.ConsumeIntegral<uint32_t>())
+ WRITE_TO_STREAM_CASE(8, int64_t, fuzzed_data_provider.ConsumeIntegral<int64_t>())
+ WRITE_TO_STREAM_CASE(9, uint64_t, fuzzed_data_provider.ConsumeIntegral<uint64_t>())
+ WRITE_TO_STREAM_CASE(10, float, fuzzed_data_provider.ConsumeFloatingPoint<float>())
+ WRITE_TO_STREAM_CASE(11, double, fuzzed_data_provider.ConsumeFloatingPoint<double>())
+ WRITE_TO_STREAM_CASE(12, std::string, fuzzed_data_provider.ConsumeRandomLengthString(32))
+ WRITE_TO_STREAM_CASE(13, std::vector<char>, ConsumeRandomLengthIntegralVector<char>(fuzzed_data_provider))
+ }
+ } catch (const std::ios_base::failure&) {
+ break;
+ }
+ }
+}
+
+#define READ_FROM_STREAM_CASE(id, type) \
+ case id: { \
+ type o; \
+ stream >> o; \
+ break; \
+ }
+template <typename Stream>
+void ReadFromStream(FuzzedDataProvider& fuzzed_data_provider, Stream& stream) noexcept
+{
+ while (fuzzed_data_provider.ConsumeBool()) {
+ try {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 13)) {
+ READ_FROM_STREAM_CASE(0, bool)
+ READ_FROM_STREAM_CASE(1, char)
+ READ_FROM_STREAM_CASE(2, int8_t)
+ READ_FROM_STREAM_CASE(3, uint8_t)
+ READ_FROM_STREAM_CASE(4, int16_t)
+ READ_FROM_STREAM_CASE(5, uint16_t)
+ READ_FROM_STREAM_CASE(6, int32_t)
+ READ_FROM_STREAM_CASE(7, uint32_t)
+ READ_FROM_STREAM_CASE(8, int64_t)
+ READ_FROM_STREAM_CASE(9, uint64_t)
+ READ_FROM_STREAM_CASE(10, float)
+ READ_FROM_STREAM_CASE(11, double)
+ READ_FROM_STREAM_CASE(12, std::string)
+ READ_FROM_STREAM_CASE(13, std::vector<char>)
+ }
+ } catch (const std::ios_base::failure&) {
+ break;
+ }
+ }
+}
+
#endif // BITCOIN_TEST_FUZZ_UTIL_H
diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp
index 512e48f8e5..45c9b90ee9 100644
--- a/src/test/getarg_tests.cpp
+++ b/src/test/getarg_tests.cpp
@@ -13,9 +13,18 @@
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
-BOOST_FIXTURE_TEST_SUITE(getarg_tests, BasicTestingSetup)
+namespace getarg_tests{
+ class LocalTestingSetup : BasicTestingSetup {
+ protected:
+ void SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args);
+ void ResetArgs(const std::string& strArg);
+ ArgsManager m_args;
+ };
+}
+
+BOOST_FIXTURE_TEST_SUITE(getarg_tests, LocalTestingSetup)
-static void ResetArgs(const std::string& strArg)
+void LocalTestingSetup :: ResetArgs(const std::string& strArg)
{
std::vector<std::string> vecArg;
if (strArg.size())
@@ -30,14 +39,14 @@ static void ResetArgs(const std::string& strArg)
vecChar.push_back(s.c_str());
std::string error;
- BOOST_CHECK(gArgs.ParseParameters(vecChar.size(), vecChar.data(), error));
+ BOOST_CHECK(m_args.ParseParameters(vecChar.size(), vecChar.data(), error));
}
-static void SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args)
+void LocalTestingSetup :: SetupArgs(const std::vector<std::pair<std::string, unsigned int>>& args)
{
- gArgs.ClearArgs();
+ m_args.ClearArgs();
for (const auto& arg : args) {
- gArgs.AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS);
+ m_args.AddArg(arg.first, "", arg.second, OptionsCategory::OPTIONS);
}
}
@@ -46,52 +55,52 @@ BOOST_AUTO_TEST_CASE(boolarg)
const auto foo = std::make_pair("-foo", ArgsManager::ALLOW_ANY);
SetupArgs({foo});
ResetArgs("-foo");
- BOOST_CHECK(gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", true));
- BOOST_CHECK(!gArgs.GetBoolArg("-fo", false));
- BOOST_CHECK(gArgs.GetBoolArg("-fo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-fo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-fo", true));
- BOOST_CHECK(!gArgs.GetBoolArg("-fooo", false));
- BOOST_CHECK(gArgs.GetBoolArg("-fooo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-fooo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-fooo", true));
ResetArgs("-foo=0");
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
ResetArgs("-foo=1");
- BOOST_CHECK(gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", true));
// New 0.6 feature: auto-map -nosomething to !-something:
ResetArgs("-nofoo");
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
ResetArgs("-nofoo=1");
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
ResetArgs("-foo -nofoo"); // -nofoo should win
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
ResetArgs("-foo=1 -nofoo=1"); // -nofoo should win
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
ResetArgs("-foo=0 -nofoo=0"); // -nofoo=0 should win
- BOOST_CHECK(gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", true));
// New 0.6 feature: treat -- same as -:
ResetArgs("--foo=1");
- BOOST_CHECK(gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", true));
ResetArgs("--nofoo=1");
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
}
@@ -101,24 +110,24 @@ BOOST_AUTO_TEST_CASE(stringarg)
const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);
SetupArgs({foo, bar});
ResetArgs("");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "eleven");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "eleven");
ResetArgs("-foo -bar");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "");
ResetArgs("-foo=");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "");
ResetArgs("-foo=11");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "11");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "11");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "11");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "11");
ResetArgs("-foo=eleven");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "eleven");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", "eleven"), "eleven");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "eleven");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", "eleven"), "eleven");
}
@@ -128,20 +137,20 @@ BOOST_AUTO_TEST_CASE(intarg)
const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);
SetupArgs({foo, bar});
ResetArgs("");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 11), 11);
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 0), 0);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 11), 11);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 0), 0);
ResetArgs("-foo -bar");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 11), 0);
- BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 0);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 11), 0);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 11), 0);
ResetArgs("-foo=11 -bar=12");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 0), 11);
- BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 12);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 0), 11);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 11), 12);
ResetArgs("-foo=NaN -bar=NotANumber");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", 1), 0);
- BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 11), 0);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", 1), 0);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 11), 0);
}
BOOST_AUTO_TEST_CASE(doubledash)
@@ -150,11 +159,11 @@ BOOST_AUTO_TEST_CASE(doubledash)
const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);
SetupArgs({foo, bar});
ResetArgs("--foo");
- BOOST_CHECK_EQUAL(gArgs.GetBoolArg("-foo", false), true);
+ BOOST_CHECK_EQUAL(m_args.GetBoolArg("-foo", false), true);
ResetArgs("--foo=verbose --bar=1");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-foo", ""), "verbose");
- BOOST_CHECK_EQUAL(gArgs.GetArg("-bar", 0), 1);
+ BOOST_CHECK_EQUAL(m_args.GetArg("-foo", ""), "verbose");
+ BOOST_CHECK_EQUAL(m_args.GetArg("-bar", 0), 1);
}
BOOST_AUTO_TEST_CASE(boolargno)
@@ -163,24 +172,24 @@ BOOST_AUTO_TEST_CASE(boolargno)
const auto bar = std::make_pair("-bar", ArgsManager::ALLOW_ANY);
SetupArgs({foo, bar});
ResetArgs("-nofoo");
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
ResetArgs("-nofoo=1");
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
ResetArgs("-nofoo=0");
- BOOST_CHECK(gArgs.GetBoolArg("-foo", true));
- BOOST_CHECK(gArgs.GetBoolArg("-foo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", true));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", false));
ResetArgs("-foo --nofoo"); // --nofoo should win
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", true));
- BOOST_CHECK(!gArgs.GetBoolArg("-foo", false));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", true));
+ BOOST_CHECK(!m_args.GetBoolArg("-foo", false));
ResetArgs("-nofoo -foo"); // foo always wins:
- BOOST_CHECK(gArgs.GetBoolArg("-foo", true));
- BOOST_CHECK(gArgs.GetBoolArg("-foo", false));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", true));
+ BOOST_CHECK(m_args.GetBoolArg("-foo", false));
}
BOOST_AUTO_TEST_CASE(logargs)
@@ -200,7 +209,7 @@ BOOST_AUTO_TEST_CASE(logargs)
});
// Log the arguments
- gArgs.LogArgs();
+ m_args.LogArgs();
LogInstance().DeleteCallback(print_connection);
// Check that what should appear does, and what shouldn't doesn't.
diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp
index cf2bd03698..fd35537c77 100644
--- a/src/test/key_tests.cpp
+++ b/src/test/key_tests.cpp
@@ -5,6 +5,7 @@
#include <key.h>
#include <key_io.h>
+#include <streams.h>
#include <test/util/setup_common.h>
#include <uint256.h>
#include <util/strencodings.h>
@@ -220,4 +221,47 @@ BOOST_AUTO_TEST_CASE(key_key_negation)
BOOST_CHECK(key.GetPubKey().data()[0] == 0x03);
}
+static CPubKey UnserializePubkey(const std::vector<uint8_t>& data)
+{
+ CDataStream stream{SER_NETWORK, INIT_PROTO_VERSION};
+ stream << data;
+ CPubKey pubkey;
+ stream >> pubkey;
+ return pubkey;
+}
+
+static unsigned int GetLen(unsigned char chHeader)
+{
+ if (chHeader == 2 || chHeader == 3)
+ return CPubKey::COMPRESSED_SIZE;
+ if (chHeader == 4 || chHeader == 6 || chHeader == 7)
+ return CPubKey::SIZE;
+ return 0;
+}
+
+static void CmpSerializationPubkey(const CPubKey& pubkey)
+{
+ CDataStream stream{SER_NETWORK, INIT_PROTO_VERSION};
+ stream << pubkey;
+ CPubKey pubkey2;
+ stream >> pubkey2;
+ BOOST_CHECK(pubkey == pubkey2);
+}
+
+BOOST_AUTO_TEST_CASE(pubkey_unserialize)
+{
+ for (uint8_t i = 2; i <= 7; ++i) {
+ CPubKey key = UnserializePubkey({0x02});
+ BOOST_CHECK(!key.IsValid());
+ CmpSerializationPubkey(key);
+ key = UnserializePubkey(std::vector<uint8_t>(GetLen(i), i));
+ CmpSerializationPubkey(key);
+ if (i == 5) {
+ BOOST_CHECK(!key.IsValid());
+ } else {
+ BOOST_CHECK(key.IsValid());
+ }
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 57eee94330..62a0dc4241 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
pblock->nNonce = blockinfo[i].nonce;
}
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
- BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
+ BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
pblock->hashPrevBlock = pblock->GetHash();
}
@@ -448,7 +448,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
m_node.mempool->addUnchecked(entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
BOOST_CHECK(CheckFinalTx(CTransaction(tx), flags)); // Locktime passes
BOOST_CHECK(!TestSequenceLocks(CTransaction(tx), flags)); // Sequence locks fail
- BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, &prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 2))); // Sequence locks pass on 2nd block
+ BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 2))); // Sequence locks pass on 2nd block
// relative time locked
tx.vin[0].prevout.hash = txFirst[1]->GetHash();
@@ -461,7 +461,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime += 512; //Trick the MedianTimePast
- BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, &prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 1))); // Sequence locks pass 512 seconds later
+ BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(::ChainActive().Tip()->nHeight + 1))); // Sequence locks pass 512 seconds later
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; i++)
::ChainActive().Tip()->GetAncestor(::ChainActive().Tip()->nHeight - i)->nTime -= 512; //undo tricked MTP
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index dd2890c134..e14d2dd72d 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard)
for (int i = 0; i < 4; i++)
key[i].MakeNewKey(true);
- txnouttype whichType;
+ TxoutType whichType;
CScript a_and_b;
a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index 84bf593497..ab42be21bd 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -6,6 +6,7 @@
#include <addrman.h>
#include <chainparams.h>
#include <clientversion.h>
+#include <cstdint>
#include <net.h>
#include <netbase.h>
#include <serialize.h>
@@ -83,10 +84,10 @@ BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(cnode_listen_port)
{
// test default
- unsigned short port = GetListenPort();
+ uint16_t port = GetListenPort();
BOOST_CHECK(port == Params().GetDefaultPort());
// test set port
- unsigned short altPort = 12345;
+ uint16_t altPort = 12345;
BOOST_CHECK(gArgs.SoftSetArg("-port", ToString(altPort)));
port = GetListenPort();
BOOST_CHECK(port == altPort);
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 2e1972cc3f..ea3e633cc2 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -6,6 +6,7 @@
#include <netbase.h>
#include <test/util/setup_common.h>
#include <util/strencodings.h>
+#include <util/translation.h>
#include <string>
@@ -159,6 +160,9 @@ BOOST_AUTO_TEST_CASE(subnet_test)
BOOST_CHECK(ResolveSubNet("1.2.2.20/26").Match(ResolveIP("1.2.2.63")));
// All-Matching IPv6 Matches arbitrary IPv4 and IPv6
BOOST_CHECK(ResolveSubNet("::/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
+ // But not `::` or `0.0.0.0` because they are considered invalid addresses
+ BOOST_CHECK(!ResolveSubNet("::/0").Match(ResolveIP("::")));
+ BOOST_CHECK(!ResolveSubNet("::/0").Match(ResolveIP("0.0.0.0")));
BOOST_CHECK(ResolveSubNet("::/0").Match(ResolveIP("1.2.3.4")));
// All-Matching IPv4 does not Match IPv6
BOOST_CHECK(!ResolveSubNet("0.0.0.0/0").Match(ResolveIP("1:2:3:4:5:6:7:1234")));
@@ -325,15 +329,15 @@ BOOST_AUTO_TEST_CASE(netbase_parsenetwork)
BOOST_AUTO_TEST_CASE(netpermissions_test)
{
- std::string error;
+ bilingual_str error;
NetWhitebindPermissions whitebindPermissions;
NetWhitelistPermissions whitelistPermissions;
// Detect invalid white bind
BOOST_CHECK(!NetWhitebindPermissions::TryParse("", whitebindPermissions, error));
- BOOST_CHECK(error.find("Cannot resolve -whitebind address") != std::string::npos);
+ BOOST_CHECK(error.original.find("Cannot resolve -whitebind address") != std::string::npos);
BOOST_CHECK(!NetWhitebindPermissions::TryParse("127.0.0.1", whitebindPermissions, error));
- BOOST_CHECK(error.find("Need to specify a port with -whitebind") != std::string::npos);
+ BOOST_CHECK(error.original.find("Need to specify a port with -whitebind") != std::string::npos);
BOOST_CHECK(!NetWhitebindPermissions::TryParse("", whitebindPermissions, error));
// If no permission flags, assume backward compatibility
@@ -377,11 +381,11 @@ BOOST_AUTO_TEST_CASE(netpermissions_test)
// Detect invalid flag
BOOST_CHECK(!NetWhitebindPermissions::TryParse("bloom,forcerelay,oopsie@1.2.3.4:32", whitebindPermissions, error));
- BOOST_CHECK(error.find("Invalid P2P permission") != std::string::npos);
+ BOOST_CHECK(error.original.find("Invalid P2P permission") != std::string::npos);
- // Check whitelist error
+ // Check netmask error
BOOST_CHECK(!NetWhitelistPermissions::TryParse("bloom,forcerelay,noban@1.2.3.4:32", whitelistPermissions, error));
- BOOST_CHECK(error.find("Invalid netmask specified in -whitelist") != std::string::npos);
+ BOOST_CHECK(error.original.find("Invalid netmask specified in -whitelist") != std::string::npos);
// Happy path for whitelist parsing
BOOST_CHECK(NetWhitelistPermissions::TryParse("noban@1.2.3.4", whitelistPermissions, error));
@@ -393,12 +397,13 @@ BOOST_AUTO_TEST_CASE(netpermissions_test)
BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay,mempool@1.2.3.4/32", whitelistPermissions, error));
const auto strings = NetPermissions::ToStrings(PF_ALL);
- BOOST_CHECK_EQUAL(strings.size(), 5U);
+ BOOST_CHECK_EQUAL(strings.size(), 6U);
BOOST_CHECK(std::find(strings.begin(), strings.end(), "bloomfilter") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "forcerelay") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "relay") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "noban") != strings.end());
BOOST_CHECK(std::find(strings.begin(), strings.end(), "mempool") != strings.end());
+ BOOST_CHECK(std::find(strings.begin(), strings.end(), "download") != strings.end());
}
BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters)
diff --git a/src/test/policy_fee_tests.cpp b/src/test/policy_fee_tests.cpp
new file mode 100644
index 0000000000..6d8872b11e
--- /dev/null
+++ b/src/test/policy_fee_tests.cpp
@@ -0,0 +1,34 @@
+// 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 <amount.h>
+#include <policy/fees.h>
+
+#include <test/util/setup_common.h>
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(policy_fee_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(FeeRounder)
+{
+ FeeFilterRounder fee_rounder{CFeeRate{1000}};
+
+ // check that 1000 rounds to 974 or 1071
+ std::set<CAmount> results;
+ while (results.size() < 2) {
+ results.emplace(fee_rounder.round(1000));
+ }
+ BOOST_CHECK_EQUAL(*results.begin(), 974);
+ BOOST_CHECK_EQUAL(*++results.begin(), 1071);
+
+ // check that negative amounts rounds to 0
+ BOOST_CHECK_EQUAL(fee_rounder.round(-0), 0);
+ BOOST_CHECK_EQUAL(fee_rounder.round(-1), 0);
+
+ // check that MAX_MONEY rounds to 9170997
+ BOOST_CHECK_EQUAL(fee_rounder.round(MAX_MONEY), 9170997);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp
index 04bf7c20c1..8c2712f764 100644
--- a/src/test/raii_event_tests.cpp
+++ b/src/test/raii_event_tests.cpp
@@ -4,9 +4,6 @@
#include <event2/event.h>
-#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
-// It would probably be ideal to define dummy test(s) that report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros)
-
#include <map>
#include <stdlib.h>
@@ -16,6 +13,10 @@
#include <boost/test/unit_test.hpp>
+BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup)
+
+#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
+
static std::map<void*, short> tags;
static std::map<void*, uint16_t> orders;
static uint16_t tagSequence = 0;
@@ -34,8 +35,6 @@ static void tag_free(void* mem) {
free(mem);
}
-BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup)
-
BOOST_AUTO_TEST_CASE(raii_event_creation)
{
event_set_mem_functions(tag_malloc, realloc, tag_free);
@@ -87,6 +86,14 @@ BOOST_AUTO_TEST_CASE(raii_event_order)
event_set_mem_functions(malloc, realloc, free);
}
-BOOST_AUTO_TEST_SUITE_END()
+#else
+
+BOOST_AUTO_TEST_CASE(raii_event_tests_SKIPPED)
+{
+ // It would probably be ideal to report skipped, but boost::test doesn't seem to make that practical (at least not in versions available with common distros)
+ BOOST_TEST_MESSAGE("Skipping raii_event_tess: libevent doesn't support event_set_mem_functions");
+}
#endif // EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/scheduler_tests.cpp b/src/test/scheduler_tests.cpp
index 1395a7f38c..2e5a7549b7 100644
--- a/src/test/scheduler_tests.cpp
+++ b/src/test/scheduler_tests.cpp
@@ -7,7 +7,7 @@
#include <util/time.h>
#include <boost/test/unit_test.hpp>
-#include <boost/thread.hpp>
+#include <boost/thread/thread.hpp>
#include <mutex>
@@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(manythreads)
}
// Drain the task queue then exit threads
- microTasks.stop(true);
+ microTasks.StopWhenDrained();
microThreads.join_all(); // ... wait until all the threads are done
int counterSum = 0;
@@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE(singlethreadedscheduler_ordered)
}
// finish up
- scheduler.stop(true);
+ scheduler.StopWhenDrained();
threads.join_all();
BOOST_CHECK_EQUAL(counter1, 100);
@@ -186,7 +186,7 @@ BOOST_AUTO_TEST_CASE(mockforward)
scheduler.MockForward(std::chrono::minutes{5});
// ensure scheduler has chance to process all tasks queued for before 1 ms from now.
- scheduler.scheduleFromNow([&scheduler] { scheduler.stop(false); }, std::chrono::milliseconds{1});
+ scheduler.scheduleFromNow([&scheduler] { scheduler.stop(); }, std::chrono::milliseconds{1});
scheduler_thread.join();
// check that the queue only has one job remaining
diff --git a/src/test/script_standard_tests.cpp b/src/test/script_standard_tests.cpp
index b185d3b4ac..77d748241b 100644
--- a/src/test/script_standard_tests.cpp
+++ b/src/test/script_standard_tests.cpp
@@ -31,35 +31,35 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
CScript s;
std::vector<std::vector<unsigned char> > solutions;
- // TX_PUBKEY
+ // TxoutType::PUBKEY
s.clear();
s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEY);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEY);
BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
- // TX_PUBKEYHASH
+ // TxoutType::PUBKEYHASH
s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEYHASH);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEYHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
- // TX_SCRIPTHASH
+ // TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_SCRIPTHASH);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::SCRIPTHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
- // TX_MULTISIG
+ // TxoutType::MULTISIG
s.clear();
s << OP_1 <<
ToByteVector(pubkeys[0]) <<
ToByteVector(pubkeys[1]) <<
OP_2 << OP_CHECKMULTISIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(solutions.size(), 4U);
BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
ToByteVector(pubkeys[1]) <<
ToByteVector(pubkeys[2]) <<
OP_3 << OP_CHECKMULTISIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(solutions.size(), 5U);
BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
@@ -80,37 +80,37 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));
BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));
- // TX_NULL_DATA
+ // TxoutType::NULL_DATA
s.clear();
s << OP_RETURN <<
std::vector<unsigned char>({0}) <<
std::vector<unsigned char>({75}) <<
std::vector<unsigned char>({255});
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NULL_DATA);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NULL_DATA);
BOOST_CHECK_EQUAL(solutions.size(), 0U);
- // TX_WITNESS_V0_KEYHASH
+ // TxoutType::WITNESS_V0_KEYHASH
s.clear();
s << OP_0 << ToByteVector(pubkeys[0].GetID());
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_KEYHASH);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_KEYHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
- // TX_WITNESS_V0_SCRIPTHASH
+ // TxoutType::WITNESS_V0_SCRIPTHASH
uint256 scriptHash;
CSHA256().Write(&redeemScript[0], redeemScript.size())
.Finalize(scriptHash.begin());
s.clear();
s << OP_0 << ToByteVector(scriptHash);
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_SCRIPTHASH);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_SCRIPTHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));
- // TX_NONSTANDARD
+ // TxoutType::NONSTANDARD
s.clear();
s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
}
BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
@@ -123,50 +123,50 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
CScript s;
std::vector<std::vector<unsigned char> > solutions;
- // TX_PUBKEY with incorrectly sized pubkey
+ // TxoutType::PUBKEY with incorrectly sized pubkey
s.clear();
s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_PUBKEYHASH with incorrectly sized key hash
+ // TxoutType::PUBKEYHASH with incorrectly sized key hash
s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_SCRIPTHASH with incorrectly sized script hash
+ // TxoutType::SCRIPTHASH with incorrectly sized script hash
s.clear();
s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_MULTISIG 0/2
+ // TxoutType::MULTISIG 0/2
s.clear();
s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_MULTISIG 2/1
+ // TxoutType::MULTISIG 2/1
s.clear();
s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_MULTISIG n = 2 with 1 pubkey
+ // TxoutType::MULTISIG n = 2 with 1 pubkey
s.clear();
s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_MULTISIG n = 1 with 0 pubkeys
+ // TxoutType::MULTISIG n = 1 with 0 pubkeys
s.clear();
s << OP_1 << OP_1 << OP_CHECKMULTISIG;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_NULL_DATA with other opcodes
+ // TxoutType::NULL_DATA with other opcodes
s.clear();
s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
- // TX_WITNESS with incorrect program size
+ // TxoutType::WITNESS_UNKNOWN with incorrect program size
s.clear();
s << OP_0 << std::vector<unsigned char>(19, 0x01);
- BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD);
+ BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
}
BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
@@ -179,21 +179,21 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
CScript s;
CTxDestination address;
- // TX_PUBKEY
+ // TxoutType::PUBKEY
s.clear();
s << ToByteVector(pubkey) << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(boost::get<PKHash>(&address) &&
*boost::get<PKHash>(&address) == PKHash(pubkey));
- // TX_PUBKEYHASH
+ // TxoutType::PUBKEYHASH
s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(boost::get<PKHash>(&address) &&
*boost::get<PKHash>(&address) == PKHash(pubkey));
- // TX_SCRIPTHASH
+ // TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
@@ -201,17 +201,17 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
BOOST_CHECK(boost::get<ScriptHash>(&address) &&
*boost::get<ScriptHash>(&address) == ScriptHash(redeemScript));
- // TX_MULTISIG
+ // TxoutType::MULTISIG
s.clear();
s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
BOOST_CHECK(!ExtractDestination(s, address));
- // TX_NULL_DATA
+ // TxoutType::NULL_DATA
s.clear();
s << OP_RETURN << std::vector<unsigned char>({75});
BOOST_CHECK(!ExtractDestination(s, address));
- // TX_WITNESS_V0_KEYHASH
+ // TxoutType::WITNESS_V0_KEYHASH
s.clear();
s << OP_0 << ToByteVector(pubkey.GetID());
BOOST_CHECK(ExtractDestination(s, address));
@@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(keyhash.begin());
BOOST_CHECK(boost::get<WitnessV0KeyHash>(&address) && *boost::get<WitnessV0KeyHash>(&address) == keyhash);
- // TX_WITNESS_V0_SCRIPTHASH
+ // TxoutType::WITNESS_V0_SCRIPTHASH
s.clear();
WitnessV0ScriptHash scripthash;
CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin());
@@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(boost::get<WitnessV0ScriptHash>(&address) && *boost::get<WitnessV0ScriptHash>(&address) == scripthash);
- // TX_WITNESS with unknown version
+ // TxoutType::WITNESS_UNKNOWN with unknown version
s.clear();
s << OP_1 << ToByteVector(pubkey);
BOOST_CHECK(ExtractDestination(s, address));
@@ -248,49 +248,49 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
}
CScript s;
- txnouttype whichType;
+ TxoutType whichType;
std::vector<CTxDestination> addresses;
int nRequired;
- // TX_PUBKEY
+ // TxoutType::PUBKEY
s.clear();
s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
- BOOST_CHECK_EQUAL(whichType, TX_PUBKEY);
+ BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEY);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
*boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
- // TX_PUBKEYHASH
+ // TxoutType::PUBKEYHASH
s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
- BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH);
+ BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEYHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
*boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
- // TX_SCRIPTHASH
+ // TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
- BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH);
+ BOOST_CHECK_EQUAL(whichType, TxoutType::SCRIPTHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<ScriptHash>(&addresses[0]) &&
*boost::get<ScriptHash>(&addresses[0]) == ScriptHash(redeemScript));
- // TX_MULTISIG
+ // TxoutType::MULTISIG
s.clear();
s << OP_2 <<
ToByteVector(pubkeys[0]) <<
ToByteVector(pubkeys[1]) <<
OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
- BOOST_CHECK_EQUAL(whichType, TX_MULTISIG);
+ BOOST_CHECK_EQUAL(whichType, TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(addresses.size(), 2U);
BOOST_CHECK_EQUAL(nRequired, 2);
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
@@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK(boost::get<PKHash>(&addresses[1]) &&
*boost::get<PKHash>(&addresses[1]) == PKHash(pubkeys[1]));
- // TX_NULL_DATA
+ // TxoutType::NULL_DATA
s.clear();
s << OP_RETURN << std::vector<unsigned char>({75});
BOOST_CHECK(!ExtractDestinations(s, whichType, addresses, nRequired));
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index fcd831ccda..1a2d775f49 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -12,10 +12,90 @@
#include <univalue.h>
#include <util/strencodings.h>
#include <util/string.h>
+#include <util/system.h>
#include <vector>
+inline bool operator==(const util::SettingsValue& a, const util::SettingsValue& b)
+{
+ return a.write() == b.write();
+}
+
+inline std::ostream& operator<<(std::ostream& os, const util::SettingsValue& value)
+{
+ os << value.write();
+ return os;
+}
+
+inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, util::SettingsValue>& kv)
+{
+ util::SettingsValue out(util::SettingsValue::VOBJ);
+ out.__pushKV(kv.first, kv.second);
+ os << out.write();
+ return os;
+}
+
+inline void WriteText(const fs::path& path, const std::string& text)
+{
+ fsbridge::ofstream file;
+ file.open(path);
+ file << text;
+}
+
BOOST_FIXTURE_TEST_SUITE(settings_tests, BasicTestingSetup)
+BOOST_AUTO_TEST_CASE(ReadWrite)
+{
+ fs::path path = GetDataDir() / "settings.json";
+
+ WriteText(path, R"({
+ "string": "string",
+ "num": 5,
+ "bool": true,
+ "null": null
+ })");
+
+ std::map<std::string, util::SettingsValue> expected{
+ {"string", "string"},
+ {"num", 5},
+ {"bool", true},
+ {"null", {}},
+ };
+
+ // Check file read.
+ std::map<std::string, util::SettingsValue> values;
+ std::vector<std::string> errors;
+ BOOST_CHECK(util::ReadSettings(path, values, errors));
+ BOOST_CHECK_EQUAL_COLLECTIONS(values.begin(), values.end(), expected.begin(), expected.end());
+ BOOST_CHECK(errors.empty());
+
+ // Check no errors if file doesn't exist.
+ fs::remove(path);
+ BOOST_CHECK(util::ReadSettings(path, values, errors));
+ BOOST_CHECK(values.empty());
+ BOOST_CHECK(errors.empty());
+
+ // Check duplicate keys not allowed
+ WriteText(path, R"({
+ "dupe": "string",
+ "dupe": "dupe"
+ })");
+ BOOST_CHECK(!util::ReadSettings(path, values, errors));
+ std::vector<std::string> dup_keys = {strprintf("Found duplicate key dupe in settings file %s", path.string())};
+ BOOST_CHECK_EQUAL_COLLECTIONS(errors.begin(), errors.end(), dup_keys.begin(), dup_keys.end());
+
+ // Check non-kv json files not allowed
+ WriteText(path, R"("non-kv")");
+ BOOST_CHECK(!util::ReadSettings(path, values, errors));
+ std::vector<std::string> non_kv = {strprintf("Found non-object value \"non-kv\" in settings file %s", path.string())};
+ BOOST_CHECK_EQUAL_COLLECTIONS(errors.begin(), errors.end(), non_kv.begin(), non_kv.end());
+
+ // Check invalid json not allowed
+ WriteText(path, R"(invalid json)");
+ BOOST_CHECK(!util::ReadSettings(path, values, errors));
+ std::vector<std::string> fail_parse = {strprintf("Unable to parse settings file %s", path.string())};
+ BOOST_CHECK_EQUAL_COLLECTIONS(errors.begin(), errors.end(), fail_parse.begin(), fail_parse.end());
+}
+
//! Check settings struct contents against expected json strings.
static void CheckValues(const util::Settings& settings, const std::string& single_val, const std::string& list_val)
{
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index 5ca136ea6e..c0bb92258b 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(sighash_test)
ss << txTo;
std::cout << "\t[\"" ;
- std::cout << HexStr(ss.begin(), ss.end()) << "\", \"";
+ std::cout << HexStr(ss) << "\", \"";
std::cout << HexStr(scriptCode) << "\", ";
std::cout << nIn << ", ";
std::cout << nHashType << ", \"";
diff --git a/src/test/sync_tests.cpp b/src/test/sync_tests.cpp
index 5c6c2ee38e..3ea8714f3a 100644
--- a/src/test/sync_tests.cpp
+++ b/src/test/sync_tests.cpp
@@ -18,7 +18,7 @@ void TestPotentialDeadLockDetected(MutexType& mutex1, MutexType& mutex2)
try {
LOCK2(mutex2, mutex1);
} catch (const std::logic_error& e) {
- BOOST_CHECK_EQUAL(e.what(), "potential deadlock detected");
+ BOOST_CHECK_EQUAL(e.what(), "potential deadlock detected: mutex1 -> mutex2 -> mutex1");
error_thrown = true;
}
#ifdef DEBUG_LOCKORDER
diff --git a/src/test/timedata_tests.cpp b/src/test/timedata_tests.cpp
index 8c880babd1..1dcee23bbb 100644
--- a/src/test/timedata_tests.cpp
+++ b/src/test/timedata_tests.cpp
@@ -9,6 +9,7 @@
#include <test/util/setup_common.h>
#include <timedata.h>
#include <util/string.h>
+#include <util/translation.h>
#include <warnings.h>
#include <string>
@@ -66,7 +67,7 @@ BOOST_AUTO_TEST_CASE(addtimedata)
MultiAddTimeData(1, DEFAULT_MAX_TIME_ADJUSTMENT + 1); //filter size 5
}
- BOOST_CHECK(GetWarnings(true).find("clock is wrong") != std::string::npos);
+ BOOST_CHECK(GetWarnings(true).original.find("clock is wrong") != std::string::npos);
// nTimeOffset is not changed if the median of offsets exceeds DEFAULT_MAX_TIME_ADJUSTMENT
BOOST_CHECK_EQUAL(GetTimeOffset(), 0);
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index ddbc68f8e2..4bf6e734ce 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -716,12 +716,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
BOOST_CHECK_EQUAL(reason, "scriptpubkey");
- // MAX_OP_RETURN_RELAY-byte TX_NULL_DATA (standard)
+ // 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));
- // MAX_OP_RETURN_RELAY+1-byte TX_NULL_DATA (non-standard)
+ // 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();
@@ -745,12 +745,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
BOOST_CHECK_EQUAL(reason, "scriptpubkey");
- // TX_NULL_DATA w/o PUSHDATA
+ // TxoutType::NULL_DATA w/o PUSHDATA
t.vout.resize(1);
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
- // Only one TX_NULL_DATA permitted in all cases
+ // Only one TxoutType::NULL_DATA permitted in all cases
t.vout.resize(2);
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp
index dac7f1a07b..74536ae74c 100644
--- a/src/test/util/mining.cpp
+++ b/src/test/util/mining.cpp
@@ -11,6 +11,7 @@
#include <node/context.h>
#include <pow.h>
#include <script/standard.h>
+#include <util/check.h>
#include <validation.h>
CTxIn generatetoaddress(const NodeContext& node, const std::string& address)
@@ -31,7 +32,7 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
assert(block->nNonce);
}
- bool processed{EnsureChainman(node).ProcessNewBlock(Params(), block, true, nullptr)};
+ bool processed{Assert(node.chainman)->ProcessNewBlock(Params(), block, true, nullptr)};
assert(processed);
return CTxIn{block->vtx[0]->GetHash(), 0};
@@ -39,9 +40,8 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{
- assert(node.mempool);
auto block = std::make_shared<CBlock>(
- BlockAssembler{*node.mempool, Params()}
+ BlockAssembler{*Assert(node.mempool), Params()}
.CreateNewBlock(coinbase_scriptPubKey)
->block);
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 83916fd080..0cd991f453 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -19,6 +19,7 @@
#include <rpc/blockchain.h>
#include <rpc/register.h>
#include <rpc/server.h>
+#include <scheduler.h>
#include <script/sigcache.h>
#include <streams.h>
#include <txdb.h>
@@ -74,11 +75,13 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
"dummy",
"-printtoconsole=0",
"-logtimemicros",
+ "-logthreadnames",
"-debug",
"-debugexclude=libevent",
"-debugexclude=leveldb",
},
extra_args);
+ util::ThreadRename("test");
fs::create_directories(m_path_root);
gArgs.ForceSetArg("-datadir", m_path_root.string());
ClearDatadirCache();
@@ -129,7 +132,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
// We have to run a scheduler thread to prevent ActivateBestChain
// from blocking due to queue overrun.
- threadGroup.create_thread([&]{ m_node.scheduler->serviceQueue(); });
+ threadGroup.create_thread([&] { TraceThread("scheduler", [&] { m_node.scheduler->serviceQueue(); }); });
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
@@ -228,7 +231,7 @@ CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransa
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
- EnsureChainman(m_node).ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
+ Assert(m_node.chainman)->ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
CBlock result = block;
return result;
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index 2477f9ad06..78b279e42a 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -11,13 +11,13 @@
#include <node/context.h>
#include <pubkey.h>
#include <random.h>
-#include <scheduler.h>
#include <txmempool.h>
+#include <util/check.h>
#include <util/string.h>
#include <type_traits>
-#include <boost/thread.hpp>
+#include <boost/thread/thread.hpp>
/** This is connected to the logger. Can be used to redirect logs to any other log */
extern const std::function<void(const std::string&)> G_TEST_LOG_FUN;
diff --git a/src/test/util/transaction_utils.h b/src/test/util/transaction_utils.h
index 1beddd334b..6f2faeec6c 100644
--- a/src/test/util/transaction_utils.h
+++ b/src/test/util/transaction_utils.h
@@ -22,8 +22,8 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int n
CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit);
// Helper: create two dummy transactions, each with two outputs.
-// The first has nValues[0] and nValues[1] outputs paid to a TX_PUBKEY,
-// the second nValues[2] and nValues[3] outputs paid to a TX_PUBKEYHASH.
+// The first has nValues[0] and nValues[1] outputs paid to a TxoutType::PUBKEY,
+// the second nValues[2] and nValues[3] outputs paid to a TxoutType::PUBKEYHASH.
std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues);
#endif // BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index cf26ca3adb..a30e366028 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -9,6 +9,7 @@
#include <key.h> // For CKey
#include <optional.h>
#include <sync.h>
+#include <test/util/logging.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
#include <uint256.h>
@@ -41,6 +42,16 @@ namespace BCLog {
BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
+BOOST_AUTO_TEST_CASE(util_check)
+{
+ // Check that Assert can forward
+ const std::unique_ptr<int> p_two = Assert(MakeUnique<int>(2));
+ // Check that Assert works on lvalues and rvalues
+ const int two = *Assert(p_two);
+ Assert(two == 2);
+ Assert(true);
+}
+
BOOST_AUTO_TEST_CASE(util_criticalsection)
{
RecursiveMutex cs;
@@ -1128,6 +1139,28 @@ BOOST_FIXTURE_TEST_CASE(util_ChainMerge, ChainMergeTestingSetup)
BOOST_CHECK_EQUAL(out_sha_hex, "f0b3a3c29869edc765d579c928f7f1690a71fbb673b49ccf39cbc4de18156a0d");
}
+BOOST_AUTO_TEST_CASE(util_ReadWriteSettings)
+{
+ // Test writing setting.
+ TestArgsManager args1;
+ args1.LockSettings([&](util::Settings& settings) { settings.rw_settings["name"] = "value"; });
+ args1.WriteSettingsFile();
+
+ // Test reading setting.
+ TestArgsManager args2;
+ args2.ReadSettingsFile();
+ args2.LockSettings([&](util::Settings& settings) { BOOST_CHECK_EQUAL(settings.rw_settings["name"].get_str(), "value"); });
+
+ // Test error logging, and remove previously written setting.
+ {
+ ASSERT_DEBUG_LOG("Failed renaming settings file");
+ fs::remove(GetDataDir() / "settings.json");
+ fs::create_directory(GetDataDir() / "settings.json");
+ args2.WriteSettingsFile();
+ fs::remove(GetDataDir() / "settings.json");
+ }
+}
+
BOOST_AUTO_TEST_CASE(util_FormatMoney)
{
BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
@@ -1829,7 +1862,7 @@ BOOST_AUTO_TEST_CASE(test_spanparsing)
// Const(...): parse a constant, update span to skip it if successful
input = "MilkToastHoney";
- sp = MakeSpan(input);
+ sp = input;
success = Const("", sp); // empty
BOOST_CHECK(success);
BOOST_CHECK_EQUAL(SpanToStr(sp), "MilkToastHoney");
@@ -1854,7 +1887,7 @@ BOOST_AUTO_TEST_CASE(test_spanparsing)
// Func(...): parse a function call, update span to argument if successful
input = "Foo(Bar(xy,z()))";
- sp = MakeSpan(input);
+ sp = input;
success = Func("FooBar", sp);
BOOST_CHECK(!success);
@@ -1877,31 +1910,31 @@ BOOST_AUTO_TEST_CASE(test_spanparsing)
Span<const char> result;
input = "(n*(n-1))/2";
- sp = MakeSpan(input);
+ sp = input;
result = Expr(sp);
BOOST_CHECK_EQUAL(SpanToStr(result), "(n*(n-1))/2");
BOOST_CHECK_EQUAL(SpanToStr(sp), "");
input = "foo,bar";
- sp = MakeSpan(input);
+ sp = input;
result = Expr(sp);
BOOST_CHECK_EQUAL(SpanToStr(result), "foo");
BOOST_CHECK_EQUAL(SpanToStr(sp), ",bar");
input = "(aaaaa,bbbbb()),c";
- sp = MakeSpan(input);
+ sp = input;
result = Expr(sp);
BOOST_CHECK_EQUAL(SpanToStr(result), "(aaaaa,bbbbb())");
BOOST_CHECK_EQUAL(SpanToStr(sp), ",c");
input = "xyz)foo";
- sp = MakeSpan(input);
+ sp = input;
result = Expr(sp);
BOOST_CHECK_EQUAL(SpanToStr(result), "xyz");
BOOST_CHECK_EQUAL(SpanToStr(sp), ")foo");
input = "((a),(b),(c)),xxx";
- sp = MakeSpan(input);
+ sp = input;
result = Expr(sp);
BOOST_CHECK_EQUAL(SpanToStr(result), "((a),(b),(c))");
BOOST_CHECK_EQUAL(SpanToStr(sp), ",xxx");
@@ -1910,7 +1943,7 @@ BOOST_AUTO_TEST_CASE(test_spanparsing)
std::vector<Span<const char>> results;
input = "xxx";
- results = Split(MakeSpan(input), 'x');
+ results = Split(input, 'x');
BOOST_CHECK_EQUAL(results.size(), 4U);
BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
BOOST_CHECK_EQUAL(SpanToStr(results[1]), "");
@@ -1918,19 +1951,19 @@ BOOST_AUTO_TEST_CASE(test_spanparsing)
BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
input = "one#two#three";
- results = Split(MakeSpan(input), '-');
+ results = Split(input, '-');
BOOST_CHECK_EQUAL(results.size(), 1U);
BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one#two#three");
input = "one#two#three";
- results = Split(MakeSpan(input), '#');
+ results = Split(input, '#');
BOOST_CHECK_EQUAL(results.size(), 3U);
BOOST_CHECK_EQUAL(SpanToStr(results[0]), "one");
BOOST_CHECK_EQUAL(SpanToStr(results[1]), "two");
BOOST_CHECK_EQUAL(SpanToStr(results[2]), "three");
input = "*foo*bar*";
- results = Split(MakeSpan(input), '*');
+ results = Split(input, '*');
BOOST_CHECK_EQUAL(results.size(), 4U);
BOOST_CHECK_EQUAL(SpanToStr(results[0]), "");
BOOST_CHECK_EQUAL(SpanToStr(results[1]), "foo");
diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp
index 4dcc080b2d..f3f9fb2bff 100644
--- a/src/test/util_threadnames_tests.cpp
+++ b/src/test/util_threadnames_tests.cpp
@@ -53,8 +53,6 @@ std::set<std::string> RenameEnMasse(int num_threads)
*/
BOOST_AUTO_TEST_CASE(util_threadnames_test_rename_threaded)
{
- BOOST_CHECK_EQUAL(util::ThreadGetInternalName(), "");
-
#if !defined(HAVE_THREAD_LOCAL)
// This test doesn't apply to platforms where we don't have thread_local.
return;
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index 45e0c5484e..8e85b7df3e 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -163,10 +163,10 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
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(EnsureChainman(m_node).ProcessNewBlockHeaders(headers, state, Params()));
+ BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlockHeaders(headers, state, Params()));
// Connect the genesis block and drain any outstanding events
- BOOST_CHECK(EnsureChainman(m_node).ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
+ BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(Params(), std::make_shared<CBlock>(Params().GenesisBlock()), true, &ignored));
SyncWithValidationInterfaceQueue();
// subscribe to events (this subscriber will validate event ordering)
@@ -188,13 +188,13 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
FastRandomContext insecure;
for (int i = 0; i < 1000; i++) {
auto block = blocks[insecure.randrange(blocks.size() - 1)];
- EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, &ignored);
+ Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, &ignored);
}
// to make sure that eventually we process the full chain - do it here
for (auto block : blocks) {
if (block->vtx.size() == 1) {
- bool processed = EnsureChainman(m_node).ProcessNewBlock(Params(), block, true, &ignored);
+ bool processed = Assert(m_node.chainman)->ProcessNewBlock(Params(), block, true, &ignored);
assert(processed);
}
}
@@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(mempool_locks_reorg)
{
bool ignored;
auto ProcessBlock = [&](std::shared_ptr<const CBlock> block) -> bool {
- return EnsureChainman(m_node).ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored);
+ return Assert(m_node.chainman)->ProcessNewBlock(Params(), block, /* fForceProcessing */ true, /* fNewBlock */ &ignored);
};
// Process all mined blocks