LCOV - code coverage report
Current view: top level - src - protocol.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 123 131 93.9 %
Date: 2020-09-26 01:30:44 Functions: 21 22 95.5 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2019 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 <util/strencodings.h>
       9             : #include <util/system.h>
      10             : 
      11             : static std::atomic<bool> g_initial_block_download_completed(false);
      12             : 
      13             : namespace NetMsgType {
      14             : const char *VERSION="version";
      15             : const char *VERACK="verack";
      16             : const char *ADDR="addr";
      17             : const char *INV="inv";
      18             : const char *GETDATA="getdata";
      19             : const char *MERKLEBLOCK="merkleblock";
      20             : const char *GETBLOCKS="getblocks";
      21             : const char *GETHEADERS="getheaders";
      22             : const char *TX="tx";
      23             : const char *HEADERS="headers";
      24             : const char *BLOCK="block";
      25             : const char *GETADDR="getaddr";
      26             : const char *MEMPOOL="mempool";
      27             : const char *PING="ping";
      28             : const char *PONG="pong";
      29             : const char *NOTFOUND="notfound";
      30             : const char *FILTERLOAD="filterload";
      31             : const char *FILTERADD="filteradd";
      32             : const char *FILTERCLEAR="filterclear";
      33             : const char *SENDHEADERS="sendheaders";
      34             : const char *FEEFILTER="feefilter";
      35             : const char *SENDCMPCT="sendcmpct";
      36             : const char *CMPCTBLOCK="cmpctblock";
      37             : const char *GETBLOCKTXN="getblocktxn";
      38             : const char *BLOCKTXN="blocktxn";
      39             : const char *GETCFILTERS="getcfilters";
      40             : const char *CFILTER="cfilter";
      41             : const char *GETCFHEADERS="getcfheaders";
      42             : const char *CFHEADERS="cfheaders";
      43             : const char *GETCFCHECKPT="getcfcheckpt";
      44             : const char *CFCHECKPT="cfcheckpt";
      45             : const char *WTXIDRELAY="wtxidrelay";
      46             : } // namespace NetMsgType
      47             : 
      48             : /** All known message types. Keep this in the same order as the list of
      49             :  * messages above and in protocol.h.
      50             :  */
      51        1300 : const static std::string allNetMessageTypes[] = {
      52         650 :     NetMsgType::VERSION,
      53         650 :     NetMsgType::VERACK,
      54         650 :     NetMsgType::ADDR,
      55         650 :     NetMsgType::INV,
      56         650 :     NetMsgType::GETDATA,
      57         650 :     NetMsgType::MERKLEBLOCK,
      58         650 :     NetMsgType::GETBLOCKS,
      59         650 :     NetMsgType::GETHEADERS,
      60         650 :     NetMsgType::TX,
      61         650 :     NetMsgType::HEADERS,
      62         650 :     NetMsgType::BLOCK,
      63         650 :     NetMsgType::GETADDR,
      64         650 :     NetMsgType::MEMPOOL,
      65         650 :     NetMsgType::PING,
      66         650 :     NetMsgType::PONG,
      67         650 :     NetMsgType::NOTFOUND,
      68         650 :     NetMsgType::FILTERLOAD,
      69         650 :     NetMsgType::FILTERADD,
      70         650 :     NetMsgType::FILTERCLEAR,
      71         650 :     NetMsgType::SENDHEADERS,
      72         650 :     NetMsgType::FEEFILTER,
      73         650 :     NetMsgType::SENDCMPCT,
      74         650 :     NetMsgType::CMPCTBLOCK,
      75         650 :     NetMsgType::GETBLOCKTXN,
      76         650 :     NetMsgType::BLOCKTXN,
      77         650 :     NetMsgType::GETCFILTERS,
      78         650 :     NetMsgType::CFILTER,
      79         650 :     NetMsgType::GETCFHEADERS,
      80         650 :     NetMsgType::CFHEADERS,
      81         650 :     NetMsgType::GETCFCHECKPT,
      82         650 :     NetMsgType::CFCHECKPT,
      83       21450 :     NetMsgType::WTXIDRELAY,
      84             : };
      85         650 : const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));
      86             : 
      87        1458 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
      88         729 : {
      89         729 :     memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
      90         729 :     memset(pchCommand, 0, sizeof(pchCommand));
      91         729 :     nMessageSize = -1;
      92         729 :     memset(pchChecksum, 0, CHECKSUM_SIZE);
      93        1458 : }
      94             : 
      95      182536 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
      96       91268 : {
      97       91268 :     memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
      98             : 
      99             :     // Copy the command name, zero-padding to COMMAND_SIZE bytes
     100             :     size_t i = 0;
     101      631526 :     for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
     102       91268 :     assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
     103      646226 :     for (; i < COMMAND_SIZE; ++i) pchCommand[i] = 0;
     104             : 
     105       91268 :     nMessageSize = nMessageSizeIn;
     106       91268 :     memset(pchChecksum, 0, CHECKSUM_SIZE);
     107      182536 : }
     108             : 
     109       86838 : std::string CMessageHeader::GetCommand() const
     110             : {
     111       86838 :     return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
     112             : }
     113             : 
     114       86838 : bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
     115             : {
     116             :     // Check start string
     117       86838 :     if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
     118           1 :         return false;
     119             : 
     120             :     // Check the command string for errors
     121      708473 :     for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
     122             :     {
     123      621637 :         if (*p1 == 0)
     124             :         {
     125             :             // Must be all zeros after the first zero
     126      594048 :             for (; p1 < pchCommand + COMMAND_SIZE; p1++)
     127      507222 :                 if (*p1 != 0)
     128           0 :                     return false;
     129             :         }
     130      534811 :         else if (*p1 < ' ' || *p1 > 0x7E)
     131           1 :             return false;
     132             :     }
     133             : 
     134             :     // Message size
     135       86836 :     if (nMessageSize > MAX_SIZE)
     136             :     {
     137           0 :         LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
     138           0 :         return false;
     139             :     }
     140             : 
     141       86836 :     return true;
     142       86838 : }
     143             : 
     144             : 
     145         340 : ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
     146         340 :     if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
     147           0 :         return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
     148             :     }
     149         340 :     return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
     150         340 : }
     151             : 
     152       39878 : void SetServiceFlagsIBDCache(bool state) {
     153       39878 :     g_initial_block_download_completed = state;
     154       39878 : }
     155             : 
     156      405782 : CInv::CInv()
     157      202891 : {
     158      202891 :     type = 0;
     159      202891 :     hash.SetNull();
     160      405782 : }
     161             : 
     162      106644 : CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
     163             : 
     164           0 : bool operator<(const CInv& a, const CInv& b)
     165             : {
     166           0 :     return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
     167             : }
     168             : 
     169       44195 : std::string CInv::GetCommand() const
     170             : {
     171       44195 :     std::string cmd;
     172       44195 :     if (type & MSG_WITNESS_FLAG)
     173        5806 :         cmd.append("witness-");
     174       44195 :     int masked = type & MSG_TYPE_MASK;
     175       44195 :     switch (masked)
     176             :     {
     177          22 :     case MSG_TX:             return cmd.append(NetMsgType::TX);
     178             :     // WTX is not a message type, just an inv type
     179       28791 :     case MSG_WTX:            return cmd.append("wtx");
     180       15179 :     case MSG_BLOCK:          return cmd.append(NetMsgType::BLOCK);
     181           7 :     case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
     182         195 :     case MSG_CMPCT_BLOCK:    return cmd.append(NetMsgType::CMPCTBLOCK);
     183             :     default:
     184           1 :         throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
     185             :     }
     186       44195 : }
     187             : 
     188       44195 : std::string CInv::ToString() const
     189             : {
     190             :     try {
     191       44196 :         return strprintf("%s %s", GetCommand(), hash.ToString());
     192           1 :     } catch(const std::out_of_range &) {
     193           1 :         return strprintf("0x%08x %s", type, hash.ToString());
     194           1 :     }
     195       44196 : }
     196             : 
     197         729 : const std::vector<std::string> &getAllNetMessageTypes()
     198             : {
     199         729 :     return allNetMessageTypesVec;
     200             : }
     201             : 
     202             : /**
     203             :  * Convert a service flag (NODE_*) to a human readable string.
     204             :  * It supports unknown service flags which will be returned as "UNKNOWN[...]".
     205             :  * @param[in] bit the service flag is calculated as (1 << bit)
     206             :  */
     207       24805 : static std::string serviceFlagToStr(size_t bit)
     208             : {
     209       24805 :     const uint64_t service_flag = 1ULL << bit;
     210       24805 :     switch ((ServiceFlags)service_flag) {
     211           0 :     case NODE_NONE: abort();  // impossible
     212        8422 :     case NODE_NETWORK:         return "NETWORK";
     213           0 :     case NODE_GETUTXO:         return "GETUTXO";
     214           4 :     case NODE_BLOOM:           return "BLOOM";
     215        8397 :     case NODE_WITNESS:         return "WITNESS";
     216         190 :     case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
     217        7790 :     case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
     218             :     // Not using default, so we get warned when a case is missing
     219             :     }
     220             : 
     221           2 :     std::ostringstream stream;
     222           2 :     stream.imbue(std::locale::classic());
     223           2 :     stream << "UNKNOWN[";
     224           2 :     stream << "2^" << bit;
     225           2 :     stream << "]";
     226           2 :     return stream.str();
     227       24805 : }
     228             : 
     229        8679 : std::vector<std::string> serviceFlagsToStr(uint64_t flags)
     230             : {
     231        8679 :     std::vector<std::string> str_flags;
     232             : 
     233      564135 :     for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
     234      555456 :         if (flags & (1ULL << i)) {
     235       24805 :             str_flags.emplace_back(serviceFlagToStr(i));
     236       24805 :         }
     237             :     }
     238             : 
     239             :     return str_flags;
     240        8679 : }
     241             : 
     242       52072 : GenTxid ToGenTxid(const CInv& inv)
     243             : {
     244       52072 :     assert(inv.IsGenTxMsg());
     245       52072 :     return {inv.IsMsgWtx(), inv.hash};
     246             : }

Generated by: LCOV version 1.15