Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin developers
3 : // Copyright (c) 2014-2021 The Dash Core developers
4 : // Copyright (c) 2017-2022 The PIVX Core developers
5 : // Distributed under the MIT/X11 software license, see the accompanying
6 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 :
8 : #include "protocol.h"
9 :
10 : #include "util/system.h"
11 : #include "utilstrencodings.h"
12 :
13 : #ifndef WIN32
14 : #include <arpa/inet.h>
15 : #endif
16 :
17 : namespace NetMsgType
18 : {
19 : const char* VERSION = "version";
20 : const char* VERACK = "verack";
21 : const char* ADDR = "addr";
22 : const char* ADDRV2="addrv2";
23 : const char* SENDADDRV2="sendaddrv2";
24 : const char* INV = "inv";
25 : const char* GETDATA = "getdata";
26 : const char* MERKLEBLOCK = "merkleblock";
27 : const char* GETBLOCKS = "getblocks";
28 : const char* GETHEADERS = "getheaders";
29 : const char* TX = "tx";
30 : const char* HEADERS = "headers";
31 : const char* BLOCK = "block";
32 : const char* GETADDR = "getaddr";
33 : const char* MEMPOOL = "mempool";
34 : const char* PING = "ping";
35 : const char* PONG = "pong";
36 : const char* ALERT = "alert";
37 : const char* NOTFOUND = "notfound";
38 : const char* FILTERLOAD = "filterload";
39 : const char* FILTERADD = "filteradd";
40 : const char* FILTERCLEAR = "filterclear";
41 : const char* SENDHEADERS = "sendheaders";
42 : const char* SPORK = "spork";
43 : const char* GETSPORKS = "getsporks";
44 : const char* MNBROADCAST = "mnb";
45 : const char* MNBROADCAST2 = "mnb2"; // BIP155 support
46 : const char* MNPING = "mnp";
47 : const char* MNWINNER = "mnw";
48 : const char* GETMNWINNERS = "mnget";
49 : const char* BUDGETPROPOSAL = "mprop";
50 : const char* BUDGETVOTE = "mvote";
51 : const char* BUDGETVOTESYNC = "mnvs";
52 : const char* FINALBUDGET = "fbs";
53 : const char* FINALBUDGETVOTE = "fbvote";
54 : const char* SYNCSTATUSCOUNT = "ssc";
55 : const char* GETMNLIST = "dseg";
56 : const char* QFCOMMITMENT = "qfcommit";
57 : const char* QSENDRECSIGS = "qsendrecsigs";
58 : const char* MNAUTH = "mnauth";
59 : const char* QCONTRIB = "qcontrib";
60 : const char* QCOMPLAINT = "qcomplaint";
61 : const char* QJUSTIFICATION = "qjustify";
62 : const char* QPCOMMITMENT = "qpcommit";
63 : const char* QSIGSESANN = "qsigsesann";
64 : const char* QSIGSHARESINV = "qsigsinv";
65 : const char* QGETSIGSHARES = "qgetsigs";
66 : const char* QBSIGSHARES = "qbsigs";
67 : const char* QSIGREC = "qsigrec";
68 : const char* QSIGSHARE = "qsigshare";
69 : const char* CLSIG = "clsig";
70 : }; // namespace NetMsgType
71 :
72 :
73 : /** All known message types. Keep this in the same order as the list of
74 : * messages above and in protocol.h.
75 : */
76 : const static std::string allNetMessageTypes[] = {
77 : NetMsgType::VERSION,
78 : NetMsgType::VERACK,
79 : NetMsgType::ADDR,
80 : NetMsgType::ADDRV2,
81 : NetMsgType::SENDADDRV2,
82 : NetMsgType::INV,
83 : NetMsgType::GETDATA,
84 : NetMsgType::MERKLEBLOCK,
85 : NetMsgType::GETBLOCKS,
86 : NetMsgType::GETHEADERS,
87 : NetMsgType::TX,
88 : NetMsgType::HEADERS,
89 : NetMsgType::BLOCK,
90 : NetMsgType::GETADDR,
91 : NetMsgType::MEMPOOL,
92 : NetMsgType::PING,
93 : NetMsgType::PONG,
94 : NetMsgType::ALERT,
95 : NetMsgType::NOTFOUND,
96 : NetMsgType::FILTERLOAD,
97 : NetMsgType::FILTERADD,
98 : NetMsgType::FILTERCLEAR,
99 : NetMsgType::SENDHEADERS,
100 : "filtered block", // Should never occur
101 : "ix", // deprecated
102 : "txlvote", // deprecated
103 : NetMsgType::SPORK, // --- tiertwoNetMessageTypes start here ---
104 : NetMsgType::MNWINNER,
105 : "mnodescanerr",
106 : NetMsgType::BUDGETVOTE,
107 : NetMsgType::BUDGETPROPOSAL,
108 : NetMsgType::FINALBUDGET,
109 : NetMsgType::FINALBUDGETVOTE,
110 : "mnq",
111 : NetMsgType::MNBROADCAST,
112 : NetMsgType::MNPING,
113 : "dstx", // deprecated
114 : NetMsgType::GETMNWINNERS,
115 : NetMsgType::GETMNLIST,
116 : NetMsgType::BUDGETVOTESYNC,
117 : NetMsgType::GETSPORKS,
118 : NetMsgType::SYNCSTATUSCOUNT,
119 : NetMsgType::MNBROADCAST2,
120 : NetMsgType::QFCOMMITMENT,
121 : NetMsgType::QSENDRECSIGS,
122 : NetMsgType::MNAUTH,
123 : NetMsgType::QCONTRIB,
124 : NetMsgType::QCOMPLAINT,
125 : NetMsgType::QJUSTIFICATION,
126 : NetMsgType::QPCOMMITMENT,
127 : NetMsgType::QSIGSESANN,
128 : NetMsgType::QSIGSHARESINV,
129 : NetMsgType::QGETSIGSHARES,
130 : NetMsgType::QBSIGSHARES,
131 : NetMsgType::QSIGREC,
132 : NetMsgType::QSIGSHARE,
133 : NetMsgType::CLSIG,
134 : };
135 : const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes + ARRAYLEN(allNetMessageTypes));
136 : const static std::vector<std::string> tiertwoNetMessageTypesVec(std::find(allNetMessageTypesVec.begin(), allNetMessageTypesVec.end(), NetMsgType::SPORK), allNetMessageTypesVec.end());
137 :
138 379156 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
139 : {
140 379156 : memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
141 379156 : memset(pchCommand, 0, sizeof(pchCommand));
142 379156 : nMessageSize = -1;
143 379156 : memset(pchChecksum, 0, CHECKSUM_SIZE);
144 379156 : }
145 :
146 329466 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
147 : {
148 329466 : memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
149 :
150 : // Copy the command name, zero-padding to COMMAND_SIZE bytes
151 329466 : size_t i = 0;
152 1636610 : for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
153 329466 : assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
154 2975920 : for (; i < COMMAND_SIZE; ++i) pchCommand[i] = 0;
155 :
156 329466 : nMessageSize = nMessageSizeIn;
157 329466 : memset(pchChecksum, 0, CHECKSUM_SIZE);
158 329466 : }
159 :
160 378830 : std::string CMessageHeader::GetCommand() const
161 : {
162 378830 : return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
163 : }
164 :
165 378829 : bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
166 : {
167 : // Check start string
168 378829 : if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
169 : return false;
170 :
171 : // Check the command string for errors
172 2210630 : for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) {
173 1831800 : if (*p1 == 0) {
174 : // Must be all zeros after the first zero
175 3471580 : for (; p1 < pchCommand + COMMAND_SIZE; p1++)
176 3092860 : if (*p1 != 0)
177 : return false;
178 1453080 : } else if (*p1 < ' ' || *p1 > 0x7E)
179 : return false;
180 : }
181 :
182 : // Message size
183 378828 : if (nMessageSize > MAX_SIZE) {
184 0 : LogPrintf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
185 0 : return false;
186 : }
187 :
188 : return true;
189 : }
190 :
191 899027 : CInv::CInv()
192 : {
193 899027 : type = 0;
194 899027 : hash.SetNull();
195 899027 : }
196 :
197 640758 : CInv::CInv(int typeIn, const uint256& hashIn)
198 : {
199 640758 : type = typeIn;
200 640758 : hash = hashIn;
201 640758 : }
202 :
203 2691260 : bool operator<(const CInv& a, const CInv& b)
204 : {
205 2691260 : return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
206 : }
207 :
208 0 : bool CInv::IsMasterNodeType() const{
209 0 : return type > 2;
210 : }
211 :
212 461138 : std::string CInv::GetCommand() const
213 : {
214 922276 : std::string cmd;
215 461138 : switch (type) {
216 33913 : case MSG_TX: return cmd.append(NetMsgType::TX);
217 215441 : case MSG_BLOCK: return cmd.append(NetMsgType::BLOCK);
218 0 : case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
219 0 : case MSG_TXLOCK_REQUEST: return cmd.append("ix"); // Deprecated
220 0 : case MSG_TXLOCK_VOTE: return cmd.append("txlvote"); // Deprecated
221 2755 : case MSG_SPORK: return cmd.append(NetMsgType::SPORK);
222 6277 : case MSG_MASTERNODE_WINNER: return cmd.append(NetMsgType::MNWINNER);
223 0 : case MSG_MASTERNODE_SCANNING_ERROR: return cmd.append("mnodescanerr"); // Deprecated
224 555 : case MSG_BUDGET_VOTE: return cmd.append(NetMsgType::BUDGETVOTE);
225 5974 : case MSG_BUDGET_PROPOSAL: return cmd.append(NetMsgType::BUDGETPROPOSAL);
226 385 : case MSG_BUDGET_FINALIZED: return cmd.append(NetMsgType::FINALBUDGET);
227 526 : case MSG_BUDGET_FINALIZED_VOTE: return cmd.append(NetMsgType::FINALBUDGETVOTE);
228 0 : case MSG_MASTERNODE_QUORUM: return cmd.append("mnq"); // Unused
229 502 : case MSG_MASTERNODE_ANNOUNCE: return cmd.append(NetMsgType::MNBROADCAST); // or MNBROADCAST2
230 165324 : case MSG_MASTERNODE_PING: return cmd.append(NetMsgType::MNPING);
231 0 : case MSG_DSTX: return cmd.append("dstx"); // Deprecated
232 2230 : case MSG_QUORUM_FINAL_COMMITMENT: return cmd.append(NetMsgType::QFCOMMITMENT);
233 727 : case MSG_QUORUM_CONTRIB: return cmd.append(NetMsgType::QCONTRIB);
234 175 : case MSG_QUORUM_COMPLAINT: return cmd.append(NetMsgType::QCOMPLAINT);
235 48 : case MSG_QUORUM_JUSTIFICATION: return cmd.append(NetMsgType::QJUSTIFICATION);
236 611 : case MSG_QUORUM_PREMATURE_COMMITMENT: return cmd.append(NetMsgType::QPCOMMITMENT);
237 12582 : case MSG_QUORUM_RECOVERED_SIG: return cmd.append(NetMsgType::QSIGREC);
238 474251 : case MSG_CLSIG: return cmd.append(NetMsgType::CLSIG);
239 0 : default:
240 0 : throw std::out_of_range(strprintf("%s: type=%d unknown type", __func__, type));
241 : }
242 : }
243 :
244 :
245 461138 : std::string CInv::ToString() const
246 : {
247 1383410 : return strprintf("%s %s", GetCommand(), hash.ToString());
248 : }
249 :
250 1464 : const std::vector<std::string>& getAllNetMessageTypes()
251 : {
252 1464 : return allNetMessageTypesVec;
253 : }
254 :
255 88106 : const std::vector<std::string>& getTierTwoNetMessageTypes()
256 : {
257 88106 : return tiertwoNetMessageTypesVec;
258 : }
|