Bitcoin Core  27.99.0
P2P Digital Currency
protocol.cpp
Go to the documentation of this file.
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* pszCommand, unsigned int nMessageSizeIn)
11  : pchMessageStart{pchMessageStartIn}
12 {
13  // Copy the command name
14  size_t i = 0;
15  for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
16  assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
17 
18  nMessageSize = nMessageSizeIn;
19 }
20 
21 std::string CMessageHeader::GetCommand() const
22 {
23  return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
24 }
25 
27 {
28  // Check the command string for errors
29  for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; ++p1) {
30  if (*p1 == 0) {
31  // Must be all zeros after the first zero
32  for (; p1 < pchCommand + COMMAND_SIZE; ++p1) {
33  if (*p1 != 0) {
34  return false;
35  }
36  }
37  } else if (*p1 < ' ' || *p1 > 0x7E) {
38  return false;
39  }
40  }
41 
42  return true;
43 }
44 
46 {
47  type = 0;
48  hash.SetNull();
49 }
50 
51 CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
52 
53 bool operator<(const CInv& a, const CInv& b)
54 {
55  return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
56 }
57 
58 std::string CInv::GetCommand() const
59 {
60  std::string cmd;
61  if (type & MSG_WITNESS_FLAG)
62  cmd.append("witness-");
63  int masked = type & MSG_TYPE_MASK;
64  switch (masked)
65  {
66  case MSG_TX: return cmd.append(NetMsgType::TX);
67  // WTX is not a message type, just an inv type
68  case MSG_WTX: return cmd.append("wtx");
69  case MSG_BLOCK: return cmd.append(NetMsgType::BLOCK);
70  case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
71  case MSG_CMPCT_BLOCK: return cmd.append(NetMsgType::CMPCTBLOCK);
72  default:
73  throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
74  }
75 }
76 
77 std::string CInv::ToString() const
78 {
79  try {
80  return strprintf("%s %s", GetCommand(), hash.ToString());
81  } catch(const std::out_of_range &) {
82  return strprintf("0x%08x %s", type, hash.ToString());
83  }
84 }
85 
91 static std::string serviceFlagToStr(size_t bit)
92 {
93  const uint64_t service_flag = 1ULL << bit;
94  switch ((ServiceFlags)service_flag) {
95  case NODE_NONE: abort(); // impossible
96  case NODE_NETWORK: return "NETWORK";
97  case NODE_BLOOM: return "BLOOM";
98  case NODE_WITNESS: return "WITNESS";
99  case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
100  case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
101  case NODE_P2P_V2: return "P2P_V2";
102  // Not using default, so we get warned when a case is missing
103  }
104 
105  return strprintf("UNKNOWN[2^%u]", bit);
106 }
107 
108 std::vector<std::string> serviceFlagsToStr(uint64_t flags)
109 {
110  std::vector<std::string> str_flags;
111 
112  for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
113  if (flags & (1ULL << i)) {
114  str_flags.emplace_back(serviceFlagToStr(i));
115  }
116  }
117 
118  return str_flags;
119 }
120 
121 GenTxid ToGenTxid(const CInv& inv)
122 {
123  assert(inv.IsGenTxMsg());
124  return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash);
125 }
int flags
Definition: bitcoin-tx.cpp:528
const auto cmd
inv message data
Definition: protocol.h:494
std::string ToString() const
Definition: protocol.cpp:77
std::string GetCommand() const
Definition: protocol.cpp:58
bool IsMsgWtx() const
Definition: protocol.h:509
CInv()
Definition: protocol.cpp:45
uint32_t type
Definition: protocol.h:524
bool IsGenTxMsg() const
Definition: protocol.h:515
uint256 hash
Definition: protocol.h:525
CMessageHeader()=default
char pchCommand[COMMAND_SIZE]
Definition: protocol.h:51
std::string GetCommand() const
Definition: protocol.cpp:21
static constexpr size_t COMMAND_SIZE
Definition: protocol.h:31
uint32_t nMessageSize
Definition: protocol.h:52
bool IsCommandValid() const
Definition: protocol.cpp:26
A generic txid reference (txid or wtxid).
Definition: transaction.h:428
static GenTxid Wtxid(const uint256 &hash)
Definition: transaction.h:435
static GenTxid Txid(const uint256 &hash)
Definition: transaction.h:434
std::string ToString() const
Definition: uint256.cpp:55
constexpr void SetNull()
Definition: uint256.h:49
256-bit opaque blob.
Definition: uint256.h:106
std::array< uint8_t, 4 > MessageStartChars
constexpr const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids".
Definition: protocol.h:206
constexpr const char * TX
The tx message transmits a single transaction.
Definition: protocol.h:117
constexpr const char * MERKLEBLOCK
The merkleblock message is a reply to a getdata message which requested a block using the inventory t...
Definition: protocol.h:102
constexpr const char * BLOCK
The block message transmits a single serialized block.
Definition: protocol.h:127
bool operator<(const CInv &a, const CInv &b)
Definition: protocol.cpp:53
GenTxid ToGenTxid(const CInv &inv)
Convert a TX/WITNESS_TX/WTX CInv to a GenTxid.
Definition: protocol.cpp:121
static std::string serviceFlagToStr(size_t bit)
Convert a service flag (NODE_*) to a human readable string.
Definition: protocol.cpp:91
std::vector< std::string > serviceFlagsToStr(uint64_t flags)
Convert service flags (a bitmask of NODE_*) to human readable strings.
Definition: protocol.cpp:108
const uint32_t MSG_WITNESS_FLAG
getdata message type flags
Definition: protocol.h:470
const uint32_t MSG_TYPE_MASK
Definition: protocol.h:471
@ MSG_TX
Definition: protocol.h:479
@ MSG_FILTERED_BLOCK
Defined in BIP37.
Definition: protocol.h:483
@ MSG_WTX
Defined in BIP 339.
Definition: protocol.h:481
@ MSG_BLOCK
Definition: protocol.h:480
@ MSG_CMPCT_BLOCK
Defined in BIP152.
Definition: protocol.h:484
ServiceFlags
nServices flags
Definition: protocol.h:309
@ NODE_NONE
Definition: protocol.h:312
@ NODE_P2P_V2
Definition: protocol.h:330
@ NODE_WITNESS
Definition: protocol.h:320
@ NODE_NETWORK_LIMITED
Definition: protocol.h:327
@ NODE_BLOOM
Definition: protocol.h:317
@ NODE_NETWORK
Definition: protocol.h:315
@ NODE_COMPACT_FILTERS
Definition: protocol.h:323
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
assert(!tx.IsCoinBase())