Skip to content

Commit 98860cf

Browse files
committed
test(fuzz): add Dash P2P message processing fuzz target
Fuzz target for Dash-specific network message handling: - Tests ProcessMessage() with Dash message types: mnb, mnp, dsq, dstx, govsync, govobj, ix, txlvote, mnget, mnw, qsigshare, qsigrec, clsig, islock, isdlock - Exercises deserialization and initial validation of each message type through the P2P processing pipeline
1 parent d38d7f9 commit 98860cf

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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

Comments
 (0)