diff options
author | MarcoFalke <falke.marco@gmail.com> | 2020-04-04 07:30:51 +0800 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2020-04-05 10:46:24 +0800 |
commit | fa6a00843447d53a5708ea3a629b9150cfe58be2 (patch) | |
tree | 788c0a0be44c45cc94bbaad8ea543d0f1b67e3b2 /src/test | |
parent | 96a30b98c925b4ca63993759ddf7b4dd1fa58ec1 (diff) | |
download | bitcoin-fa6a00843447d53a5708ea3a629b9150cfe58be2.tar.xz |
fuzz: Add process_messages harness
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/fuzz/process_messages.cpp | 75 | ||||
-rw-r--r-- | src/test/util/net.cpp | 39 | ||||
-rw-r--r-- | src/test/util/net.h | 33 | ||||
-rw-r--r-- | src/test/util/setup_common.cpp | 5 |
4 files changed, 152 insertions, 0 deletions
diff --git a/src/test/fuzz/process_messages.cpp b/src/test/fuzz/process_messages.cpp new file mode 100644 index 0000000000..12a5dbb607 --- /dev/null +++ b/src/test/fuzz/process_messages.cpp @@ -0,0 +1,75 @@ +// 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 <consensus/consensus.h> +#include <net.h> +#include <net_processing.h> +#include <protocol.h> +#include <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <test/fuzz/util.h> +#include <test/util/mining.h> +#include <test/util/net.h> +#include <test/util/setup_common.h> +#include <util/memory.h> +#include <validation.h> +#include <validationinterface.h> + +const RegTestingSetup* g_setup; + +void initialize() +{ + static RegTestingSetup setup{}; + g_setup = &setup; + + for (int i = 0; i < 2 * COINBASE_MATURITY; i++) { + MineBlock(g_setup->m_node, CScript() << OP_TRUE); + } + SyncWithValidationInterfaceQueue(); +} + +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(); + std::vector<CNode*> peers; + + const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3); + for (int i = 0; i < num_peers_to_add; ++i) { + const ServiceFlags service_flags = ServiceFlags(fuzzed_data_provider.ConsumeIntegral<uint64_t>()); + const bool inbound{fuzzed_data_provider.ConsumeBool()}; + const bool block_relay_only{fuzzed_data_provider.ConsumeBool()}; + peers.push_back(MakeUnique<CNode>(i, service_flags, 0, INVALID_SOCKET, CAddress{CService{in_addr{0x0100007f}, 7777}, NODE_NETWORK}, 0, 0, CAddress{}, std::string{}, inbound, block_relay_only).release()); + CNode& p2p_node = *peers.back(); + + p2p_node.fSuccessfullyConnected = true; + p2p_node.fPauseSend = false; + p2p_node.nVersion = PROTOCOL_VERSION; + p2p_node.SetSendVersion(PROTOCOL_VERSION); + g_setup->m_node.peer_logic->InitializeNode(&p2p_node); + + connman.AddTestNode(p2p_node); + } + + while (fuzzed_data_provider.ConsumeBool()) { + 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.data = ConsumeRandomLengthByteVector(fuzzed_data_provider); + + CNode& random_node = *peers.at(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, peers.size() - 1)); + + (void)connman.ReceiveMsgFrom(random_node, net_msg); + random_node.fPauseSend = false; + + try { + connman.ProcessMessagesOnce(random_node); + } catch (const std::ios_base::failure&) { + } + } + connman.ClearTestNodes(); + SyncWithValidationInterfaceQueue(); +} diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp new file mode 100644 index 0000000000..09f2f1807f --- /dev/null +++ b/src/test/util/net.cpp @@ -0,0 +1,39 @@ +// 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/net.h> + +#include <chainparams.h> +#include <net.h> + +void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, const char* pch, unsigned int nBytes, bool& complete) const +{ + assert(node.ReceiveMsgBytes(pch, nBytes, complete)); + if (complete) { + size_t nSizeAdded = 0; + auto it(node.vRecvMsg.begin()); + for (; it != node.vRecvMsg.end(); ++it) { + // vRecvMsg contains only completed CNetMessage + // the single possible partially deserialized message are held by TransportDeserializer + nSizeAdded += it->m_raw_message_size; + } + { + LOCK(node.cs_vProcessMsg); + node.vProcessMsg.splice(node.vProcessMsg.end(), node.vRecvMsg, node.vRecvMsg.begin(), it); + node.nProcessQueueSize += nSizeAdded; + node.fPauseRecv = node.nProcessQueueSize > nReceiveFloodSize; + } + } +} + +bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const +{ + std::vector<unsigned char> ser_msg_header; + node.m_serializer->prepareForTransport(ser_msg, ser_msg_header); + + bool complete; + NodeReceiveMsgBytes(node, (const char*)ser_msg_header.data(), ser_msg_header.size(), complete); + NodeReceiveMsgBytes(node, (const char*)ser_msg.data.data(), ser_msg.data.size(), complete); + return complete; +} diff --git a/src/test/util/net.h b/src/test/util/net.h new file mode 100644 index 0000000000..ca8cb7fad5 --- /dev/null +++ b/src/test/util/net.h @@ -0,0 +1,33 @@ +// 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_NET_H +#define BITCOIN_TEST_UTIL_NET_H + +#include <net.h> + +struct ConnmanTestMsg : public CConnman { + using CConnman::CConnman; + void AddTestNode(CNode& node) + { + LOCK(cs_vNodes); + vNodes.push_back(&node); + } + void ClearTestNodes() + { + LOCK(cs_vNodes); + for (CNode* node : vNodes) { + delete node; + } + vNodes.clear(); + } + + void ProcessMessagesOnce(CNode& node) { m_msgproc->ProcessMessages(&node, flagInterruptMsgProc); } + + void NodeReceiveMsgBytes(CNode& node, const char* pch, unsigned int nBytes, bool& complete) const; + + bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const; +}; + +#endif // BITCOIN_TEST_UTIL_NET_H diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index d684b97787..a4d0126925 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -139,6 +139,11 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME); m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests. m_node.peer_logic = MakeUnique<PeerLogicValidation>(m_node.connman.get(), m_node.banman.get(), *m_node.scheduler, *m_node.mempool); + { + CConnman::Options options; + options.m_msgproc = m_node.peer_logic.get(); + m_node.connman->Init(options); + } } TestingSetup::~TestingSetup() |