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