1 // Copyright (c) 2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <banman.h>
6 #include <chainparams.h>
7 #include <consensus/consensus.h>
8 #include <net.h>
9 #include <net_processing.h>
10 #include <protocol.h>
11 #include <scheduler.h>
12 #include <script/script.h>
13 #include <streams.h>
14 #include <test/fuzz/FuzzedDataProvider.h>
15 #include <test/fuzz/fuzz.h>
16 #include <test/util/mining.h>
17 #include <test/util/net.h>
18 #include <test/util/setup_common.h>
19 #include <test/util/validation.h>
20 #include <util/memory.h>
21 #include <validationinterface.h>
22 #include <version.h>
23
24 #include <atomic>
25 #include <cassert>
26 #include <chrono>
27 #include <cstdint>
28 #include <iosfwd>
29 #include <iostream>
30 #include <memory>
31 #include <string>
32 #include <vector>
33
34 namespace {
35
36 #ifdef MESSAGE_TYPE
37 #define TO_STRING_(s) #s
38 #define TO_STRING(s) TO_STRING_(s)
39 const std::string LIMIT_TO_MESSAGE_TYPE{TO_STRING(MESSAGE_TYPE)};
40 #else
41 const std::string LIMIT_TO_MESSAGE_TYPE;
42 #endif
43
44 const TestingSetup* g_setup;
45 } // namespace
46
initialize()47 void initialize()
48 {
49 static TestingSetup setup{
50 CBaseChainParams::REGTEST,
51 {
52 "-nodebuglogfile",
53 },
54 };
55 g_setup = &setup;
56
57 for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
58 MineBlock(g_setup->m_node, CScript() << OP_TRUE);
59 }
60 SyncWithValidationInterfaceQueue();
61 }
62
test_one_input(const std::vector<uint8_t> & buffer)63 void test_one_input(const std::vector<uint8_t>& buffer)
64 {
65 FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
66 ConnmanTestMsg& connman = *(ConnmanTestMsg*)g_setup->m_node.connman.get();
67 TestChainState& chainstate = *(TestChainState*)&g_setup->m_node.chainman->ActiveChainstate();
68 chainstate.ResetIbd();
69 const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()};
70 if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) {
71 return;
72 }
73 const bool jump_out_of_ibd{fuzzed_data_provider.ConsumeBool()};
74 if (jump_out_of_ibd) chainstate.JumpOutOfIbd();
75 CDataStream random_bytes_data_stream{fuzzed_data_provider.ConsumeRemainingBytes<unsigned char>(), SER_NETWORK, PROTOCOL_VERSION};
76 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();
77 p2p_node.fSuccessfullyConnected = true;
78 p2p_node.nVersion = PROTOCOL_VERSION;
79 p2p_node.SetCommonVersion(PROTOCOL_VERSION);
80 connman.AddTestNode(p2p_node);
81 g_setup->m_node.peerman->InitializeNode(&p2p_node);
82 try {
83 g_setup->m_node.peerman->ProcessMessage(p2p_node, random_message_type, random_bytes_data_stream,
84 GetTime<std::chrono::microseconds>(), std::atomic<bool>{false});
85 } catch (const std::ios_base::failure&) {
86 }
87 SyncWithValidationInterfaceQueue();
88 LOCK2(::cs_main, g_cs_orphans); // See init.cpp for rationale for implicit locking order requirement
89 g_setup->m_node.connman->StopNodes();
90 }
91