/root/bitcoin/src/test/fuzz/process_message.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 <consensus/consensus.h> |
6 | | #include <net.h> |
7 | | #include <net_processing.h> |
8 | | #include <primitives/transaction.h> |
9 | | #include <protocol.h> |
10 | | #include <script/script.h> |
11 | | #include <sync.h> |
12 | | #include <test/fuzz/FuzzedDataProvider.h> |
13 | | #include <test/fuzz/fuzz.h> |
14 | | #include <test/fuzz/util.h> |
15 | | #include <test/fuzz/util/net.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/check.h> |
21 | | #include <util/time.h> |
22 | | #include <validationinterface.h> |
23 | | |
24 | | #include <cstdlib> |
25 | | #include <iostream> |
26 | | #include <memory> |
27 | | #include <string> |
28 | | #include <string_view> |
29 | | #include <vector> |
30 | | |
31 | | namespace { |
32 | | const TestingSetup* g_setup; |
33 | | std::string_view LIMIT_TO_MESSAGE_TYPE{}; |
34 | | } // namespace |
35 | | |
36 | | void initialize_process_message() |
37 | 0 | { |
38 | 0 | if (const auto val{std::getenv("LIMIT_TO_MESSAGE_TYPE")}) { |
39 | 0 | LIMIT_TO_MESSAGE_TYPE = val; |
40 | 0 | Assert(std::count(ALL_NET_MESSAGE_TYPES.begin(), ALL_NET_MESSAGE_TYPES.end(), LIMIT_TO_MESSAGE_TYPE)); // Unknown message type passed |
41 | 0 | } |
42 | |
|
43 | 0 | static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>( |
44 | 0 | /*chain_type=*/ChainType::REGTEST, |
45 | 0 | {.extra_args = {"-txreconciliation"}}); |
46 | 0 | g_setup = testing_setup.get(); |
47 | 0 | for (int i = 0; i < 2 * COINBASE_MATURITY; i++) { |
48 | 0 | MineBlock(g_setup->m_node, CScript() << OP_TRUE); |
49 | 0 | } |
50 | 0 | g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue(); |
51 | 0 | } |
52 | | |
53 | | FUZZ_TARGET(process_message, .init = initialize_process_message) |
54 | 0 | { |
55 | 0 | FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); |
56 | |
|
57 | 0 | ConnmanTestMsg& connman = *static_cast<ConnmanTestMsg*>(g_setup->m_node.connman.get()); |
58 | 0 | auto& chainman = static_cast<TestChainstateManager&>(*g_setup->m_node.chainman); |
59 | 0 | SetMockTime(1610000000); // any time to successfully reset ibd |
60 | 0 | chainman.ResetIbd(); |
61 | |
|
62 | 0 | LOCK(NetEventsInterface::g_msgproc_mutex); |
63 | |
|
64 | 0 | const std::string random_message_type{fuzzed_data_provider.ConsumeBytesAsString(CMessageHeader::COMMAND_SIZE).c_str()}; |
65 | 0 | if (!LIMIT_TO_MESSAGE_TYPE.empty() && random_message_type != LIMIT_TO_MESSAGE_TYPE) { |
66 | 0 | return; |
67 | 0 | } |
68 | 0 | CNode& p2p_node = *ConsumeNodeAsUniquePtr(fuzzed_data_provider).release(); |
69 | |
|
70 | 0 | connman.AddTestNode(p2p_node); |
71 | 0 | FillNode(fuzzed_data_provider, connman, p2p_node); |
72 | |
|
73 | 0 | const auto mock_time = ConsumeTime(fuzzed_data_provider); |
74 | 0 | SetMockTime(mock_time); |
75 | |
|
76 | 0 | CSerializedNetMsg net_msg; |
77 | 0 | net_msg.m_type = random_message_type; |
78 | 0 | net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider, MAX_PROTOCOL_MESSAGE_LENGTH); |
79 | |
|
80 | 0 | connman.FlushSendBuffer(p2p_node); |
81 | 0 | (void)connman.ReceiveMsgFrom(p2p_node, std::move(net_msg)); |
82 | |
|
83 | 0 | bool more_work{true}; |
84 | 0 | while (more_work) { |
85 | 0 | p2p_node.fPauseSend = false; |
86 | 0 | try { |
87 | 0 | more_work = connman.ProcessMessagesOnce(p2p_node); |
88 | 0 | } catch (const std::ios_base::failure&) { |
89 | 0 | } |
90 | 0 | g_setup->m_node.peerman->SendMessages(&p2p_node); |
91 | 0 | } |
92 | 0 | g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue(); |
93 | 0 | g_setup->m_node.connman->StopNodes(); |
94 | 0 | } |