/bitcoin/src/protocol.cpp
Line | Count | Source |
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 | | CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* msg_type, unsigned int nMessageSizeIn) |
11 | 12.9M | : pchMessageStart{pchMessageStartIn} |
12 | 12.9M | { |
13 | | // Copy the message type name |
14 | 12.9M | size_t i = 0; |
15 | 60.0M | for (; i < MESSAGE_TYPE_SIZE && msg_type[i] != 0; ++i) m_msg_type[i] = msg_type[i]; Branch (15:12): [True: 60.0M, False: 0]
Branch (15:37): [True: 47.1M, False: 12.9M]
|
16 | 12.9M | assert(msg_type[i] == 0); // Assert that the message type name passed in is not longer than MESSAGE_TYPE_SIZE Branch (16:5): [True: 12.9M, False: 0]
|
17 | | |
18 | 12.9M | nMessageSize = nMessageSizeIn; |
19 | 12.9M | } |
20 | | |
21 | | std::string CMessageHeader::GetMessageType() const |
22 | 5.52M | { |
23 | 5.52M | return std::string(m_msg_type, m_msg_type + strnlen(m_msg_type, MESSAGE_TYPE_SIZE)); |
24 | 5.52M | } |
25 | | |
26 | | bool CMessageHeader::IsMessageTypeValid() const |
27 | 5.52M | { |
28 | | // Check the message type string for errors |
29 | 35.6M | for (const char* p1 = m_msg_type; p1 < m_msg_type + MESSAGE_TYPE_SIZE; ++p1) { Branch (29:39): [True: 30.1M, False: 5.52M]
|
30 | 30.1M | if (*p1 == 0) { Branch (30:13): [True: 5.52M, False: 24.6M]
|
31 | | // Must be all zeros after the first zero |
32 | 47.1M | for (; p1 < m_msg_type + MESSAGE_TYPE_SIZE; ++p1) { Branch (32:20): [True: 41.6M, False: 5.52M]
|
33 | 41.6M | if (*p1 != 0) { Branch (33:21): [True: 0, False: 41.6M]
|
34 | 0 | return false; |
35 | 0 | } |
36 | 41.6M | } |
37 | 24.6M | } else if (*p1 < ' ' || *p1 > 0x7E) { Branch (37:20): [True: 0, False: 24.6M]
Branch (37:33): [True: 0, False: 24.6M]
|
38 | 0 | return false; |
39 | 0 | } |
40 | 30.1M | } |
41 | | |
42 | 5.52M | return true; |
43 | 5.52M | } |
44 | | |
45 | | CInv::CInv() |
46 | 673k | { |
47 | 673k | type = 0; |
48 | 673k | hash.SetNull(); |
49 | 673k | } |
50 | | |
51 | 10.2M | CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {} |
52 | | |
53 | | bool operator<(const CInv& a, const CInv& b) |
54 | 0 | { |
55 | 0 | return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); Branch (55:13): [True: 0, False: 0]
Branch (55:33): [True: 0, False: 0]
Branch (55:53): [True: 0, False: 0]
|
56 | 0 | } |
57 | | |
58 | | std::string CInv::GetMessageType() const |
59 | 565k | { |
60 | 565k | std::string cmd; |
61 | 565k | if (type & MSG_WITNESS_FLAG) Branch (61:9): [True: 54.6k, False: 510k]
|
62 | 54.6k | cmd.append("witness-"); |
63 | 565k | int masked = type & MSG_TYPE_MASK; |
64 | 565k | switch (masked) |
65 | 565k | { |
66 | 51.9k | case MSG_TX: return cmd.append(NetMsgType::TX); Branch (66:5): [True: 51.9k, False: 513k]
|
67 | | // WTX is not a message type, just an inv type |
68 | 418k | case MSG_WTX: return cmd.append("wtx"); Branch (68:5): [True: 418k, False: 146k]
|
69 | 94.8k | case MSG_BLOCK: return cmd.append(NetMsgType::BLOCK); Branch (69:5): [True: 94.8k, False: 470k]
|
70 | 0 | case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK); Branch (70:5): [True: 0, False: 565k]
|
71 | 4 | case MSG_CMPCT_BLOCK: return cmd.append(NetMsgType::CMPCTBLOCK); Branch (71:5): [True: 4, False: 565k]
|
72 | 151 | default: Branch (72:5): [True: 151, False: 565k]
|
73 | 151 | throw std::out_of_range(strprintf("CInv::GetMessageType(): type=%d unknown type", type)); |
74 | 565k | } |
75 | 565k | } |
76 | | |
77 | | std::string CInv::ToString() const |
78 | 565k | { |
79 | 565k | try { |
80 | 565k | return strprintf("%s %s", GetMessageType(), hash.ToString()); |
81 | 565k | } catch(const std::out_of_range &) { |
82 | 151 | return strprintf("0x%08x %s", type, hash.ToString()); |
83 | 151 | } |
84 | 565k | } |
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 | | static std::string serviceFlagToStr(size_t bit) |
92 | 0 | { |
93 | 0 | const uint64_t service_flag = 1ULL << bit; |
94 | 0 | switch ((ServiceFlags)service_flag) { Branch (94:13): [True: 0, False: 0]
|
95 | 0 | case NODE_NONE: abort(); // impossible Branch (95:5): [True: 0, False: 0]
|
96 | 0 | case NODE_NETWORK: return "NETWORK"; Branch (96:5): [True: 0, False: 0]
|
97 | 0 | case NODE_BLOOM: return "BLOOM"; Branch (97:5): [True: 0, False: 0]
|
98 | 0 | case NODE_WITNESS: return "WITNESS"; Branch (98:5): [True: 0, False: 0]
|
99 | 0 | case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS"; Branch (99:5): [True: 0, False: 0]
|
100 | 0 | case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED"; Branch (100:5): [True: 0, False: 0]
|
101 | 0 | case NODE_P2P_V2: return "P2P_V2"; Branch (101:5): [True: 0, False: 0]
|
102 | | // Not using default, so we get warned when a case is missing |
103 | 0 | } |
104 | | |
105 | 0 | return strprintf("UNKNOWN[2^%u]", bit); |
106 | 0 | } |
107 | | |
108 | | std::vector<std::string> serviceFlagsToStr(uint64_t flags) |
109 | 0 | { |
110 | 0 | std::vector<std::string> str_flags; |
111 | |
|
112 | 0 | for (size_t i = 0; i < sizeof(flags) * 8; ++i) { Branch (112:24): [True: 0, False: 0]
|
113 | 0 | if (flags & (1ULL << i)) { Branch (113:13): [True: 0, False: 0]
|
114 | 0 | str_flags.emplace_back(serviceFlagToStr(i)); |
115 | 0 | } |
116 | 0 | } |
117 | |
|
118 | 0 | return str_flags; |
119 | 0 | } |
120 | | |
121 | | GenTxid ToGenTxid(const CInv& inv) |
122 | 611k | { |
123 | 611k | assert(inv.IsGenTxMsg()); Branch (123:5): [True: 611k, False: 0]
|
124 | 611k | return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash); Branch (124:12): [True: 537k, False: 73.6k]
|
125 | 611k | } |