/root/bitcoin/src/test/fuzz/p2p_handshake.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2020-present 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 <addrman.h> |
6 | | #include <consensus/consensus.h> |
7 | | #include <net.h> |
8 | | #include <net_processing.h> |
9 | | #include <node/warnings.h> |
10 | | #include <protocol.h> |
11 | | #include <script/script.h> |
12 | | #include <sync.h> |
13 | | #include <test/fuzz/FuzzedDataProvider.h> |
14 | | #include <test/fuzz/fuzz.h> |
15 | | #include <test/fuzz/util.h> |
16 | | #include <test/fuzz/util/net.h> |
17 | | #include <test/util/mining.h> |
18 | | #include <test/util/net.h> |
19 | | #include <test/util/setup_common.h> |
20 | | #include <test/util/validation.h> |
21 | | #include <util/time.h> |
22 | | #include <validationinterface.h> |
23 | | |
24 | | #include <ios> |
25 | | #include <string> |
26 | | #include <utility> |
27 | | #include <vector> |
28 | | |
29 | | namespace { |
30 | | const TestingSetup* g_setup; |
31 | | |
32 | | void initialize() |
33 | 0 | { |
34 | 0 | static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>( |
35 | 0 | /*chain_type=*/ChainType::REGTEST); |
36 | 0 | g_setup = testing_setup.get(); |
37 | 0 | } |
38 | | } // namespace |
39 | | |
40 | | FUZZ_TARGET(p2p_handshake, .init = ::initialize) |
41 | 0 | { |
42 | 0 | FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); |
43 | |
|
44 | 0 | ConnmanTestMsg& connman = static_cast<ConnmanTestMsg&>(*g_setup->m_node.connman); |
45 | 0 | auto& chainman = static_cast<TestChainstateManager&>(*g_setup->m_node.chainman); |
46 | 0 | SetMockTime(1610000000); // any time to successfully reset ibd |
47 | 0 | chainman.ResetIbd(); |
48 | |
|
49 | 0 | node::Warnings warnings{}; |
50 | 0 | NetGroupManager netgroupman{{}}; |
51 | 0 | AddrMan addrman{netgroupman, /*deterministic=*/true, 0}; |
52 | 0 | auto peerman = PeerManager::make(connman, addrman, |
53 | 0 | /*banman=*/nullptr, chainman, |
54 | 0 | *g_setup->m_node.mempool, warnings, |
55 | 0 | PeerManager::Options{ |
56 | 0 | .reconcile_txs = true, |
57 | 0 | .deterministic_rng = true, |
58 | 0 | }); |
59 | 0 | connman.SetMsgProc(peerman.get()); |
60 | |
|
61 | 0 | LOCK(NetEventsInterface::g_msgproc_mutex); |
62 | |
|
63 | 0 | std::vector<CNode*> peers; |
64 | 0 | const auto num_peers_to_add = fuzzed_data_provider.ConsumeIntegralInRange(1, 3); |
65 | 0 | for (int i = 0; i < num_peers_to_add; ++i) { |
66 | 0 | peers.push_back(ConsumeNodeAsUniquePtr(fuzzed_data_provider, i).release()); |
67 | 0 | connman.AddTestNode(*peers.back()); |
68 | 0 | peerman->InitializeNode( |
69 | 0 | *peers.back(), |
70 | 0 | static_cast<ServiceFlags>(fuzzed_data_provider.ConsumeIntegral<uint64_t>())); |
71 | 0 | } |
72 | |
|
73 | 0 | LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 100) |
74 | 0 | { |
75 | 0 | CNode& connection = *PickValue(fuzzed_data_provider, peers); |
76 | 0 | if (connection.fDisconnect || connection.fSuccessfullyConnected) { |
77 | | // Skip if the connection was disconnected or if the version |
78 | | // handshake was already completed. |
79 | 0 | continue; |
80 | 0 | } |
81 | | |
82 | 0 | SetMockTime(GetTime() + |
83 | 0 | fuzzed_data_provider.ConsumeIntegralInRange<int64_t>( |
84 | 0 | -std::chrono::seconds{10min}.count(), // Allow mocktime to go backwards slightly |
85 | 0 | std::chrono::seconds{TIMEOUT_INTERVAL}.count())); |
86 | |
|
87 | 0 | CSerializedNetMsg net_msg; |
88 | 0 | net_msg.m_type = PickValue(fuzzed_data_provider, ALL_NET_MESSAGE_TYPES); |
89 | 0 | net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider, MAX_PROTOCOL_MESSAGE_LENGTH); |
90 | |
|
91 | 0 | connman.FlushSendBuffer(connection); |
92 | 0 | (void)connman.ReceiveMsgFrom(connection, std::move(net_msg)); |
93 | |
|
94 | 0 | bool more_work{true}; |
95 | 0 | while (more_work) { |
96 | 0 | connection.fPauseSend = false; |
97 | |
|
98 | 0 | try { |
99 | 0 | more_work = connman.ProcessMessagesOnce(connection); |
100 | 0 | } catch (const std::ios_base::failure&) { |
101 | 0 | } |
102 | 0 | peerman->SendMessages(&connection); |
103 | 0 | } |
104 | 0 | } |
105 | | |
106 | 0 | g_setup->m_node.connman->StopNodes(); |
107 | 0 | } |