Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions src/Makefile.test.include

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Makefile.test_util.include
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ EXTRA_LIBRARIES += \
TEST_UTIL_H = \
test/util/blockfilter.h \
test/util/logging.h \
test/util/net.h \
test/util/setup_common.h \
test/util/str.h \
test/util/transaction_utils.h
Expand All @@ -19,6 +20,7 @@ libtest_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libtest_util_a_SOURCES = \
test/util/blockfilter.cpp \
test/util/logging.cpp \
test/util/net.cpp \
test/util/setup_common.cpp \
test/util/str.cpp \
test/util/transaction_utils.cpp \
Expand Down
3 changes: 3 additions & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ friend class CNode;
std::atomic<int64_t> m_next_send_inv_to_incoming{0};

friend struct CConnmanTest;
friend struct ConnmanTestMsg;
};
void Discover();
unsigned short GetListenPort();
Expand Down Expand Up @@ -925,6 +926,8 @@ class V1TransportSerializer : public TransportSerializer {
class CNode
{
friend class CConnman;
friend struct ConnmanTestMsg;

public:
std::unique_ptr<TransportDeserializer> m_deserializer;
std::unique_ptr<TransportSerializer> m_serializer;
Expand Down
14 changes: 9 additions & 5 deletions src/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ void RandAddEvent(const uint32_t event_info) noexcept;
*
* This class is not thread-safe.
*/
class FastRandomContext {
class FastRandomContext
{
private:
bool requires_seed;
ChaCha20 rng;
Expand Down Expand Up @@ -158,7 +159,8 @@ class FastRandomContext {
}

/** Generate a random (bits)-bit integer. */
uint64_t randbits(int bits) noexcept {
uint64_t randbits(int bits) noexcept
{
if (bits == 0) {
return 0;
} else if (bits > 32) {
Expand All @@ -172,7 +174,9 @@ class FastRandomContext {
}
}

/** Generate a random integer in the range [0..range). */
/** Generate a random integer in the range [0..range).
* Precondition: range > 0.
*/
uint64_t randrange(uint64_t range) noexcept
{
assert(range);
Expand Down Expand Up @@ -221,7 +225,7 @@ class FastRandomContext {
* debug mode detects and panics on. This is a known issue, see
* https://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle
*/
template<typename I, typename R>
template <typename I, typename R>
void Shuffle(I first, I last, R&& rng)
{
while (first != last) {
Expand All @@ -244,7 +248,7 @@ static const int NUM_OS_RANDOM_BYTES = 32;
/** Get 32 bytes of system entropy. Do not use this in application code: use
* GetStrongRandBytes instead.
*/
void GetOSRand(unsigned char *ent32);
void GetOSRand(unsigned char* ent32);

/** Check that OS randomness is available and returning the requested number
* of bytes.
Expand Down
55 changes: 55 additions & 0 deletions src/test/fuzz/addition_overflow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>

#include <cstdint>
#include <string>
#include <vector>

#if defined(__has_builtin)
#if __has_builtin(__builtin_add_overflow)
#define HAVE_BUILTIN_ADD_OVERFLOW
#endif
#elif defined(__GNUC__) && (__GNUC__ >= 5)
#define HAVE_BUILTIN_ADD_OVERFLOW
#endif

namespace {
template <typename T>
void TestAdditionOverflow(FuzzedDataProvider& fuzzed_data_provider)
{
const T i = fuzzed_data_provider.ConsumeIntegral<T>();
const T j = fuzzed_data_provider.ConsumeIntegral<T>();
const bool is_addition_overflow_custom = AdditionOverflow(i, j);
#if defined(HAVE_BUILTIN_ADD_OVERFLOW)
T result_builtin;
const bool is_addition_overflow_builtin = __builtin_add_overflow(i, j, &result_builtin);
assert(is_addition_overflow_custom == is_addition_overflow_builtin);
if (!is_addition_overflow_custom) {
assert(i + j == result_builtin);
}
#else
if (!is_addition_overflow_custom) {
(void)(i + j);
}
#endif
}
} // namespace

void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
TestAdditionOverflow<int64_t>(fuzzed_data_provider);
TestAdditionOverflow<uint64_t>(fuzzed_data_provider);
TestAdditionOverflow<int32_t>(fuzzed_data_provider);
TestAdditionOverflow<uint32_t>(fuzzed_data_provider);
TestAdditionOverflow<int16_t>(fuzzed_data_provider);
TestAdditionOverflow<uint16_t>(fuzzed_data_provider);
TestAdditionOverflow<char>(fuzzed_data_provider);
TestAdditionOverflow<unsigned char>(fuzzed_data_provider);
TestAdditionOverflow<signed char>(fuzzed_data_provider);
}
36 changes: 36 additions & 0 deletions src/test/fuzz/addrdb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 <optional.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>

#include <cassert>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>

void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

const CBanEntry ban_entry = [&] {
switch (fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 2)) {
case 0:
return CBanEntry{fuzzed_data_provider.ConsumeIntegral<int64_t>()};
break;
case 1: {
const Optional<CBanEntry> ban_entry = ConsumeDeserializable<CBanEntry>(fuzzed_data_provider);
if (ban_entry) {
return *ban_entry;
}
break;
}
}
return CBanEntry{};
}();
}
41 changes: 41 additions & 0 deletions src/test/fuzz/block_header.cpp
Original file line number Diff line number Diff line change
@@ -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 <optional.h>
#include <primitives/block.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <uint256.h>

#include <cassert>
#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 Optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);
if (!block_header) {
return;
}
{
const uint256 hash = block_header->GetHash();
static const uint256 u256_max(uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
assert(hash != u256_max);
assert(block_header->GetBlockTime() == block_header->nTime);
assert(block_header->IsNull() == (block_header->nBits == 0));
}
{
CBlockHeader mut_block_header = *block_header;
mut_block_header.SetNull();
assert(mut_block_header.IsNull());
CBlock block{*block_header};
assert(block.GetBlockHeader().GetHash() == block_header->GetHash());
(void)block.ToString();
block.SetNull();
assert(block.GetBlockHeader().GetHash() == mut_block_header.GetHash());
}
}
44 changes: 44 additions & 0 deletions src/test/fuzz/blockfilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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 <blockfilter.h>
#include <optional.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 Optional<BlockFilter> block_filter = ConsumeDeserializable<BlockFilter>(fuzzed_data_provider);
if (!block_filter) {
return;
}
{
(void)block_filter->ComputeHeader(ConsumeUInt256(fuzzed_data_provider));
(void)block_filter->GetBlockHash();
(void)block_filter->GetEncodedFilter();
(void)block_filter->GetHash();
}
{
const BlockFilterType block_filter_type = block_filter->GetFilterType();
(void)BlockFilterTypeName(block_filter_type);
}
{
const GCSFilter gcs_filter = block_filter->GetFilter();
(void)gcs_filter.GetN();
(void)gcs_filter.GetParams();
(void)gcs_filter.GetEncoded();
(void)gcs_filter.Match(ConsumeRandomLengthByteVector(fuzzed_data_provider));
GCSFilter::ElementSet element_set;
while (fuzzed_data_provider.ConsumeBool()) {
element_set.insert(ConsumeRandomLengthByteVector(fuzzed_data_provider));
gcs_filter.MatchAny(element_set);
}
}
}
2 changes: 1 addition & 1 deletion src/test/fuzz/bloom_filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
while (fuzzed_data_provider.remaining_bytes() > 0) {
switch (fuzzed_data_provider.ConsumeIntegralInRange(0, 6)) {
case 0: {
const std::vector<unsigned char>& b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
const std::vector<unsigned char> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
(void)bloom_filter.contains(b);
bloom_filter.insert(b);
const bool present = bloom_filter.contains(b);
Expand Down
65 changes: 65 additions & 0 deletions src/test/fuzz/checkqueue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// 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 <checkqueue.h>
#include <optional.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>

#include <cstdint>
#include <string>
#include <vector>

namespace {
struct DumbCheck {
const bool result = false;

DumbCheck() = default;

explicit DumbCheck(const bool _result) : result(_result)
{
}

bool operator()() const
{
return result;
}

void swap(DumbCheck& x)
{
}
};
} // namespace

void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());

const unsigned int batch_size = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, 1024);
CCheckQueue<DumbCheck> check_queue_1{batch_size};
CCheckQueue<DumbCheck> check_queue_2{batch_size};
std::vector<DumbCheck> checks_1;
std::vector<DumbCheck> checks_2;
const int size = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 1024);
for (int i = 0; i < size; ++i) {
const bool result = fuzzed_data_provider.ConsumeBool();
checks_1.emplace_back(result);
checks_2.emplace_back(result);
}
if (fuzzed_data_provider.ConsumeBool()) {
check_queue_1.Add(checks_1);
}
if (fuzzed_data_provider.ConsumeBool()) {
(void)check_queue_1.Wait();
}

CCheckQueueControl<DumbCheck> check_queue_control{&check_queue_2};
if (fuzzed_data_provider.ConsumeBool()) {
check_queue_control.Add(checks_2);
}
if (fuzzed_data_provider.ConsumeBool()) {
(void)check_queue_control.Wait();
}
}
49 changes: 49 additions & 0 deletions src/test/fuzz/cuckoocache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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 <cuckoocache.h>
#include <optional.h>
#include <script/sigcache.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/setup_common.h>

#include <cstdint>
#include <string>
#include <vector>

namespace {
FuzzedDataProvider* fuzzed_data_provider_ptr = nullptr;

struct RandomHasher {
template <uint8_t>
uint32_t operator()(const bool& /* unused */) const
{
assert(fuzzed_data_provider_ptr != nullptr);
return fuzzed_data_provider_ptr->ConsumeIntegral<uint32_t>();
}
};
} // namespace

void test_one_input(const std::vector<uint8_t>& buffer)
{
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
fuzzed_data_provider_ptr = &fuzzed_data_provider;
CuckooCache::cache<int, RandomHasher> cuckoo_cache{};
if (fuzzed_data_provider.ConsumeBool()) {
const size_t megabytes = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 16);
cuckoo_cache.setup_bytes(megabytes << 20);
} else {
cuckoo_cache.setup(fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, 4096));
}
while (fuzzed_data_provider.ConsumeBool()) {
if (fuzzed_data_provider.ConsumeBool()) {
cuckoo_cache.insert(fuzzed_data_provider.ConsumeBool());
} else {
cuckoo_cache.contains(fuzzed_data_provider.ConsumeBool(), fuzzed_data_provider.ConsumeBool());
}
}
fuzzed_data_provider_ptr = nullptr;
}
Loading