|
| 1 | +// Copyright (c) 2026-present The Dash 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 <protocol.h> |
| 8 | +#include <script/script.h> |
| 9 | +#include <sync.h> |
| 10 | +#include <test/fuzz/FuzzedDataProvider.h> |
| 11 | +#include <test/fuzz/fuzz.h> |
| 12 | +#include <test/fuzz/util.h> |
| 13 | +#include <test/util/mining.h> |
| 14 | +#include <test/util/net.h> |
| 15 | +#include <test/util/setup_common.h> |
| 16 | +#include <test/util/validation.h> |
| 17 | +#include <validationinterface.h> |
| 18 | + |
| 19 | +#include <algorithm> |
| 20 | +#include <array> |
| 21 | +#include <cstdlib> |
| 22 | +#include <memory> |
| 23 | +#include <string_view> |
| 24 | + |
| 25 | +namespace { |
| 26 | +const TestingSetup* g_setup; |
| 27 | +std::string_view LIMIT_TO_MESSAGE_TYPE{}; |
| 28 | + |
| 29 | +const std::array<const char*, 41> DASH_MESSAGE_TYPES{ |
| 30 | + NetMsgType::SPORK, |
| 31 | + NetMsgType::GETSPORKS, |
| 32 | + NetMsgType::DSACCEPT, |
| 33 | + NetMsgType::DSVIN, |
| 34 | + NetMsgType::DSFINALTX, |
| 35 | + NetMsgType::DSSIGNFINALTX, |
| 36 | + NetMsgType::DSCOMPLETE, |
| 37 | + NetMsgType::DSSTATUSUPDATE, |
| 38 | + NetMsgType::DSTX, |
| 39 | + NetMsgType::DSQUEUE, |
| 40 | + NetMsgType::SENDDSQUEUE, |
| 41 | + NetMsgType::SYNCSTATUSCOUNT, |
| 42 | + NetMsgType::MNGOVERNANCESYNC, |
| 43 | + NetMsgType::MNGOVERNANCEOBJECT, |
| 44 | + NetMsgType::MNGOVERNANCEOBJECTVOTE, |
| 45 | + NetMsgType::GETMNLISTDIFF, |
| 46 | + NetMsgType::MNLISTDIFF, |
| 47 | + NetMsgType::QSENDRECSIGS, |
| 48 | + NetMsgType::QFCOMMITMENT, |
| 49 | + NetMsgType::QCONTRIB, |
| 50 | + NetMsgType::QCOMPLAINT, |
| 51 | + NetMsgType::QJUSTIFICATION, |
| 52 | + NetMsgType::QPCOMMITMENT, |
| 53 | + NetMsgType::QWATCH, |
| 54 | + NetMsgType::QSIGSESANN, |
| 55 | + NetMsgType::QSIGSHARESINV, |
| 56 | + NetMsgType::QGETSIGSHARES, |
| 57 | + NetMsgType::QBSIGSHARES, |
| 58 | + NetMsgType::QSIGREC, |
| 59 | + NetMsgType::QSIGSHARE, |
| 60 | + NetMsgType::QGETDATA, |
| 61 | + NetMsgType::QDATA, |
| 62 | + NetMsgType::CLSIG, |
| 63 | + NetMsgType::ISDLOCK, |
| 64 | + NetMsgType::MNAUTH, |
| 65 | + NetMsgType::GETHEADERS2, |
| 66 | + NetMsgType::SENDHEADERS2, |
| 67 | + NetMsgType::HEADERS2, |
| 68 | + NetMsgType::GETQUORUMROTATIONINFO, |
| 69 | + NetMsgType::QUORUMROTATIONINFO, |
| 70 | + NetMsgType::PLATFORMBAN, |
| 71 | +}; |
| 72 | +} // namespace |
| 73 | + |
| 74 | +void initialize_process_message_dash() |
| 75 | +{ |
| 76 | + if (const auto val{std::getenv("LIMIT_TO_MESSAGE_TYPE")}) { |
| 77 | + LIMIT_TO_MESSAGE_TYPE = val; |
| 78 | + Assert(std::count(DASH_MESSAGE_TYPES.begin(), DASH_MESSAGE_TYPES.end(), LIMIT_TO_MESSAGE_TYPE)); // Unknown message type passed |
| 79 | + } |
| 80 | + |
| 81 | + static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>( |
| 82 | + /*chain_name=*/CBaseChainParams::REGTEST, |
| 83 | + /*extra_args=*/{"-txreconciliation"}); |
| 84 | + g_setup = testing_setup.get(); |
| 85 | + for (int i = 0; i < 2 * COINBASE_MATURITY; i++) { |
| 86 | + MineBlock(g_setup->m_node, CScript() << OP_TRUE); |
| 87 | + } |
| 88 | + SyncWithValidationInterfaceQueue(); |
| 89 | +} |
| 90 | + |
| 91 | +FUZZ_TARGET(process_message_dash, .init = initialize_process_message_dash) |
| 92 | +{ |
| 93 | + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); |
| 94 | + |
| 95 | + ConnmanTestMsg& connman = *static_cast<ConnmanTestMsg*>(g_setup->m_node.connman.get()); |
| 96 | + TestChainState& chainstate = *static_cast<TestChainState*>(&g_setup->m_node.chainman->ActiveChainstate()); |
| 97 | + SetMockTime(1610000000); // any time to successfully reset ibd |
| 98 | + chainstate.ResetIbd(); |
| 99 | + |
| 100 | + LOCK(NetEventsInterface::g_msgproc_mutex); |
| 101 | + |
| 102 | + CNode& p2p_node = *ConsumeNodeAsUniquePtr(fuzzed_data_provider).release(); |
| 103 | + |
| 104 | + connman.AddTestNode(p2p_node); |
| 105 | + FillNode(fuzzed_data_provider, connman, p2p_node); |
| 106 | + |
| 107 | + const auto mock_time = ConsumeTime(fuzzed_data_provider); |
| 108 | + SetMockTime(mock_time); |
| 109 | + |
| 110 | + CSerializedNetMsg net_msg; |
| 111 | + net_msg.m_type = fuzzed_data_provider.PickValueInArray(DASH_MESSAGE_TYPES); |
| 112 | + if (!LIMIT_TO_MESSAGE_TYPE.empty() && net_msg.m_type != LIMIT_TO_MESSAGE_TYPE) { |
| 113 | + return; |
| 114 | + } |
| 115 | + net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider, MAX_PROTOCOL_MESSAGE_LENGTH); |
| 116 | + |
| 117 | + connman.FlushSendBuffer(p2p_node); |
| 118 | + (void)connman.ReceiveMsgFrom(p2p_node, std::move(net_msg)); |
| 119 | + |
| 120 | + bool more_work{true}; |
| 121 | + LIMITED_WHILE(more_work, 10000) |
| 122 | + { |
| 123 | + p2p_node.fPauseSend = false; |
| 124 | + try { |
| 125 | + more_work = connman.ProcessMessagesOnce(p2p_node); |
| 126 | + } catch (const std::ios_base::failure&) { |
| 127 | + more_work = false; |
| 128 | + } |
| 129 | + g_setup->m_node.peerman->SendMessages(&p2p_node); |
| 130 | + } |
| 131 | + SyncWithValidationInterfaceQueue(); |
| 132 | + g_setup->m_node.connman->StopNodes(); |
| 133 | +} |
0 commit comments