LCOV - code coverage report
Current view: top level - src - protocol.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 63 122 51.6 %
Date: 2023-10-05 12:38:51 Functions: 6 16 37.5 %
Branches: 54 188 28.7 %

           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                 :       3489 : } // namespace NetMsgType
      51                 :       3489 : 
      52                 :       3489 : /** All known message types. Keep this in the same order as the list of
      53                 :       3489 :  * 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         [ +  - ]:          4 :     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                 :       3489 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
      94                 :            : {
      95                 :       3489 :     pchMessageStart = pchMessageStartIn;
      96                 :            : 
      97                 :            :     // Copy the command name
      98                 :       3489 :     size_t i = 0;
      99   [ +  +  +  + ]:      23777 :     for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
     100         [ +  - ]:       3489 :     assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
     101                 :            : 
     102                 :       3489 :     nMessageSize = nMessageSizeIn;
     103                 :       3489 : }
     104                 :            : 
     105                 :         64 : std::string CMessageHeader::GetCommand() const
     106                 :            : {
     107         [ +  - ]:         64 :     return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
     108                 :          0 : }
     109                 :            : 
     110                 :         28 : bool CMessageHeader::IsCommandValid() const
     111                 :            : {
     112                 :            :     // Check the command string for errors
     113         [ +  + ]:        231 :     for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; ++p1) {
     114         [ +  + ]:        213 :         if (*p1 == 0) {
     115                 :            :             // Must be all zeros after the first zero
     116         [ +  + ]:         85 :             for (; p1 < pchCommand + COMMAND_SIZE; ++p1) {
     117         [ +  + ]:         74 :                 if (*p1 != 0) {
     118                 :          5 :                     return false;
     119                 :            :                 }
     120                 :         69 :             }
     121   [ +  +  +  + ]:        208 :         } else if (*p1 < ' ' || *p1 > 0x7E) {
     122                 :          5 :             return false;
     123                 :            :         }
     124                 :        203 :     }
     125                 :            : 
     126                 :         18 :     return true;
     127                 :         28 : }
     128                 :            : 
     129                 :            : 
     130                 :          0 : ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
     131   [ #  #  #  # ]:          0 :     if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
     132                 :          0 :         return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
     133                 :            :     }
     134                 :          0 :     return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
     135                 :          0 : }
     136                 :            : 
     137                 :          0 : void SetServiceFlagsIBDCache(bool state) {
     138                 :          0 :     g_initial_block_download_completed = state;
     139                 :          0 : }
     140                 :            : 
     141                 :          0 : CInv::CInv()
     142                 :            : {
     143                 :          0 :     type = 0;
     144                 :          0 :     hash.SetNull();
     145                 :          0 : }
     146                 :            : 
     147                 :          0 : CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
     148                 :            : 
     149                 :          0 : bool operator<(const CInv& a, const CInv& b)
     150                 :            : {
     151   [ #  #  #  # ]:          0 :     return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
     152                 :            : }
     153                 :            : 
     154                 :          0 : std::string CInv::GetCommand() const
     155                 :            : {
     156                 :          0 :     std::string cmd;
     157         [ #  # ]:          0 :     if (type & MSG_WITNESS_FLAG)
     158         [ #  # ]:          0 :         cmd.append("witness-");
     159                 :          0 :     int masked = type & MSG_TYPE_MASK;
     160   [ #  #  #  #  :          0 :     switch (masked)
                   #  # ]
     161                 :            :     {
     162   [ #  #  #  # ]:          0 :     case MSG_TX:             return cmd.append(NetMsgType::TX);
     163                 :            :     // WTX is not a message type, just an inv type
     164   [ #  #  #  # ]:          0 :     case MSG_WTX:            return cmd.append("wtx");
     165   [ #  #  #  # ]:          0 :     case MSG_BLOCK:          return cmd.append(NetMsgType::BLOCK);
     166   [ #  #  #  # ]:          0 :     case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
     167   [ #  #  #  # ]:          0 :     case MSG_CMPCT_BLOCK:    return cmd.append(NetMsgType::CMPCTBLOCK);
     168                 :            :     default:
     169   [ #  #  #  #  :          0 :         throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
             #  #  #  # ]
     170                 :            :     }
     171                 :          0 : }
     172                 :            : 
     173                 :          0 : std::string CInv::ToString() const
     174                 :            : {
     175                 :            :     try {
     176   [ #  #  #  #  :          0 :         return strprintf("%s %s", GetCommand(), hash.ToString());
                   #  # ]
     177         [ #  # ]:          0 :     } catch(const std::out_of_range &) {
     178   [ #  #  #  # ]:          0 :         return strprintf("0x%08x %s", type, hash.ToString());
     179         [ #  # ]:          0 :     }
     180                 :          0 : }
     181                 :            : 
     182                 :      12442 : const std::vector<std::string> &getAllNetMessageTypes()
     183                 :            : {
     184                 :      12442 :     return g_all_net_message_types;
     185                 :            : }
     186                 :            : 
     187                 :            : /**
     188                 :            :  * Convert a service flag (NODE_*) to a human readable string.
     189                 :            :  * It supports unknown service flags which will be returned as "UNKNOWN[...]".
     190                 :            :  * @param[in] bit the service flag is calculated as (1 << bit)
     191                 :            :  */
     192                 :          0 : static std::string serviceFlagToStr(size_t bit)
     193                 :            : {
     194                 :          0 :     const uint64_t service_flag = 1ULL << bit;
     195   [ #  #  #  #  :          0 :     switch ((ServiceFlags)service_flag) {
             #  #  #  # ]
     196                 :          0 :     case NODE_NONE: abort();  // impossible
     197         [ #  # ]:          0 :     case NODE_NETWORK:         return "NETWORK";
     198         [ #  # ]:          0 :     case NODE_BLOOM:           return "BLOOM";
     199         [ #  # ]:          0 :     case NODE_WITNESS:         return "WITNESS";
     200         [ #  # ]:          0 :     case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
     201         [ #  # ]:          0 :     case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
     202         [ #  # ]:          0 :     case NODE_P2P_V2:          return "P2P_V2";
     203                 :            :     // Not using default, so we get warned when a case is missing
     204                 :            :     }
     205                 :            : 
     206                 :          0 :     return strprintf("UNKNOWN[2^%u]", bit);
     207                 :          0 : }
     208                 :            : 
     209                 :          0 : std::vector<std::string> serviceFlagsToStr(uint64_t flags)
     210                 :            : {
     211                 :          0 :     std::vector<std::string> str_flags;
     212                 :            : 
     213         [ #  # ]:          0 :     for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
     214         [ #  # ]:          0 :         if (flags & (1ULL << i)) {
     215   [ #  #  #  # ]:          0 :             str_flags.emplace_back(serviceFlagToStr(i));
     216                 :          0 :         }
     217                 :          0 :     }
     218                 :            : 
     219                 :          0 :     return str_flags;
     220         [ #  # ]:          0 : }
     221                 :            : 
     222                 :          0 : GenTxid ToGenTxid(const CInv& inv)
     223                 :            : {
     224         [ #  # ]:          0 :     assert(inv.IsGenTxMsg());
     225         [ #  # ]:          0 :     return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash);
     226                 :            : }

Generated by: LCOV version 1.14