LCOV - code coverage report
Current view: top level - src - protocol.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 31 110 28.2 %
Date: 2024-05-24 10:43:37 Functions: 7 13 53.8 %
Branches: 22 185 11.9 %

           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                 :      87022 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
      11                 :      87022 :     : pchMessageStart{pchMessageStartIn}
      12                 :            : {
      13                 :            :     // Copy the command name
      14                 :      87022 :     size_t i = 0;
      15   [ +  +  +  + ]:     678990 :     for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
      16         [ +  - ]:      87022 :     assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
      17                 :            : 
      18                 :      87022 :     nMessageSize = nMessageSizeIn;
      19                 :      87022 : }
      20                 :            : 
      21                 :      52933 : std::string CMessageHeader::GetCommand() const
      22                 :            : {
      23         [ +  - ]:      52933 :     return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
      24                 :          0 : }
      25                 :            : 
      26                 :      52933 : bool CMessageHeader::IsCommandValid() const
      27                 :            : {
      28                 :            :     // Check the command string for errors
      29   [ +  +  -  +  :     393482 :     for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; ++p1) {
                      + ]
      30         [ +  + ]:     340549 :         if (*p1 == 0) {
      31                 :            :             // Must be all zeros after the first zero
      32         [ +  + ]:     334946 :             for (; p1 < pchCommand + COMMAND_SIZE; ++p1) {
      33         [ -  + ]:     288953 :                 if (*p1 != 0) {
      34                 :          0 :                     return false;
      35                 :            :                 }
      36                 :     288953 :             }
      37   [ +  +  +  + ]:     340549 :         } else if (*p1 < ' ' || *p1 > 0x7E) {
      38                 :       5733 :             return false;
      39                 :            :         }
      40                 :     334816 :     }
      41                 :            : 
      42                 :      47200 :     return true;
      43                 :      52933 : }
      44                 :            : 
      45                 :      30714 : CInv::CInv()
      46                 :            : {
      47                 :      30714 :     type = 0;
      48                 :      30714 :     hash.SetNull();
      49                 :      30714 : }
      50                 :            : 
      51                 :     138411 : CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
      52                 :      87022 : 
      53                 :      87022 : bool operator<(const CInv& a, const CInv& b)
      54                 :            : {
      55   [ #  #  #  # ]:          0 :     return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
      56                 :            : }
      57                 :            : 
      58                 :          0 : std::string CInv::GetCommand() const
      59                 :            : {
      60                 :          0 :     std::string cmd;
      61         [ #  # ]:          0 :     if (type & MSG_WITNESS_FLAG)
      62         [ #  # ]:          0 :         cmd.append("witness-");
      63                 :          0 :     int masked = type & MSG_TYPE_MASK;
      64   [ #  #  #  #  :          0 :     switch (masked)
                   #  # ]
      65                 :            :     {
      66   [ #  #  #  # ]:          0 :     case MSG_TX:             return cmd.append(NetMsgType::TX);
      67                 :            :     // WTX is not a message type, just an inv type
      68   [ #  #  #  # ]:          0 :     case MSG_WTX:            return cmd.append("wtx");
      69   [ #  #  #  # ]:          0 :     case MSG_BLOCK:          return cmd.append(NetMsgType::BLOCK);
      70   [ #  #  #  # ]:          0 :     case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
      71   [ #  #  #  # ]:          0 :     case MSG_CMPCT_BLOCK:    return cmd.append(NetMsgType::CMPCTBLOCK);
      72                 :            :     default:
      73   [ #  #  #  #  :          0 :         throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
             #  #  #  # ]
      74                 :          3 :     }
      75                 :          0 : }
      76                 :            : 
      77                 :          0 : std::string CInv::ToString() const
      78                 :            : {
      79                 :            :     try {
      80   [ #  #  #  #  :          0 :         return strprintf("%s %s", GetCommand(), hash.ToString());
                   #  # ]
      81         [ #  # ]:          0 :     } catch(const std::out_of_range &) {
      82   [ #  #  #  # ]:          0 :         return strprintf("0x%08x %s", type, hash.ToString());
      83         [ #  # ]:          0 :     }
      84                 :          0 : }
      85                 :            : 
      86                 :            : /**
      87                 :            :  * Convert a service flag (NODE_*) to a human readable string.
      88                 :            :  * It supports unknown service flags which will be returned as "UNKNOWN[...]".
      89                 :            :  * @param[in] bit the service flag is calculated as (1 << bit)
      90                 :            :  */
      91                 :          0 : static std::string serviceFlagToStr(size_t bit)
      92                 :            : {
      93                 :          0 :     const uint64_t service_flag = 1ULL << bit;
      94   [ #  #  #  #  :          0 :     switch ((ServiceFlags)service_flag) {
             #  #  #  # ]
      95                 :          0 :     case NODE_NONE: abort();  // impossible
      96         [ #  # ]:          0 :     case NODE_NETWORK:         return "NETWORK";
      97         [ #  # ]:          0 :     case NODE_BLOOM:           return "BLOOM";
      98         [ #  # ]:          0 :     case NODE_WITNESS:         return "WITNESS";
      99         [ #  # ]:          0 :     case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
     100         [ #  # ]:          0 :     case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
     101         [ #  # ]:          0 :     case NODE_P2P_V2:          return "P2P_V2";
     102                 :            :     // Not using default, so we get warned when a case is missing
     103                 :            :     }
     104                 :            : 
     105                 :          0 :     return strprintf("UNKNOWN[2^%u]", bit);
     106                 :          0 : }
     107                 :            : 
     108                 :          0 : std::vector<std::string> serviceFlagsToStr(uint64_t flags)
     109                 :            : {
     110                 :          0 :     std::vector<std::string> str_flags;
     111                 :            : 
     112         [ #  # ]:          0 :     for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
     113         [ #  # ]:          0 :         if (flags & (1ULL << i)) {
     114   [ #  #  #  # ]:          0 :             str_flags.emplace_back(serviceFlagToStr(i));
     115                 :          0 :         }
     116                 :          0 :     }
     117                 :            : 
     118                 :          0 :     return str_flags;
     119         [ #  # ]:          0 : }
     120                 :            : 
     121                 :       1406 : GenTxid ToGenTxid(const CInv& inv)
     122                 :            : {
     123         [ +  - ]:       1406 :     assert(inv.IsGenTxMsg());
     124         [ +  + ]:       1406 :     return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash);
     125                 :            : }

Generated by: LCOV version 1.16