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 : 343798 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn) 11 : 343798 : : pchMessageStart{pchMessageStartIn} 12 : : { 13 : : // Copy the command name 14 : 343798 : size_t i = 0; 15 [ + + + + ]: 2601360 : for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i]; 16 [ + - ]: 343798 : assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE 17 : : 18 : 343798 : nMessageSize = nMessageSizeIn; 19 : 343798 : } 20 : : 21 : 239833 : std::string CMessageHeader::GetCommand() const 22 : : { 23 [ + - ]: 239833 : return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE)); 24 : 0 : } 25 : : 26 : 205716 : bool CMessageHeader::IsCommandValid() const 27 : : { 28 : : // Check the command string for errors 29 [ + + - + : 1369042 : for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; ++p1) { + ] 30 [ + + ]: 1163326 : if (*p1 == 0) { 31 : : // Must be all zeros after the first zero 32 [ + + ]: 1366332 : for (; p1 < pchCommand + COMMAND_SIZE; ++p1) { 33 [ + + ]: 1204977 : if (*p1 != 0) { 34 : 8591 : return false; 35 : : } 36 : 1196386 : } 37 [ + + + + ]: 1154735 : } else if (*p1 < ' ' || *p1 > 0x7E) { 38 : 24899 : return false; 39 : : } 40 : 1129836 : } 41 : : 42 : 172226 : return true; 43 : 205716 : } 44 : : 45 : 1248688 : CInv::CInv() 46 : : { 47 : 1248688 : type = 0; 48 : 1248688 : hash.SetNull(); 49 : 1248688 : } 50 : : 51 : 493588 : CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {} 52 : 343798 : 53 : 343806 : bool operator<(const CInv& a, const CInv& b) 54 : : { 55 [ + + + + ]: 8 : return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); 56 : : } 57 : : 58 : 54 : std::string CInv::GetCommand() const 59 : : { 60 : 54 : std::string cmd; 61 [ + + ]: 54 : if (type & MSG_WITNESS_FLAG) 62 [ + - ]: 38 : cmd.append("witness-"); 63 : 54 : int masked = type & MSG_TYPE_MASK; 64 [ + + + + : 54 : switch (masked) + + ] 65 : : { 66 [ + - + - ]: 4 : case MSG_TX: return cmd.append(NetMsgType::TX); 67 : : // WTX is not a message type, just an inv type 68 [ + - + - ]: 6 : case MSG_WTX: return cmd.append("wtx"); 69 [ + - + - ]: 4 : case MSG_BLOCK: return cmd.append(NetMsgType::BLOCK); 70 [ + - + - ]: 8 : case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK); 71 [ + - + - ]: 10 : case MSG_CMPCT_BLOCK: return cmd.append(NetMsgType::CMPCTBLOCK); 72 : : default: 73 [ + - + - : 22 : throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type)); - + + - ] 74 : 1 : } 75 : 76 : } 76 : : 77 : 27 : std::string CInv::ToString() const 78 : : { 79 : : try { 80 [ + + + - : 38 : return strprintf("%s %s", GetCommand(), hash.ToString()); + - ] 81 [ - + ]: 11 : } catch(const std::out_of_range &) { 82 [ + - + - ]: 11 : return strprintf("0x%08x %s", type, hash.ToString()); 83 [ # # ]: 11 : } 84 : 38 : } 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 : 3 : std::vector<std::string> serviceFlagsToStr(uint64_t flags) 109 : : { 110 : 3 : std::vector<std::string> str_flags; 111 : : 112 [ + + ]: 195 : for (size_t i = 0; i < sizeof(flags) * 8; ++i) { 113 [ + - ]: 192 : if (flags & (1ULL << i)) { 114 [ # # # # ]: 0 : str_flags.emplace_back(serviceFlagToStr(i)); 115 : 0 : } 116 : 192 : } 117 : : 118 : 3 : return str_flags; 119 [ + - ]: 3 : } 120 : : 121 : 114967 : GenTxid ToGenTxid(const CInv& inv) 122 : : { 123 [ + - ]: 114967 : assert(inv.IsGenTxMsg()); 124 [ + + ]: 114967 : return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash); 125 : : }