Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2015 The Bitcoin developers
3 : // Copyright (c) 2014-2021 The Dash Core developers
4 : // Copyright (c) 2016-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 : #ifndef __cplusplus
9 : #error This header can only be compiled as C++.
10 : #endif
11 :
12 : #ifndef PIVX_PROTOCOL_H
13 : #define PIVX_PROTOCOL_H
14 :
15 : #include "netaddress.h"
16 : #include "serialize.h"
17 : #include "streams.h"
18 : #include "uint256.h"
19 : #include "version.h"
20 :
21 : #include <stdint.h>
22 : #include <string>
23 :
24 : /** Message header.
25 : * (4) message start.
26 : * (12) command.
27 : * (4) size.
28 : * (4) checksum.
29 : */
30 : class CMessageHeader
31 : {
32 : public:
33 : static constexpr size_t MESSAGE_START_SIZE = 4;
34 : static constexpr size_t COMMAND_SIZE = 12;
35 : static constexpr size_t MESSAGE_SIZE_SIZE = 4;
36 : static constexpr size_t CHECKSUM_SIZE = 4;
37 : static constexpr size_t MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE;
38 : static constexpr size_t CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE;
39 : static constexpr size_t HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE;
40 : typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
41 :
42 : explicit CMessageHeader(const MessageStartChars& pchMessageStartIn);
43 :
44 : /** Construct a P2P message header from message-start characters, a command and the size of the message.
45 : * @note Passing in a `pszCommand` longer than COMMAND_SIZE will result in a run-time assertion error.
46 : */
47 : CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn);
48 :
49 : std::string GetCommand() const;
50 : bool IsValid(const MessageStartChars& messageStart) const;
51 :
52 708622 : SERIALIZE_METHODS(CMessageHeader, obj) { READWRITE(obj.pchMessageStart, obj.pchCommand, obj.nMessageSize, obj.pchChecksum); }
53 :
54 : char pchMessageStart[MESSAGE_START_SIZE];
55 : char pchCommand[COMMAND_SIZE];
56 : uint32_t nMessageSize;
57 : uint8_t pchChecksum[CHECKSUM_SIZE];
58 : };
59 :
60 : /**
61 : * Bitcoin protocol message types. When adding new message types, don't forget
62 : * to update allNetMessageTypes in protocol.cpp.
63 : */
64 : namespace NetMsgType
65 : {
66 : /**
67 : * The version message provides information about the transmitting node to the
68 : * receiving node at the beginning of a connection.
69 : * @see https://bitcoin.org/en/developer-reference#version
70 : */
71 : extern const char* VERSION;
72 : /**
73 : * The verack message acknowledges a previously-received version message,
74 : * informing the connecting node that it can begin to send other messages.
75 : * @see https://bitcoin.org/en/developer-reference#verack
76 : */
77 : extern const char* VERACK;
78 : /**
79 : * The addr (IP address) message relays connection information for peers on the
80 : * network.
81 : * @see https://bitcoin.org/en/developer-reference#addr
82 : */
83 : extern const char* ADDR;
84 : /**
85 : * The addrv2 message relays connection information for peers on the network just
86 : * like the addr message, but is extended to allow gossiping of longer node
87 : * addresses (see BIP155).
88 : */
89 : extern const char *ADDRV2;
90 : /**
91 : * The sendaddrv2 message signals support for receiving ADDRV2 messages (BIP155).
92 : * It also implies that its sender can encode as ADDRV2 and would send ADDRV2
93 : * instead of ADDR to a peer that has signaled ADDRV2 support by sending SENDADDRV2.
94 : */
95 : extern const char *SENDADDRV2;
96 : /**
97 : * The inv message (inventory message) transmits one or more inventories of
98 : * objects known to the transmitting peer.
99 : * @see https://bitcoin.org/en/developer-reference#inv
100 : */
101 : extern const char* INV;
102 : /**
103 : * The getdata message requests one or more data objects from another node.
104 : * @see https://bitcoin.org/en/developer-reference#getdata
105 : */
106 : extern const char* GETDATA;
107 : /**
108 : * The merkleblock message is a reply to a getdata message which requested a
109 : * block using the inventory type MSG_MERKLEBLOCK.
110 : * @since protocol version 70001 as described by BIP37.
111 : * @see https://bitcoin.org/en/developer-reference#merkleblock
112 : */
113 : extern const char* MERKLEBLOCK;
114 : /**
115 : * The getblocks message requests an inv message that provides block header
116 : * hashes starting from a particular point in the block chain.
117 : * @see https://bitcoin.org/en/developer-reference#getblocks
118 : */
119 : extern const char* GETBLOCKS;
120 : /**
121 : * The getheaders message requests a headers message that provides block
122 : * headers starting from a particular point in the block chain.
123 : * @since protocol version 31800.
124 : * @see https://bitcoin.org/en/developer-reference#getheaders
125 : */
126 : extern const char* GETHEADERS;
127 : /**
128 : * The tx message transmits a single transaction.
129 : * @see https://bitcoin.org/en/developer-reference#tx
130 : */
131 : extern const char* TX;
132 : /**
133 : * The headers message sends one or more block headers to a node which
134 : * previously requested certain headers with a getheaders message.
135 : * @since protocol version 31800.
136 : * @see https://bitcoin.org/en/developer-reference#headers
137 : */
138 : extern const char* HEADERS;
139 : /**
140 : * The block message transmits a single serialized block.
141 : * @see https://bitcoin.org/en/developer-reference#block
142 : */
143 : extern const char* BLOCK;
144 : /**
145 : * The getaddr message requests an addr message from the receiving node,
146 : * preferably one with lots of IP addresses of other receiving nodes.
147 : * @see https://bitcoin.org/en/developer-reference#getaddr
148 : */
149 : extern const char* GETADDR;
150 : /**
151 : * The mempool message requests the TXIDs of transactions that the receiving
152 : * node has verified as valid but which have not yet appeared in a block.
153 : * @since protocol version 60002.
154 : * @see https://bitcoin.org/en/developer-reference#mempool
155 : */
156 : extern const char* MEMPOOL;
157 : /**
158 : * The ping message is sent periodically to help confirm that the receiving
159 : * peer is still connected.
160 : * @see https://bitcoin.org/en/developer-reference#ping
161 : */
162 : extern const char* PING;
163 : /**
164 : * The pong message replies to a ping message, proving to the pinging node that
165 : * the ponging node is still alive.
166 : * @since protocol version 60001 as described by BIP31.
167 : * @see https://bitcoin.org/en/developer-reference#pong
168 : */
169 : extern const char* PONG;
170 : /**
171 : * The alert message warns nodes of problems that may affect them or the rest
172 : * of the network.
173 : * @since protocol version 311.
174 : * @see https://bitcoin.org/en/developer-reference#alert
175 : */
176 : extern const char* ALERT;
177 : /**
178 : * The notfound message is a reply to a getdata message which requested an
179 : * object the receiving node does not have available for relay.
180 : * @ince protocol version 70001.
181 : * @see https://bitcoin.org/en/developer-reference#notfound
182 : */
183 : extern const char* NOTFOUND;
184 : /**
185 : * The filterload message tells the receiving peer to filter all relayed
186 : * transactions and requested merkle blocks through the provided filter.
187 : * @since protocol version 70001 as described by BIP37.
188 : * Only available with service bit NODE_BLOOM since protocol version
189 : * 70011 as described by BIP111.
190 : * @see https://bitcoin.org/en/developer-reference#filterload
191 : */
192 : extern const char* FILTERLOAD;
193 : /**
194 : * The filteradd message tells the receiving peer to add a single element to a
195 : * previously-set bloom filter, such as a new public key.
196 : * @since protocol version 70001 as described by BIP37.
197 : * Only available with service bit NODE_BLOOM since protocol version
198 : * 70011 as described by BIP111.
199 : * @see https://bitcoin.org/en/developer-reference#filteradd
200 : */
201 : extern const char* FILTERADD;
202 : /**
203 : * The filterclear message tells the receiving peer to remove a previously-set
204 : * bloom filter.
205 : * @since protocol version 70001 as described by BIP37.
206 : * Only available with service bit NODE_BLOOM since protocol version
207 : * 70011 as described by BIP111.
208 : * @see https://bitcoin.org/en/developer-reference#filterclear
209 : */
210 : extern const char* FILTERCLEAR;
211 : /**
212 : * Indicates that a node prefers to receive new block announcements via a
213 : * "headers" message rather than an "inv".
214 : * @since protocol version 70012 as described by BIP130.
215 : * @see https://bitcoin.org/en/developer-reference#sendheaders
216 : */
217 : extern const char* SENDHEADERS;
218 : /**
219 : * The spork message is used to send spork values to connected
220 : * peers
221 : */
222 : extern const char* SPORK;
223 : /**
224 : * The getsporks message is used to request spork data from connected peers
225 : */
226 : extern const char* GETSPORKS;
227 : /**
228 : * The mnbroadcast message is used to broadcast masternode startup data to connected peers
229 : */
230 : extern const char* MNBROADCAST;
231 : /**
232 : * The mnbroadcast2 message is used to broadcast masternode startup data to connected peers
233 : * Supporting BIP155 node addresses.
234 : */
235 : extern const char* MNBROADCAST2;
236 : /**
237 : * The mnping message is used to ensure a masternode is still active
238 : */
239 : extern const char* MNPING;
240 : /**
241 : * The mnwinner message is used to relay and distribute consensus for masternode
242 : * payout ordering
243 : */
244 : extern const char* MNWINNER;
245 : /**
246 : * The getmnwinners message is used to request winning masternode data from connected peers
247 : */
248 : extern const char* GETMNWINNERS;
249 : /**
250 : * The dseg message is used to request the Masternode list or an specific entry
251 : */
252 : extern const char* GETMNLIST;
253 : /**
254 : * The budgetproposal message is used to broadcast or relay budget proposal metadata to connected peers
255 : */
256 : extern const char* BUDGETPROPOSAL;
257 : /**
258 : * The budgetvote message is used to broadcast or relay budget proposal votes to connected peers
259 : */
260 : extern const char* BUDGETVOTE;
261 : /**
262 : * The budgetvotesync message is used to request budget vote data from connected peers
263 : */
264 : extern const char* BUDGETVOTESYNC;
265 : /**
266 : * The finalbudget message is used to broadcast or relay finalized budget metadata to connected peers
267 : */
268 : extern const char* FINALBUDGET;
269 : /**
270 : * The finalbudgetvote message is used to broadcast or relay finalized budget votes to connected peers
271 : */
272 : extern const char* FINALBUDGETVOTE;
273 : /**
274 : * The syncstatuscount message is used to track the layer 2 syncing process
275 : */
276 : extern const char* SYNCSTATUSCOUNT;
277 : /**
278 : * The qfcommit message is used to propagate LLMQ final commitments
279 : */
280 : extern const char* QFCOMMITMENT;
281 : /**
282 : * The qsendrecsigs message is used to propagate LLMQ intra-quorum partial recovered signatures
283 : */
284 : extern const char* QSENDRECSIGS;
285 : /**
286 : * The mnauth message is used authenticate MN connections
287 : */
288 : extern const char* MNAUTH;
289 : /*
290 : * Messages for LLMQ-DKG inter-quorum communication
291 : */
292 : extern const char* QCONTRIB;
293 : extern const char* QCOMPLAINT;
294 : extern const char* QJUSTIFICATION;
295 : extern const char* QPCOMMITMENT;
296 : extern const char* QSIGSESANN;
297 : extern const char* QSIGSHARESINV;
298 : extern const char* QGETSIGSHARES;
299 : extern const char* QBSIGSHARES;
300 : extern const char* QSIGREC;
301 : extern const char* QSIGSHARE;
302 : extern const char* CLSIG;
303 : }; // namespace NetMsgType
304 :
305 : /* Get a vector of all valid message types (see above) */
306 : const std::vector<std::string>& getAllNetMessageTypes();
307 :
308 : /* Get a vector of all tier two valid message types (see above) */
309 : const std::vector<std::string>& getTierTwoNetMessageTypes();
310 :
311 : /** nServices flags */
312 : enum ServiceFlags : uint64_t {
313 : // Nothing
314 : NODE_NONE = 0,
315 : // NODE_NETWORK means that the node is capable of serving the block chain. It is currently
316 : // set by all Bitcoin Core nodes, and is unset by SPV clients or other peers that just want
317 : // network services but don't provide them.
318 : NODE_NETWORK = (1 << 0),
319 :
320 : // NODE_BLOOM means the node is capable and willing to handle bloom-filtered connections.
321 : NODE_BLOOM = (1 << 2),
322 :
323 : // NODE_BLOOM_WITHOUT_MN means the node has the same features as NODE_BLOOM with the only difference
324 : // that the node doesn't want to receive master nodes messages. (the 1<<3 was not picked as constant because on bitcoin 0.14 is witness and we want that update here )
325 : NODE_BLOOM_WITHOUT_MN = (1 << 4),
326 :
327 : // Bits 24-31 are reserved for temporary experiments. Just pick a bit that
328 : // isn't getting used, or one not being used much, and notify the
329 : // bitcoin-development mailing list. Remember that service bits are just
330 : // unauthenticated advertisements, so your code must be robust against
331 : // collisions and other cases where nodes may be advertising a service they
332 : // do not actually support. Other service bits should be allocated via the
333 : // BIP process.
334 : };
335 :
336 : /** A CService with information about it as peer */
337 185475 : class CAddress : public CService
338 : {
339 : static constexpr uint32_t TIME_INIT{100000000};
340 :
341 : /** Historically, CAddress disk serialization stored the CLIENT_VERSION, optionally OR'ed with
342 : * the ADDRV2_FORMAT flag to indicate V2 serialization. The first field has since been
343 : * disentangled from client versioning, and now instead:
344 : * - The low bits (masked by DISK_VERSION_IGNORE_MASK) store the fixed value DISK_VERSION_INIT,
345 : * (in case any code exists that treats it as a client version) but are ignored on
346 : * deserialization.
347 : * - The high bits (masked by ~DISK_VERSION_IGNORE_MASK) store actual serialization information.
348 : * Only 0 or DISK_VERSION_ADDRV2 (equal to the historical ADDRV2_FORMAT) are valid now, and
349 : * any other value triggers a deserialization failure. Other values can be added later if
350 : * needed.
351 : *
352 : * For disk deserialization, ADDRV2_FORMAT in the stream version signals that ADDRV2
353 : * deserialization is permitted, but the actual format is determined by the high bits in the
354 : * stored version field. For network serialization, the stream version having ADDRV2_FORMAT or
355 : * not determines the actual format used (as it has no embedded version number).
356 : */
357 : static constexpr uint32_t DISK_VERSION_INIT{220000};
358 : static constexpr uint32_t DISK_VERSION_IGNORE_MASK{0b00000000'00000111'11111111'11111111};
359 : /** The version number written in disk serialized addresses to indicate V2 serializations.
360 : * It must be exactly 1<<29, as that is the value that historical versions used for this
361 : * (they used their internal ADDRV2_FORMAT flag here). */
362 : static constexpr uint32_t DISK_VERSION_ADDRV2{1 << 29};
363 : static_assert((DISK_VERSION_INIT & ~DISK_VERSION_IGNORE_MASK) == 0, "DISK_VERSION_INIT must be covered by DISK_VERSION_IGNORE_MASK");
364 : static_assert((DISK_VERSION_ADDRV2 & DISK_VERSION_IGNORE_MASK) == 0, "DISK_VERSION_ADDRV2 must not be covered by DISK_VERSION_IGNORE_MASK");
365 :
366 : public:
367 209122 : CAddress() : CService{} {};
368 21867 : CAddress(CService ipIn, ServiceFlags nServicesIn) : CService{ipIn}, nServices{nServicesIn} {};
369 : CAddress(CService ipIn, ServiceFlags nServicesIn, uint32_t nTimeIn) : CService{ipIn}, nTime{nTimeIn}, nServices{nServicesIn} {};
370 :
371 57495 : SERIALIZE_METHODS(CAddress, obj)
372 : {
373 : // CAddress has a distinct network serialization and a disk serialization, but it should never
374 : // be hashed (except through CHashWriter in addrdb.cpp, which sets SER_DISK), and it's
375 : // ambiguous what that would mean. Make sure no code relying on that is introduced:
376 27012 : assert(!(s.GetType() & SER_GETHASH));
377 : bool use_v2;
378 : bool store_time;
379 27012 : if (s.GetType() & SER_DISK) {
380 : // In the disk serialization format, the encoding (v1 or v2) is determined by a flag version
381 : // that's part of the serialization itself. ADDRV2_FORMAT in the stream version only determines
382 : // whether V2 is chosen/permitted at all.
383 17976 : uint32_t stored_format_version = DISK_VERSION_INIT;
384 17976 : if (s.GetVersion() & ADDRV2_FORMAT) stored_format_version |= DISK_VERSION_ADDRV2;
385 17974 : READWRITE(stored_format_version);
386 17974 : stored_format_version &= ~DISK_VERSION_IGNORE_MASK; // ignore low bits
387 17974 : if (stored_format_version == 0) {
388 : use_v2 = false;
389 17970 : } else if (stored_format_version == DISK_VERSION_ADDRV2 && (s.GetVersion() & ADDRV2_FORMAT)) {
390 : // Only support v2 deserialization if ADDRV2_FORMAT is set.
391 : use_v2 = true;
392 : } else {
393 0 : throw std::ios_base::failure("Unsupported CAddress disk format version");
394 : }
395 17966 : store_time = true;
396 : } else {
397 : // In the network serialization format, the encoding (v1 or v2) is determined directly by
398 : // the value of ADDRV2_FORMAT in the stream version, as no explicitly encoded version
399 : // exists in the stream.
400 9036 : assert(s.GetType() & SER_NETWORK);
401 9036 : use_v2 = s.GetVersion() & ADDRV2_FORMAT;
402 : // The only time we serialize a CAddress object without nTime is in
403 : // the initial VERSION messages which contain two CAddress records.
404 : // At that point, the serialization version is INIT_PROTO_VERSION.
405 : // After the version handshake, serialization version is >=
406 : // MIN_PEER_PROTO_VERSION and all ADDR messages are serialized with
407 : // nTime.
408 9036 : store_time = s.GetVersion() != INIT_PROTO_VERSION;
409 : }
410 :
411 27010 : SER_READ(obj, obj.nTime = TIME_INIT);
412 27010 : if (store_time) READWRITE(obj.nTime);
413 : // nServices is serialized as CompactSize in V2; as uint64_t in V1.
414 27010 : if (use_v2) {
415 : uint64_t services_tmp;
416 19019 : SER_WRITE(obj, services_tmp = obj.nServices);
417 19019 : READWRITE(Using<CompactSizeFormatter<false>>(services_tmp));
418 19019 : SER_READ(obj, obj.nServices = static_cast<ServiceFlags>(services_tmp));
419 : } else {
420 7991 : READWRITE(Using<CustomUintFormatter<8>>(obj.nServices));
421 : }
422 : // Invoke V1/V2 serializer for CService parent object.
423 35001 : OverrideStream<Stream> os(&s, s.GetType(), use_v2 ? ADDRV2_FORMAT : 0);
424 27010 : SerReadWriteMany(os, ser_action, ReadWriteAsHelper<CService>(obj));
425 27009 : }
426 :
427 : //! Always included in serialization, except in the network format on INIT_PROTO_VERSION.
428 : uint32_t nTime{TIME_INIT};
429 : //! Serialized as uint64_t in V1, and as CompactSize in V2.
430 : ServiceFlags nServices{NODE_NONE};
431 : };
432 :
433 : /** getdata message types */
434 : enum GetDataMsg {
435 : UNDEFINED = 0,
436 : MSG_TX,
437 : MSG_BLOCK,
438 : // Nodes may always request a MSG_FILTERED_BLOCK in a getdata, however,
439 : // MSG_FILTERED_BLOCK should not appear in any invs except as a part of getdata.
440 : MSG_FILTERED_BLOCK,
441 : MSG_TXLOCK_REQUEST, // Deprecated
442 : MSG_TXLOCK_VOTE, // Deprecated
443 : MSG_SPORK,
444 : MSG_MASTERNODE_WINNER,
445 : MSG_MASTERNODE_SCANNING_ERROR,
446 : MSG_BUDGET_VOTE,
447 : MSG_BUDGET_PROPOSAL,
448 : MSG_BUDGET_FINALIZED,
449 : MSG_BUDGET_FINALIZED_VOTE,
450 : MSG_MASTERNODE_QUORUM,
451 : MSG_MASTERNODE_ANNOUNCE,
452 : MSG_MASTERNODE_PING,
453 : MSG_DSTX, // Deprecated
454 : MSG_QUORUM_FINAL_COMMITMENT,
455 : MSG_QUORUM_CONTRIB,
456 : MSG_QUORUM_COMPLAINT,
457 : MSG_QUORUM_JUSTIFICATION,
458 : MSG_QUORUM_PREMATURE_COMMITMENT,
459 : MSG_QUORUM_RECOVERED_SIG,
460 : MSG_CLSIG,
461 : MSG_TYPE_MAX = MSG_CLSIG,
462 : };
463 :
464 : /** inv message data */
465 : class CInv
466 : {
467 : public:
468 : CInv();
469 : CInv(int typeIn, const uint256& hashIn);
470 :
471 1490480 : SERIALIZE_METHODS(CInv, obj) { READWRITE(obj.type, obj.hash); }
472 :
473 : friend bool operator<(const CInv& a, const CInv& b);
474 :
475 : bool IsMasterNodeType() const;
476 : std::string ToString() const;
477 :
478 : // TODO: make private (improve encapsulation)
479 : int type;
480 : uint256 hash;
481 :
482 : private:
483 : std::string GetCommand() const;
484 : };
485 :
486 : #endif // PIVX_PROTOCOL_H
|