2011-08-11 18:14:53 +02:00
|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
2022-12-24 23:49:50 +00:00
|
|
|
// Copyright (c) 2009-2022 The Bitcoin Core developers
|
2014-12-13 12:09:33 +08:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2012-05-18 22:02:28 +08:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2011-08-11 18:14:53 +02:00
|
|
|
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <protocol.h>
|
2013-04-13 00:13:08 -05:00
|
|
|
|
2023-05-08 11:32:13 +02:00
|
|
|
#include <common/system.h>
|
2013-04-13 00:13:08 -05:00
|
|
|
|
2023-03-23 12:23:29 +01:00
|
|
|
#include <atomic>
|
|
|
|
|
2015-12-07 15:31:32 +01:00
|
|
|
namespace NetMsgType {
|
2023-07-11 15:44:43 +02:00
|
|
|
const char* VERSION = "version";
|
|
|
|
const char* VERACK = "verack";
|
|
|
|
const char* ADDR = "addr";
|
|
|
|
const char* ADDRV2 = "addrv2";
|
|
|
|
const char* SENDADDRV2 = "sendaddrv2";
|
|
|
|
const char* INV = "inv";
|
|
|
|
const char* GETDATA = "getdata";
|
|
|
|
const char* MERKLEBLOCK = "merkleblock";
|
|
|
|
const char* GETBLOCKS = "getblocks";
|
|
|
|
const char* GETHEADERS = "getheaders";
|
|
|
|
const char* TX = "tx";
|
|
|
|
const char* HEADERS = "headers";
|
|
|
|
const char* BLOCK = "block";
|
|
|
|
const char* GETADDR = "getaddr";
|
|
|
|
const char* MEMPOOL = "mempool";
|
|
|
|
const char* PING = "ping";
|
|
|
|
const char* PONG = "pong";
|
|
|
|
const char* NOTFOUND = "notfound";
|
|
|
|
const char* FILTERLOAD = "filterload";
|
|
|
|
const char* FILTERADD = "filteradd";
|
|
|
|
const char* FILTERCLEAR = "filterclear";
|
|
|
|
const char* SENDHEADERS = "sendheaders";
|
|
|
|
const char* FEEFILTER = "feefilter";
|
|
|
|
const char* SENDCMPCT = "sendcmpct";
|
|
|
|
const char* CMPCTBLOCK = "cmpctblock";
|
|
|
|
const char* GETBLOCKTXN = "getblocktxn";
|
|
|
|
const char* BLOCKTXN = "blocktxn";
|
|
|
|
const char* GETCFILTERS = "getcfilters";
|
|
|
|
const char* CFILTER = "cfilter";
|
|
|
|
const char* GETCFHEADERS = "getcfheaders";
|
|
|
|
const char* CFHEADERS = "cfheaders";
|
|
|
|
const char* GETCFCHECKPT = "getcfcheckpt";
|
|
|
|
const char* CFCHECKPT = "cfcheckpt";
|
|
|
|
const char* WTXIDRELAY = "wtxidrelay";
|
|
|
|
const char* SENDTXRCNCL = "sendtxrcncl";
|
2017-05-31 22:21:25 +02:00
|
|
|
} // namespace NetMsgType
|
2015-12-07 15:31:32 +01:00
|
|
|
|
|
|
|
/** All known message types. Keep this in the same order as the list of
|
|
|
|
* messages above and in protocol.h.
|
|
|
|
*/
|
2023-07-11 15:44:43 +02:00
|
|
|
const static std::vector<std::string> g_all_net_message_types{
|
2015-12-07 15:31:32 +01:00
|
|
|
NetMsgType::VERSION,
|
|
|
|
NetMsgType::VERACK,
|
|
|
|
NetMsgType::ADDR,
|
2020-05-20 12:05:18 +02:00
|
|
|
NetMsgType::ADDRV2,
|
|
|
|
NetMsgType::SENDADDRV2,
|
2015-12-07 15:31:32 +01:00
|
|
|
NetMsgType::INV,
|
|
|
|
NetMsgType::GETDATA,
|
|
|
|
NetMsgType::MERKLEBLOCK,
|
|
|
|
NetMsgType::GETBLOCKS,
|
|
|
|
NetMsgType::GETHEADERS,
|
|
|
|
NetMsgType::TX,
|
|
|
|
NetMsgType::HEADERS,
|
|
|
|
NetMsgType::BLOCK,
|
|
|
|
NetMsgType::GETADDR,
|
|
|
|
NetMsgType::MEMPOOL,
|
|
|
|
NetMsgType::PING,
|
|
|
|
NetMsgType::PONG,
|
|
|
|
NetMsgType::NOTFOUND,
|
|
|
|
NetMsgType::FILTERLOAD,
|
|
|
|
NetMsgType::FILTERADD,
|
|
|
|
NetMsgType::FILTERCLEAR,
|
2016-02-12 15:57:15 -05:00
|
|
|
NetMsgType::SENDHEADERS,
|
2016-06-06 01:26:52 -07:00
|
|
|
NetMsgType::FEEFILTER,
|
|
|
|
NetMsgType::SENDCMPCT,
|
|
|
|
NetMsgType::CMPCTBLOCK,
|
|
|
|
NetMsgType::GETBLOCKTXN,
|
|
|
|
NetMsgType::BLOCKTXN,
|
2019-06-30 15:42:13 +02:00
|
|
|
NetMsgType::GETCFILTERS,
|
|
|
|
NetMsgType::CFILTER,
|
2020-05-04 19:47:26 -04:00
|
|
|
NetMsgType::GETCFHEADERS,
|
|
|
|
NetMsgType::CFHEADERS,
|
2019-06-30 16:19:40 +02:00
|
|
|
NetMsgType::GETCFCHECKPT,
|
|
|
|
NetMsgType::CFCHECKPT,
|
2020-01-30 10:10:50 -05:00
|
|
|
NetMsgType::WTXIDRELAY,
|
2022-09-19 17:31:01 +03:00
|
|
|
NetMsgType::SENDTXRCNCL,
|
2011-08-11 18:49:03 +02:00
|
|
|
};
|
2011-08-11 18:14:53 +02:00
|
|
|
|
2014-10-27 20:24:31 -04:00
|
|
|
CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
|
2023-11-11 13:04:18 +01:00
|
|
|
: pchMessageStart{pchMessageStartIn}
|
2011-08-11 18:14:53 +02:00
|
|
|
{
|
2021-05-13 08:44:34 +01:00
|
|
|
// Copy the command name
|
2019-09-30 12:27:27 +02:00
|
|
|
size_t i = 0;
|
|
|
|
for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i];
|
|
|
|
assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE
|
|
|
|
|
2011-08-11 18:14:53 +02:00
|
|
|
nMessageSize = nMessageSizeIn;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string CMessageHeader::GetCommand() const
|
|
|
|
{
|
2014-09-16 18:13:05 +02:00
|
|
|
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
|
2011-08-11 18:14:53 +02:00
|
|
|
}
|
|
|
|
|
2020-05-26 17:01:57 -04:00
|
|
|
bool CMessageHeader::IsCommandValid() const
|
2011-08-11 18:14:53 +02:00
|
|
|
{
|
|
|
|
// Check the command string for errors
|
2020-05-26 17:01:57 -04:00
|
|
|
for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; ++p1) {
|
|
|
|
if (*p1 == 0) {
|
2011-08-11 18:14:53 +02:00
|
|
|
// Must be all zeros after the first zero
|
2020-05-26 17:01:57 -04:00
|
|
|
for (; p1 < pchCommand + COMMAND_SIZE; ++p1) {
|
|
|
|
if (*p1 != 0) {
|
2011-08-11 18:14:53 +02:00
|
|
|
return false;
|
2020-05-26 17:01:57 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (*p1 < ' ' || *p1 > 0x7E) {
|
2011-08-11 18:14:53 +02:00
|
|
|
return false;
|
2020-05-26 17:01:57 -04:00
|
|
|
}
|
2011-08-11 18:14:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2011-08-11 18:40:12 +02:00
|
|
|
|
2011-08-11 18:49:03 +02:00
|
|
|
CInv::CInv()
|
|
|
|
{
|
|
|
|
type = 0;
|
2014-12-15 09:11:16 +01:00
|
|
|
hash.SetNull();
|
2011-08-11 18:49:03 +02:00
|
|
|
}
|
|
|
|
|
2020-07-28 10:47:07 +02:00
|
|
|
CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
|
2011-08-11 18:49:03 +02:00
|
|
|
|
|
|
|
bool operator<(const CInv& a, const CInv& b)
|
|
|
|
{
|
|
|
|
return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
|
|
|
|
}
|
|
|
|
|
2015-11-06 01:32:04 +01:00
|
|
|
std::string CInv::GetCommand() const
|
2011-08-11 18:49:03 +02:00
|
|
|
{
|
2015-11-06 01:32:04 +01:00
|
|
|
std::string cmd;
|
|
|
|
if (type & MSG_WITNESS_FLAG)
|
|
|
|
cmd.append("witness-");
|
|
|
|
int masked = type & MSG_TYPE_MASK;
|
|
|
|
switch (masked)
|
|
|
|
{
|
|
|
|
case MSG_TX: return cmd.append(NetMsgType::TX);
|
2020-01-30 09:35:00 -05:00
|
|
|
// WTX is not a message type, just an inv type
|
|
|
|
case MSG_WTX: return cmd.append("wtx");
|
2015-11-06 01:32:04 +01:00
|
|
|
case MSG_BLOCK: return cmd.append(NetMsgType::BLOCK);
|
|
|
|
case MSG_FILTERED_BLOCK: return cmd.append(NetMsgType::MERKLEBLOCK);
|
|
|
|
case MSG_CMPCT_BLOCK: return cmd.append(NetMsgType::CMPCTBLOCK);
|
|
|
|
default:
|
2015-01-08 11:44:25 +01:00
|
|
|
throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
|
2015-11-06 01:32:04 +01:00
|
|
|
}
|
2011-08-11 18:49:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string CInv::ToString() const
|
|
|
|
{
|
2016-11-09 11:09:16 +01:00
|
|
|
try {
|
|
|
|
return strprintf("%s %s", GetCommand(), hash.ToString());
|
|
|
|
} catch(const std::out_of_range &) {
|
|
|
|
return strprintf("0x%08x %s", type, hash.ToString());
|
|
|
|
}
|
2011-08-11 18:49:03 +02:00
|
|
|
}
|
2015-12-07 15:31:32 +01:00
|
|
|
|
|
|
|
const std::vector<std::string> &getAllNetMessageTypes()
|
|
|
|
{
|
2023-07-11 15:44:43 +02:00
|
|
|
return g_all_net_message_types;
|
2015-12-07 15:31:32 +01:00
|
|
|
}
|
2020-02-17 01:53:13 +00:00
|
|
|
|
2020-05-29 18:52:59 +02:00
|
|
|
/**
|
|
|
|
* Convert a service flag (NODE_*) to a human readable string.
|
|
|
|
* It supports unknown service flags which will be returned as "UNKNOWN[...]".
|
|
|
|
* @param[in] bit the service flag is calculated as (1 << bit)
|
|
|
|
*/
|
|
|
|
static std::string serviceFlagToStr(size_t bit)
|
2020-02-17 01:53:13 +00:00
|
|
|
{
|
2020-05-29 18:49:26 +02:00
|
|
|
const uint64_t service_flag = 1ULL << bit;
|
|
|
|
switch ((ServiceFlags)service_flag) {
|
2020-02-17 01:53:13 +00:00
|
|
|
case NODE_NONE: abort(); // impossible
|
|
|
|
case NODE_NETWORK: return "NETWORK";
|
|
|
|
case NODE_BLOOM: return "BLOOM";
|
|
|
|
case NODE_WITNESS: return "WITNESS";
|
2020-05-04 11:13:13 -04:00
|
|
|
case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
|
2020-02-17 01:53:13 +00:00
|
|
|
case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
|
2023-08-22 17:50:59 -04:00
|
|
|
case NODE_P2P_V2: return "P2P_V2";
|
2020-02-17 01:53:13 +00:00
|
|
|
// Not using default, so we get warned when a case is missing
|
|
|
|
}
|
|
|
|
|
2022-08-20 15:01:57 +02:00
|
|
|
return strprintf("UNKNOWN[2^%u]", bit);
|
2020-02-17 01:53:13 +00:00
|
|
|
}
|
2020-05-29 18:52:59 +02:00
|
|
|
|
|
|
|
std::vector<std::string> serviceFlagsToStr(uint64_t flags)
|
|
|
|
{
|
|
|
|
std::vector<std::string> str_flags;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < sizeof(flags) * 8; ++i) {
|
|
|
|
if (flags & (1ULL << i)) {
|
|
|
|
str_flags.emplace_back(serviceFlagToStr(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return str_flags;
|
|
|
|
}
|
2020-07-22 17:17:00 -07:00
|
|
|
|
|
|
|
GenTxid ToGenTxid(const CInv& inv)
|
|
|
|
{
|
|
|
|
assert(inv.IsGenTxMsg());
|
2021-10-22 12:28:14 +02:00
|
|
|
return inv.IsMsgWtx() ? GenTxid::Wtxid(inv.hash) : GenTxid::Txid(inv.hash);
|
2020-07-22 17:17:00 -07:00
|
|
|
}
|