Skip to content

Commit

Permalink
Merge #20332: test: Mock IBD in net_processing fuzzers
Browse files Browse the repository at this point in the history
fa4234d877ea3193bfd0e18ff68dcb8fb84b47b5 test: Mock IBD in net_processing fuzzers (MarcoFalke)

Pull request description:

  Without this the fuzzers fail to detect trivial crasher bugs, such as bitcoin/bitcoin#20317 (comment)

ACKs for top commit:
  practicalswift:
    Tested ACK fa4234d877ea3193bfd0e18ff68dcb8fb84b47b5

Tree-SHA512: ce5da5c0a604b7559805a98ffdde882b44ca4f91b003b493d6e1be230714ce4cccb11dbfc1fc175f9d8fc779551c0a4103ceb4b473552928207d7d78ae329e10

Former-commit-id: bf9794723ebf37244ccdae86754d422345ea6c52
  • Loading branch information
MarcoFalke authored and jagdeep sidhu committed Nov 11, 2020
1 parent a112c70 commit 0587b91
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.test_util.include
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ TEST_UTIL_H = \
test/util/setup_common.h \
test/util/str.h \
test/util/transaction_utils.h \
test/util/validation.h \
test/util/wallet.h

libtest_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(SYSCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
Expand All @@ -27,6 +28,7 @@ libtest_util_a_SOURCES = \
test/util/setup_common.cpp \
test/util/str.cpp \
test/util/transaction_utils.cpp \
test/util/validation.cpp \
test/util/wallet.cpp \
$(TEST_UTIL_H)

Expand Down
7 changes: 6 additions & 1 deletion src/test/fuzz/process_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand All @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions src/test/fuzz/process_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions src/test/util/validation.cpp
Original file line number Diff line number Diff line change
@@ -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());
}
17 changes: 17 additions & 0 deletions src/test/util/validation.h
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,9 +521,9 @@ enum class CoinsCacheSizeState
* whereas block information and metadata independent of the current tip is
* kept in `BlockMetadataManager`.
*/
class CChainState {
private:

class CChainState
{
protected:
/**
* Every received block is assigned a unique and increasing identifier, so we
* know which one to give priority in case of a fork.
Expand Down

0 comments on commit 0587b91

Please sign in to comment.