aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/fuzz/addrman.cpp119
-rw-r--r--src/test/fuzz/connman.cpp162
-rw-r--r--src/test/fuzz/deserialize.cpp38
-rw-r--r--src/test/fuzz/merkleblock.cpp34
-rw-r--r--src/test/fuzz/net.cpp2
-rw-r--r--src/test/fuzz/process_message.cpp7
-rw-r--r--src/test/fuzz/process_messages.cpp6
-rw-r--r--src/test/fuzz/util.h41
-rw-r--r--src/test/util/setup_common.h9
-rw-r--r--src/test/util/validation.cpp22
-rw-r--r--src/test/util/validation.h17
11 files changed, 437 insertions, 20 deletions
diff --git a/src/test/fuzz/addrman.cpp b/src/test/fuzz/addrman.cpp
new file mode 100644
index 0000000000..0ceeea2d36
--- /dev/null
+++ b/src/test/fuzz/addrman.cpp
@@ -0,0 +1,119 @@
+// Copyright (c) 2020 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include <addrdb.h>
+#include <addrman.h>
+#include <chainparams.h>
+#include <merkleblock.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <time.h>
+#include <util/asmap.h>
+
+#include <cstdint>
+#include <optional>
+#include <string>
+#include <vector>
+
+void initialize()
+{
+ SelectParams(CBaseChainParams::REGTEST);
+}
+
+void test_one_input(const std::vector<uint8_t>& buffer)
+{
+ FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
+
+ SetMockTime(ConsumeTime(fuzzed_data_provider));
+ CAddrMan addr_man;
+ if (fuzzed_data_provider.ConsumeBool()) {
+ addr_man.m_asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
+ if (!SanityCheckASMap(addr_man.m_asmap)) {
+ addr_man.m_asmap.clear();
+ }
+ }
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 11)) {
+ case 0: {
+ addr_man.Clear();
+ break;
+ }
+ case 1: {
+ addr_man.ResolveCollisions();
+ break;
+ }
+ case 2: {
+ (void)addr_man.SelectTriedCollision();
+ break;
+ }
+ case 3: {
+ (void)addr_man.Select(fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ case 4: {
+ (void)addr_man.GetAddr(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096), fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 4096));
+ break;
+ }
+ case 5: {
+ const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
+ const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
+ if (opt_address && opt_net_addr) {
+ addr_man.Add(*opt_address, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
+ }
+ break;
+ }
+ case 6: {
+ std::vector<CAddress> addresses;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ const std::optional<CAddress> opt_address = ConsumeDeserializable<CAddress>(fuzzed_data_provider);
+ if (!opt_address) {
+ break;
+ }
+ addresses.push_back(*opt_address);
+ }
+ const std::optional<CNetAddr> opt_net_addr = ConsumeDeserializable<CNetAddr>(fuzzed_data_provider);
+ if (opt_net_addr) {
+ addr_man.Add(addresses, *opt_net_addr, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 100000000));
+ }
+ break;
+ }
+ case 7: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Good(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
+ }
+ break;
+ }
+ case 8: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Attempt(*opt_service, fuzzed_data_provider.ConsumeBool(), ConsumeTime(fuzzed_data_provider));
+ }
+ break;
+ }
+ case 9: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.Connected(*opt_service, ConsumeTime(fuzzed_data_provider));
+ }
+ break;
+ }
+ case 10: {
+ const std::optional<CService> opt_service = ConsumeDeserializable<CService>(fuzzed_data_provider);
+ if (opt_service) {
+ addr_man.SetServices(*opt_service, ServiceFlags{fuzzed_data_provider.ConsumeIntegral<uint64_t>()});
+ }
+ break;
+ }
+ case 11: {
+ (void)addr_man.Check();
+ break;
+ }
+ }
+ }
+ (void)addr_man.size();
+ CDataStream data_stream(SER_NETWORK, PROTOCOL_VERSION);
+ data_stream << addr_man;
+}
diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp
new file mode 100644
index 0000000000..6521c3f3b2
--- /dev/null
+++ b/src/test/fuzz/connman.cpp
@@ -0,0 +1,162 @@
+// 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 <net.h>
+#include <netaddress.h>
+#include <protocol.h>
+#include <test/fuzz/FuzzedDataProvider.h>
+#include <test/fuzz/fuzz.h>
+#include <test/fuzz/util.h>
+#include <util/translation.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()};
+ CConnman connman{fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeIntegral<uint64_t>(), fuzzed_data_provider.ConsumeBool()};
+ CAddress random_address;
+ CNetAddr random_netaddr;
+ CNode random_node = ConsumeNode(fuzzed_data_provider);
+ CService random_service;
+ CSubNet random_subnet;
+ std::string random_string;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 30)) {
+ case 0:
+ random_address = ConsumeAddress(fuzzed_data_provider);
+ break;
+ case 1:
+ random_netaddr = ConsumeNetAddr(fuzzed_data_provider);
+ break;
+ case 2:
+ random_service = ConsumeService(fuzzed_data_provider);
+ break;
+ case 3:
+ random_subnet = ConsumeSubNet(fuzzed_data_provider);
+ break;
+ case 4:
+ random_string = fuzzed_data_provider.ConsumeRandomLengthString(64);
+ break;
+ case 5: {
+ std::vector<CAddress> addresses;
+ while (fuzzed_data_provider.ConsumeBool()) {
+ addresses.push_back(ConsumeAddress(fuzzed_data_provider));
+ }
+ // Limit nTimePenalty to int32_t to avoid signed integer overflow
+ (void)connman.AddNewAddresses(addresses, ConsumeAddress(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int32_t>());
+ break;
+ }
+ case 6:
+ connman.AddNode(random_string);
+ break;
+ case 7:
+ connman.CheckIncomingNonce(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ break;
+ case 8:
+ connman.DisconnectNode(fuzzed_data_provider.ConsumeIntegral<NodeId>());
+ break;
+ case 9:
+ connman.DisconnectNode(random_netaddr);
+ break;
+ case 10:
+ connman.DisconnectNode(random_string);
+ break;
+ case 11:
+ connman.DisconnectNode(random_subnet);
+ break;
+ case 12:
+ connman.ForEachNode([](auto) {});
+ break;
+ case 13:
+ connman.ForEachNodeThen([](auto) {}, []() {});
+ break;
+ case 14:
+ (void)connman.ForNode(fuzzed_data_provider.ConsumeIntegral<NodeId>(), [&](auto) { return fuzzed_data_provider.ConsumeBool(); });
+ break;
+ case 15:
+ (void)connman.GetAddresses(fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
+ break;
+ case 16: {
+ (void)connman.GetAddresses(random_node, fuzzed_data_provider.ConsumeIntegral<size_t>(), fuzzed_data_provider.ConsumeIntegral<size_t>());
+ break;
+ }
+ case 17:
+ (void)connman.GetDeterministicRandomizer(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ break;
+ case 18:
+ (void)connman.GetNodeCount(fuzzed_data_provider.PickValueInArray({CConnman::CONNECTIONS_NONE, CConnman::CONNECTIONS_IN, CConnman::CONNECTIONS_OUT, CConnman::CONNECTIONS_ALL}));
+ break;
+ case 19:
+ connman.MarkAddressGood(random_address);
+ break;
+ case 20:
+ (void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
+ break;
+ case 21:
+ // Limit now to int32_t to avoid signed integer overflow
+ (void)connman.PoissonNextSendInbound(fuzzed_data_provider.ConsumeIntegral<int32_t>(), fuzzed_data_provider.ConsumeIntegral<int>());
+ break;
+ case 22: {
+ CSerializedNetMsg serialized_net_msg;
+ serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE);
+ serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);
+ connman.PushMessage(&random_node, std::move(serialized_net_msg));
+ break;
+ }
+ case 23:
+ connman.RemoveAddedNode(random_string);
+ break;
+ case 24: {
+ const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
+ if (SanityCheckASMap(asmap)) {
+ connman.SetAsmap(asmap);
+ }
+ break;
+ }
+ case 25:
+ connman.SetBestHeight(fuzzed_data_provider.ConsumeIntegral<int>());
+ break;
+ case 26:
+ connman.SetMaxOutboundTarget(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ break;
+ case 27:
+ connman.SetMaxOutboundTimeframe(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ break;
+ case 28:
+ connman.SetNetworkActive(fuzzed_data_provider.ConsumeBool());
+ break;
+ case 29:
+ connman.SetServices(random_service, static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>()));
+ break;
+ case 30:
+ connman.SetTryNewOutboundPeer(fuzzed_data_provider.ConsumeBool());
+ break;
+ }
+ }
+ (void)connman.GetAddedNodeInfo();
+ (void)connman.GetBestHeight();
+ (void)connman.GetExtraOutboundCount();
+ (void)connman.GetLocalServices();
+ (void)connman.GetMaxOutboundTarget();
+ (void)connman.GetMaxOutboundTimeframe();
+ (void)connman.GetMaxOutboundTimeLeftInCycle();
+ (void)connman.GetNetworkActive();
+ std::vector<CNodeStats> stats;
+ connman.GetNodeStats(stats);
+ (void)connman.GetOutboundTargetBytesLeft();
+ (void)connman.GetReceiveFloodSize();
+ (void)connman.GetTotalBytesRecv();
+ (void)connman.GetTotalBytesSent();
+ (void)connman.GetTryNewOutboundPeer();
+ (void)connman.GetUseAddrmanOutgoing();
+}
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index 9803fdc882..8ca5366c8a 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -15,6 +15,7 @@
#include <net.h>
#include <netbase.h>
#include <node/utxo_snapshot.h>
+#include <optional.h>
#include <primitives/block.h>
#include <protocol.h>
#include <psbt.h>
@@ -61,15 +62,19 @@ T Deserialize(CDataStream ds)
}
template <typename T>
-void DeserializeFromFuzzingInput(const std::vector<uint8_t>& buffer, T& obj)
+void DeserializeFromFuzzingInput(const std::vector<uint8_t>& buffer, T& obj, const Optional<int> protocol_version = nullopt)
{
CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION);
- try {
- int version;
- ds >> version;
- ds.SetVersion(version);
- } catch (const std::ios_base::failure&) {
- throw invalid_fuzzing_input_exception();
+ if (protocol_version) {
+ ds.SetVersion(*protocol_version);
+ } else {
+ try {
+ int version;
+ ds >> version;
+ ds.SetVersion(version);
+ } catch (const std::ios_base::failure&) {
+ throw invalid_fuzzing_input_exception();
+ }
}
try {
ds >> obj;
@@ -125,9 +130,15 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CScript script;
DeserializeFromFuzzingInput(buffer, script);
#elif SUB_NET_DESERIALIZE
- CSubNet sub_net;
- DeserializeFromFuzzingInput(buffer, sub_net);
- AssertEqualAfterSerializeDeserialize(sub_net);
+ CSubNet sub_net_1;
+ DeserializeFromFuzzingInput(buffer, sub_net_1, INIT_PROTO_VERSION);
+ AssertEqualAfterSerializeDeserialize(sub_net_1, INIT_PROTO_VERSION);
+ CSubNet sub_net_2;
+ DeserializeFromFuzzingInput(buffer, sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ AssertEqualAfterSerializeDeserialize(sub_net_2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ CSubNet sub_net_3;
+ DeserializeFromFuzzingInput(buffer, sub_net_3);
+ AssertEqualAfterSerializeDeserialize(sub_net_3, INIT_PROTO_VERSION | ADDRV2_FORMAT);
#elif TX_IN_DESERIALIZE
CTxIn tx_in;
DeserializeFromFuzzingInput(buffer, tx_in);
@@ -195,6 +206,13 @@ void test_one_input(const std::vector<uint8_t>& buffer)
AssertEqualAfterSerializeDeserialize(s);
}
AssertEqualAfterSerializeDeserialize(s, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ CService s1;
+ DeserializeFromFuzzingInput(buffer, s1, INIT_PROTO_VERSION);
+ AssertEqualAfterSerializeDeserialize(s1, INIT_PROTO_VERSION);
+ assert(s1.IsAddrV1Compatible());
+ CService s2;
+ DeserializeFromFuzzingInput(buffer, s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
+ AssertEqualAfterSerializeDeserialize(s2, INIT_PROTO_VERSION | ADDRV2_FORMAT);
#elif MESSAGEHEADER_DESERIALIZE
CMessageHeader mh;
DeserializeFromFuzzingInput(buffer, mh);
diff --git a/src/test/fuzz/merkleblock.cpp b/src/test/fuzz/merkleblock.cpp
index c44e334272..4710e75757 100644
--- a/src/test/fuzz/merkleblock.cpp
+++ b/src/test/fuzz/merkleblock.cpp
@@ -16,12 +16,36 @@
void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
- std::optional<CPartialMerkleTree> partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider);
- if (!partial_merkle_tree) {
- return;
+ CPartialMerkleTree partial_merkle_tree;
+ switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1)) {
+ case 0: {
+ const std::optional<CPartialMerkleTree> opt_partial_merkle_tree = ConsumeDeserializable<CPartialMerkleTree>(fuzzed_data_provider);
+ if (opt_partial_merkle_tree) {
+ partial_merkle_tree = *opt_partial_merkle_tree;
+ }
+ break;
}
- (void)partial_merkle_tree->GetNumTransactions();
+ case 1: {
+ CMerkleBlock merkle_block;
+ const std::optional<CBlock> opt_block = ConsumeDeserializable<CBlock>(fuzzed_data_provider);
+ CBloomFilter bloom_filter;
+ std::set<uint256> txids;
+ if (opt_block && !opt_block->vtx.empty()) {
+ if (fuzzed_data_provider.ConsumeBool()) {
+ merkle_block = CMerkleBlock{*opt_block, bloom_filter};
+ } else if (fuzzed_data_provider.ConsumeBool()) {
+ while (fuzzed_data_provider.ConsumeBool()) {
+ txids.insert(ConsumeUInt256(fuzzed_data_provider));
+ }
+ merkle_block = CMerkleBlock{*opt_block, txids};
+ }
+ }
+ partial_merkle_tree = merkle_block.txn;
+ break;
+ }
+ }
+ (void)partial_merkle_tree.GetNumTransactions();
std::vector<uint256> matches;
std::vector<unsigned int> indices;
- (void)partial_merkle_tree->ExtractMatches(matches, indices);
+ (void)partial_merkle_tree.ExtractMatches(matches, indices);
}
diff --git a/src/test/fuzz/net.cpp b/src/test/fuzz/net.cpp
index 3818838765..c61d406291 100644
--- a/src/test/fuzz/net.cpp
+++ b/src/test/fuzz/net.cpp
@@ -63,7 +63,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
break;
}
case 3: {
- const std::vector<bool> asmap = ConsumeRandomLengthIntegralVector<bool>(fuzzed_data_provider, 128);
+ const std::vector<bool> asmap = ConsumeRandomLengthBitVector(fuzzed_data_provider);
if (!SanityCheckASMap(asmap)) {
break;
}
diff --git a/src/test/fuzz/process_message.cpp b/src/test/fuzz/process_message.cpp
index 3ef03137ec..9390399878 100644
--- a/src/test/fuzz/process_message.cpp
+++ b/src/test/fuzz/process_message.cpp
@@ -16,6 +16,7 @@
#include <test/util/mining.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
+#include <test/util/validation.h>
#include <util/memory.h>
#include <validationinterface.h>
#include <version.h>
@@ -63,10 +64,14 @@ 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();
+ TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate();
+ chainstate.ResetIbd();
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;
}
+ const bool jump_out_of_ibd{fuzzed_data_provider.ConsumeBool()};
+ if (jump_out_of_ibd) chainstate.JumpOutOfIbd();
CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION};
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{}, ConnectionType::OUTBOUND_FULL_RELAY).release();
p2p_node.fSuccessfullyConnected = true;
@@ -76,7 +81,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
g_setup->m_node.peerman->InitializeNode(&p2p_node);
try {
g_setup->m_node.peerman->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream,
- GetTime<std::chrono::microseconds>(), std::atomic<bool>{false});
+ GetTime<std::chrono::microseconds>(), std::atomic<bool>{false});
} catch (const std::ios_base::failure&) {
}
SyncWithValidationInterfaceQueue();
diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp
index f722eeac3a..19ea92b750 100644
--- a/src/test/fuzz/process_messages.cpp
+++ b/src/test/fuzz/process_messages.cpp
@@ -12,6 +12,7 @@
#include <test/util/mining.h>
#include <test/util/net.h>
#include <test/util/setup_common.h>
+#include <test/util/validation.h>
#include <util/memory.h>
#include <validation.h>
#include <validationinterface.h>
@@ -39,7 +40,10 @@ 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();
+ TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate();
+ chainstate.ResetIbd();
std::vector<CNode*> peers;
+ bool jump_out_of_ibd{false};
const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3);
for (int i = 0; i < num_peers_to_add; ++i) {
@@ -58,6 +62,8 @@ void test_one_input(const std::vector<uint8_t>& buffer)
}
while (fuzzed_data_provider.ConsumeBool()) {
+ if (!jump_out_of_ibd) jump_out_of_ibd = fuzzed_data_provider.ConsumeBool();
+ if (jump_out_of_ibd && chainstate.IsInitialBlockDownload()) chainstate.JumpOutOfIbd();
const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
CSerializedNetMsg net_msg;
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index ed6093a8a8..e99ed8d72d 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -11,6 +11,8 @@
#include <chainparamsbase.h>
#include <coins.h>
#include <consensus/consensus.h>
+#include <merkleblock.h>
+#include <net.h>
#include <netaddress.h>
#include <netbase.h>
#include <primitives/transaction.h>
@@ -23,6 +25,7 @@
#include <test/util/setup_common.h>
#include <txmempool.h>
#include <uint256.h>
+#include <util/time.h>
#include <version.h>
#include <algorithm>
@@ -38,6 +41,11 @@ NODISCARD inline std::vector<uint8_t> ConsumeRandomLengthByteVector(FuzzedDataPr
return {s.begin(), s.end()};
}
+NODISCARD inline std::vector<bool> ConsumeRandomLengthBitVector(FuzzedDataProvider& fuzzed_data_provider, const size_t max_length = 4096) noexcept
+{
+ return BytesToBits(ConsumeRandomLengthByteVector(fuzzed_data_provider, max_length));
+}
+
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};
@@ -88,6 +96,13 @@ NODISCARD inline CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider)
return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, MAX_MONEY);
}
+NODISCARD inline int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ static const int64_t time_min = ParseISO8601DateTime("1970-01-01T00:00:00Z");
+ static const int64_t time_max = ParseISO8601DateTime("9999-12-31T23:59:59Z");
+ return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(time_min, time_max);
+}
+
NODISCARD inline CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider) noexcept
{
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
@@ -260,6 +275,32 @@ CSubNet ConsumeSubNet(FuzzedDataProvider& fuzzed_data_provider) noexcept
return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint8_t>()};
}
+CService ConsumeService(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ return {ConsumeNetAddr(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<uint16_t>()};
+}
+
+CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ return {ConsumeService(fuzzed_data_provider), static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>()), fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
+}
+
+CNode ConsumeNode(FuzzedDataProvider& fuzzed_data_provider) noexcept
+{
+ const NodeId node_id = fuzzed_data_provider.ConsumeIntegral<NodeId>();
+ const ServiceFlags local_services = static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>());
+ const int my_starting_height = fuzzed_data_provider.ConsumeIntegral<int>();
+ const SOCKET socket = INVALID_SOCKET;
+ const CAddress address = ConsumeAddress(fuzzed_data_provider);
+ const uint64_t keyed_net_group = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
+ const uint64_t local_host_nonce = fuzzed_data_provider.ConsumeIntegral<uint64_t>();
+ const CAddress addr_bind = ConsumeAddress(fuzzed_data_provider);
+ const std::string addr_name = fuzzed_data_provider.ConsumeRandomLengthString(64);
+ const ConnectionType conn_type = fuzzed_data_provider.PickValueInArray({ConnectionType::INBOUND, ConnectionType::OUTBOUND_FULL_RELAY, ConnectionType::MANUAL, ConnectionType::FEELER, ConnectionType::BLOCK_RELAY, ConnectionType::ADDR_FETCH});
+ const bool inbound_onion = fuzzed_data_provider.ConsumeBool();
+ return {node_id, local_services, my_starting_height, socket, address, keyed_net_group, local_host_nonce, addr_bind, addr_name, conn_type, inbound_onion};
+}
+
void InitializeFuzzingContext(const std::string& chain_name = CBaseChainParams::REGTEST)
{
static const BasicTestingSetup basic_testing_setup{chain_name, {"-nodebuglogfile"}};
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index a09c8c122d..1812ce1666 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -11,6 +11,7 @@
#include <node/context.h>
#include <pubkey.h>
#include <random.h>
+#include <stdexcept>
#include <txmempool.h>
#include <util/check.h>
#include <util/string.h>
@@ -158,13 +159,15 @@ std::ostream& operator<<(std::ostream& os, const uint256& num);
* Use as
* BOOST_CHECK_EXCEPTION(code that throws, exception type, HasReason("foo"));
*/
-class HasReason {
+class HasReason
+{
public:
explicit HasReason(const std::string& reason) : m_reason(reason) {}
- template <typename E>
- bool operator() (const E& e) const {
+ bool operator()(const std::exception& e) const
+ {
return std::string(e.what()).find(m_reason) != std::string::npos;
};
+
private:
const std::string m_reason;
};
diff --git a/src/test/util/validation.cpp b/src/test/util/validation.cpp
new file mode 100644
index 0000000000..1aed492c3c
--- /dev/null
+++ b/src/test/util/validation.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 <test/util/validation.h>
+
+#include <util/check.h>
+#include <util/time.h>
+#include <validation.h>
+
+void TestChainState::ResetIbd()
+{
+ m_cached_finished_ibd = false;
+ assert(IsInitialBlockDownload());
+}
+
+void TestChainState::JumpOutOfIbd()
+{
+ Assert(IsInitialBlockDownload());
+ m_cached_finished_ibd = true;
+ Assert(!IsInitialBlockDownload());
+}
diff --git a/src/test/util/validation.h b/src/test/util/validation.h
new file mode 100644
index 0000000000..b13aa0be60
--- /dev/null
+++ b/src/test/util/validation.h
@@ -0,0 +1,17 @@
+// 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.
+
+#ifndef BITCOIN_TEST_UTIL_VALIDATION_H
+#define BITCOIN_TEST_UTIL_VALIDATION_H
+
+#include <validation.h>
+
+struct TestChainState : public CChainState {
+ /** Reset the ibd cache to its initial state */
+ void ResetIbd();
+ /** Toggle IsInitialBlockDownload from true to false */
+ void JumpOutOfIbd();
+};
+
+#endif // BITCOIN_TEST_UTIL_VALIDATION_H