LCOV - code coverage report
Current view: top level - src - protocol.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 28 29 96.6 %
Date: 2025-02-23 09:33:43 Functions: 9 10 90.0 %

          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

Generated by: LCOV version 1.14