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 : 176278 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
11 : 176278 : : pchMessageStart{pchMessageStartIn}
12 : : {
13 : : // Copy the command name
14 : 176278 : size_t i = 0;
15 [ + - + + ]: 1267498 : for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
16 [ - + ]: 176278 : assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
17 : :
18 : 176278 : nMessageSize = nMessageSizeIn;
19 : 176278 : }
20 : :
21 : 172317 : std::string CMessageHeader::GetCommand() const
22 : : {
23 : 172317 : return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
24 : : }
25 : :
26 : 172232 : bool CMessageHeader::IsCommandValid() const
27 : : {
28 : : // Check the command string for errors
29 [ + + ]: 1413660 : for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; ++p1) {
30 [ + + ]: 1241509 : if (*p1 == 0) {
31 : : // Must be all zeros after the first zero
32 [ + + ]: 1169149 : for (; p1 < pchCommand + COMMAND_SIZE; ++p1) {
33 [ + + ]: 997009 : if (*p1 != 0) {
34 : : return false;
35 : : }
36 : : }
37 [ + + ]: 1069368 : } else if (*p1 < ' ' || *p1 > 0x7E) {
38 : : return false;
39 : : }
40 : : }
41 : :
42 : : return true;
43 : : }
44 : :
45 : 186016 : CInv::CInv()
46 : : {
47 : 186016 : type = 0;
48 : 186016 : hash.SetNull();
49 : 186016 : }
50 : :
51 : 98858 : CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
52 : :
53 : 0 : 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 : 78184 : std::string CInv::GetCommand() const
59 : : {
60 [ + + ]: 78184 : std::string cmd;
61 [ + + ]: 78184 : if (type & MSG_WITNESS_FLAG)
62 [ + - ]: 39353 : cmd.append("witness-");
63 : 78184 : int masked = type & MSG_TYPE_MASK;
64 [ + + + + : 78184 : switch (masked)
+ + ]
65 : : {
66 [ + - + - ]: 21 : case MSG_TX: return cmd.append(NetMsgType::TX);
67 : : // WTX is not a message type, just an inv type
68 [ + - + - ]: 31537 : case MSG_WTX: return cmd.append("wtx");
69 [ + - + - ]: 46325 : case MSG_BLOCK: return cmd.append(NetMsgType::BLOCK);
70 [ + - + - ]: 7 : case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
71 [ + - + - ]: 293 : case MSG_CMPCT_BLOCK: return cmd.append(NetMsgType::CMPCTBLOCK);
72 : 1 : default:
73 [ + - + - ]: 2 : throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
74 : : }
75 : 78183 : }
76 : :
77 : 78184 : std::string CInv::ToString() const
78 : : {
79 : 78184 : try {
80 [ + - + + : 156368 : return strprintf("%s %s", GetCommand(), hash.ToString());
+ - ]
81 [ - + ]: 1 : } catch(const std::out_of_range &) {
82 [ + - + - ]: 1 : return strprintf("0x%08x %s", type, hash.ToString());
83 : 1 : }
84 : : }
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 : 38052 : static std::string serviceFlagToStr(size_t bit)
92 : : {
93 : 38052 : const uint64_t service_flag = 1ULL << bit;
94 [ - + + + : 38052 : switch ((ServiceFlags)service_flag) {
+ + + + ]
95 : 0 : case NODE_NONE: abort(); // impossible
96 : 11301 : case NODE_NETWORK: return "NETWORK";
97 : 10 : case NODE_BLOOM: return "BLOOM";
98 : 13666 : case NODE_WITNESS: return "WITNESS";
99 : 20 : case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
100 : 11221 : case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
101 : 1826 : case NODE_P2P_V2: return "P2P_V2";
102 : : // Not using default, so we get warned when a case is missing
103 : : }
104 : :
105 : 8 : return strprintf("UNKNOWN[2^%u]", bit);
106 : : }
107 : :
108 : 14465 : std::vector<std::string> serviceFlagsToStr(uint64_t flags)
109 : : {
110 : 14465 : std::vector<std::string> str_flags;
111 : :
112 [ + + ]: 940225 : for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
113 [ + + ]: 925760 : if (flags & (1ULL << i)) {
114 [ + - + - ]: 76104 : str_flags.emplace_back(serviceFlagToStr(i));
115 : : }
116 : : }
117 : :
118 : 14465 : return str_flags;
119 : 0 : }
120 : :
121 : 54872 : GenTxid ToGenTxid(const CInv& inv)
122 : : {
123 [ + + ]: 54872 : assert(inv.IsGenTxMsg());
124 [ + + ]: 54872 : return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash);
125 : : }
|