LCOV - code coverage report
Current view: top level - src - protocol.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 36 122 29.5 %
Date: 2024-01-03 14:57:27 Functions: 0 15 0.0 %
Branches: 36 188 19.1 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2                 :            : // Copyright (c) 2009-2022 The Bitcoin Core developers
       3                 :            : // Distributed under the MIT software license, see the accompanying
       4                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5                 :            : 
       6                 :            : #include <protocol.h>
       7                 :            : 
       8                 :            : #include <common/system.h>
       9                 :            : 
      10                 :            : #include <atomic>
      11                 :            : 
      12                 :            : static std::atomic<bool> g_initial_block_download_completed(false);
      13                 :            : 
      14                 :            : namespace NetMsgType {
      15                 :            : const char* VERSION = "version";
      16                 :            : const char* VERACK = "verack";
      17                 :            : const char* ADDR = "addr";
      18                 :            : const char* ADDRV2 = "addrv2";
      19                 :            : const char* SENDADDRV2 = "sendaddrv2";
      20                 :            : const char* INV = "inv";
      21                 :            : const char* GETDATA = "getdata";
      22                 :            : const char* MERKLEBLOCK = "merkleblock";
      23                 :            : const char* GETBLOCKS = "getblocks";
      24                 :            : const char* GETHEADERS = "getheaders";
      25                 :            : const char* TX = "tx";
      26                 :            : const char* HEADERS = "headers";
      27                 :            : const char* BLOCK = "block";
      28                 :            : const char* GETADDR = "getaddr";
      29                 :            : const char* MEMPOOL = "mempool";
      30                 :            : const char* PING = "ping";
      31                 :            : const char* PONG = "pong";
      32                 :            : const char* NOTFOUND = "notfound";
      33                 :            : const char* FILTERLOAD = "filterload";
      34                 :            : const char* FILTERADD = "filteradd";
      35                 :            : const char* FILTERCLEAR = "filterclear";
      36                 :            : const char* SENDHEADERS = "sendheaders";
      37                 :            : const char* FEEFILTER = "feefilter";
      38                 :            : const char* SENDCMPCT = "sendcmpct";
      39                 :            : const char* CMPCTBLOCK = "cmpctblock";
      40                 :            : const char* GETBLOCKTXN = "getblocktxn";
      41                 :            : const char* BLOCKTXN = "blocktxn";
      42                 :            : const char* GETCFILTERS = "getcfilters";
      43                 :            : const char* CFILTER = "cfilter";
      44                 :            : const char* GETCFHEADERS = "getcfheaders";
      45                 :            : const char* CFHEADERS = "cfheaders";
      46                 :            : const char* GETCFCHECKPT = "getcfcheckpt";
      47                 :            : const char* CFCHECKPT = "cfcheckpt";
      48                 :            : const char* WTXIDRELAY = "wtxidrelay";
      49                 :            : const char* SENDTXRCNCL = "sendtxrcncl";
      50                 :            : } // namespace NetMsgType
      51                 :          0 : 
      52                 :          0 : /** All known message types. Keep this in the same order as the list of
      53                 :          0 :  * messages above and in protocol.h.
      54                 :            :  */
      55 [ +  - ][ #  # ]:          2 : const static std::vector<std::string> g_all_net_message_types{
      56         [ +  - ]:          2 :     NetMsgType::VERSION,
      57         [ +  - ]:          2 :     NetMsgType::VERACK,
      58         [ +  - ]:          2 :     NetMsgType::ADDR,
      59         [ +  - ]:          2 :     NetMsgType::ADDRV2,
      60         [ +  - ]:          2 :     NetMsgType::SENDADDRV2,
      61         [ +  - ]:          2 :     NetMsgType::INV,
      62         [ +  - ]:          2 :     NetMsgType::GETDATA,
      63         [ +  - ]:          2 :     NetMsgType::MERKLEBLOCK,
      64         [ +  - ]:          2 :     NetMsgType::GETBLOCKS,
      65         [ +  - ]:          2 :     NetMsgType::GETHEADERS,
      66         [ +  - ]:          2 :     NetMsgType::TX,
      67         [ +  - ]:          2 :     NetMsgType::HEADERS,
      68         [ +  - ]:          2 :     NetMsgType::BLOCK,
      69         [ +  - ]:          2 :     NetMsgType::GETADDR,
      70         [ +  - ]:          2 :     NetMsgType::MEMPOOL,
      71         [ +  - ]:          2 :     NetMsgType::PING,
      72         [ +  - ]:          2 :     NetMsgType::PONG,
      73         [ +  - ]:          2 :     NetMsgType::NOTFOUND,
      74         [ +  - ]:          2 :     NetMsgType::FILTERLOAD,
      75         [ +  - ]:          2 :     NetMsgType::FILTERADD,
      76         [ +  - ]:          2 :     NetMsgType::FILTERCLEAR,
      77         [ +  - ]:          2 :     NetMsgType::SENDHEADERS,
      78         [ +  - ]:          2 :     NetMsgType::FEEFILTER,
      79         [ +  - ]:          2 :     NetMsgType::SENDCMPCT,
      80         [ +  - ]:          2 :     NetMsgType::CMPCTBLOCK,
      81         [ +  - ]:          2 :     NetMsgType::GETBLOCKTXN,
      82         [ +  - ]:          2 :     NetMsgType::BLOCKTXN,
      83         [ +  - ]:          2 :     NetMsgType::GETCFILTERS,
      84         [ +  - ]:          2 :     NetMsgType::CFILTER,
      85         [ +  - ]:          2 :     NetMsgType::GETCFHEADERS,
      86         [ +  - ]:          2 :     NetMsgType::CFHEADERS,
      87         [ +  - ]:          2 :     NetMsgType::GETCFCHECKPT,
      88         [ +  - ]:          2 :     NetMsgType::CFCHECKPT,
      89         [ +  - ]:          2 :     NetMsgType::WTXIDRELAY,
      90         [ +  - ]:          2 :     NetMsgType::SENDTXRCNCL,
      91                 :            : };
      92                 :            : 
      93                 :          0 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
      94                 :          0 :     : pchMessageStart{pchMessageStartIn}
      95                 :            : {
      96                 :            :     // Copy the command name
      97                 :          0 :     size_t i = 0;
      98 [ #  # ][ #  # ]:          0 :     for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
      99         [ #  # ]:          0 :     assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
     100                 :            : 
     101                 :          0 :     nMessageSize = nMessageSizeIn;
     102                 :          0 : }
     103                 :            : 
     104                 :          0 : std::string CMessageHeader::GetCommand() const
     105                 :            : {
     106         [ #  # ]:          0 :     return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
     107                 :          0 : }
     108                 :            : 
     109                 :          0 : bool CMessageHeader::IsCommandValid() const
     110                 :            : {
     111                 :            :     // Check the command string for errors
     112         [ #  # ]:          0 :     for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; ++p1) {
     113         [ #  # ]:          0 :         if (*p1 == 0) {
     114                 :            :             // Must be all zeros after the first zero
     115         [ #  # ]:          0 :             for (; p1 < pchCommand + COMMAND_SIZE; ++p1) {
     116         [ #  # ]:          0 :                 if (*p1 != 0) {
     117                 :          0 :                     return false;
     118                 :            :                 }
     119                 :          0 :             }
     120 [ #  # ][ #  # ]:          0 :         } else if (*p1 < ' ' || *p1 > 0x7E) {
     121                 :          0 :             return false;
     122                 :            :         }
     123                 :          0 :     }
     124                 :            : 
     125                 :          0 :     return true;
     126                 :          0 : }
     127                 :            : 
     128                 :            : 
     129                 :          0 : ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
     130 [ #  # ][ #  # ]:          0 :     if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
     131                 :          0 :         return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
     132                 :            :     }
     133                 :          0 :     return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
     134                 :          0 : }
     135                 :            : 
     136                 :          0 : void SetServiceFlagsIBDCache(bool state) {
     137                 :          0 :     g_initial_block_download_completed = state;
     138                 :          0 : }
     139                 :            : 
     140                 :          0 : CInv::CInv()
     141                 :            : {
     142                 :          0 :     type = 0;
     143                 :          0 :     hash.SetNull();
     144                 :          0 : }
     145                 :            : 
     146                 :          0 : CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
     147                 :            : 
     148                 :          0 : bool operator<(const CInv& a, const CInv& b)
     149                 :            : {
     150 [ #  # ][ #  # ]:          0 :     return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
     151                 :            : }
     152                 :            : 
     153                 :          0 : std::string CInv::GetCommand() const
     154                 :            : {
     155                 :          0 :     std::string cmd;
     156         [ #  # ]:          0 :     if (type & MSG_WITNESS_FLAG)
     157         [ #  # ]:          0 :         cmd.append("witness-");
     158                 :          0 :     int masked = type & MSG_TYPE_MASK;
     159   [ #  #  #  #  :          0 :     switch (masked)
                   #  # ]
     160                 :            :     {
     161 [ #  # ][ #  # ]:          0 :     case MSG_TX:             return cmd.append(NetMsgType::TX);
     162                 :            :     // WTX is not a message type, just an inv type
     163 [ #  # ][ #  # ]:          0 :     case MSG_WTX:            return cmd.append("wtx");
     164 [ #  # ][ #  # ]:          0 :     case MSG_BLOCK:          return cmd.append(NetMsgType::BLOCK);
     165 [ #  # ][ #  # ]:          0 :     case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
     166 [ #  # ][ #  # ]:          0 :     case MSG_CMPCT_BLOCK:    return cmd.append(NetMsgType::CMPCTBLOCK);
     167                 :            :     default:
     168 [ #  # ][ #  # ]:          0 :         throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
         [ #  # ][ #  # ]
     169                 :            :     }
     170                 :          0 : }
     171                 :            : 
     172                 :          0 : std::string CInv::ToString() const
     173                 :            : {
     174                 :            :     try {
     175 [ #  # ][ #  # ]:          0 :         return strprintf("%s %s", GetCommand(), hash.ToString());
                 [ #  # ]
     176         [ #  # ]:          0 :     } catch(const std::out_of_range &) {
     177 [ #  # ][ #  # ]:          0 :         return strprintf("0x%08x %s", type, hash.ToString());
     178         [ #  # ]:          0 :     }
     179                 :          0 : }
     180                 :            : 
     181                 :          0 : const std::vector<std::string> &getAllNetMessageTypes()
     182                 :            : {
     183                 :          0 :     return g_all_net_message_types;
     184                 :            : }
     185                 :            : 
     186                 :            : /**
     187                 :            :  * Convert a service flag (NODE_*) to a human readable string.
     188                 :            :  * It supports unknown service flags which will be returned as "UNKNOWN[...]".
     189                 :            :  * @param[in] bit the service flag is calculated as (1 << bit)
     190                 :            :  */
     191                 :          0 : static std::string serviceFlagToStr(size_t bit)
     192                 :            : {
     193                 :          0 :     const uint64_t service_flag = 1ULL << bit;
     194   [ #  #  #  #  :          0 :     switch ((ServiceFlags)service_flag) {
             #  #  #  # ]
     195                 :          0 :     case NODE_NONE: abort();  // impossible
     196         [ #  # ]:          0 :     case NODE_NETWORK:         return "NETWORK";
     197         [ #  # ]:          0 :     case NODE_BLOOM:           return "BLOOM";
     198         [ #  # ]:          0 :     case NODE_WITNESS:         return "WITNESS";
     199         [ #  # ]:          0 :     case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
     200         [ #  # ]:          0 :     case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
     201         [ #  # ]:          0 :     case NODE_P2P_V2:          return "P2P_V2";
     202                 :            :     // Not using default, so we get warned when a case is missing
     203                 :            :     }
     204                 :            : 
     205                 :          0 :     return strprintf("UNKNOWN[2^%u]", bit);
     206                 :          0 : }
     207                 :            : 
     208                 :          0 : std::vector<std::string> serviceFlagsToStr(uint64_t flags)
     209                 :            : {
     210                 :          0 :     std::vector<std::string> str_flags;
     211                 :            : 
     212         [ #  # ]:          0 :     for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
     213         [ #  # ]:          0 :         if (flags & (1ULL << i)) {
     214 [ #  # ][ #  # ]:          0 :             str_flags.emplace_back(serviceFlagToStr(i));
     215                 :          0 :         }
     216                 :          0 :     }
     217                 :            : 
     218                 :          0 :     return str_flags;
     219         [ #  # ]:          0 : }
     220                 :            : 
     221                 :          0 : GenTxid ToGenTxid(const CInv& inv)
     222                 :            : {
     223         [ #  # ]:          0 :     assert(inv.IsGenTxMsg());
     224         [ #  # ]:          0 :     return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash);
     225                 :            : }

Generated by: LCOV version 1.14