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 : 0 : CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* msg_type, unsigned int nMessageSizeIn)
11 : 0 : : pchMessageStart{pchMessageStartIn}
12 : : {
13 : : // Copy the message type name
14 : 0 : size_t i = 0;
15 [ # # # # ]: 0 : for (; i < MESSAGE_TYPE_SIZE && msg_type[i] != 0; ++i) m_msg_type[i] = msg_type[i];
16 [ # # ]: 0 : assert(msg_type[i] == 0); // Assert that the message type name passed in is not longer than MESSAGE_TYPE_SIZE
17 : :
18 : 0 : nMessageSize = nMessageSizeIn;
19 : 0 : }
20 : :
21 : 0 : std::string CMessageHeader::GetMessageType() const
22 : : {
23 : 0 : return std::string(m_msg_type, m_msg_type + strnlen(m_msg_type, MESSAGE_TYPE_SIZE));
24 : : }
25 : :
26 : 0 : bool CMessageHeader::IsMessageTypeValid() const
27 : : {
28 : : // Check the message type string for errors
29 [ # # ]: 0 : for (const char* p1 = m_msg_type; p1 < m_msg_type + MESSAGE_TYPE_SIZE; ++p1) {
30 [ # # ]: 0 : if (*p1 == 0) {
31 : : // Must be all zeros after the first zero
32 [ # # ]: 0 : for (; p1 < m_msg_type + MESSAGE_TYPE_SIZE; ++p1) {
33 [ # # ]: 0 : if (*p1 != 0) {
34 : : return false;
35 : : }
36 : : }
37 [ # # ]: 0 : } else if (*p1 < ' ' || *p1 > 0x7E) {
38 : : return false;
39 : : }
40 : : }
41 : :
42 : : return true;
43 : : }
44 : :
45 : 0 : CInv::CInv()
46 : : {
47 : 0 : type = 0;
48 : 0 : hash.SetNull();
49 : 0 : }
50 : :
51 : 0 : 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 : 0 : std::string CInv::GetMessageType() 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 : 0 : default:
73 [ # # # # ]: 0 : throw std::out_of_range(strprintf("CInv::GetMessageType(): type=%d unknown type", type));
74 : : }
75 : 0 : }
76 : :
77 : 0 : std::string CInv::ToString() const
78 : : {
79 : 0 : try {
80 [ # # # # : 0 : return strprintf("%s %s", GetMessageType(), hash.ToString());
# # ]
81 [ - - ]: 0 : } catch(const std::out_of_range &) {
82 [ - - - - ]: 0 : return strprintf("0x%08x %s", type, hash.ToString());
83 : 0 : }
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 : 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 : : }
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 : : }
116 : : }
117 : :
118 : 0 : return str_flags;
119 : 0 : }
120 : :
121 : 0 : GenTxid ToGenTxid(const CInv& inv)
122 : : {
123 [ # # ]: 0 : assert(inv.IsGenTxMsg());
124 [ # # ]: 0 : return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash);
125 : : }
|