2011-08-11 12:14:53 -04:00
|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
2020-04-16 13:14:08 -04:00
|
|
|
// Copyright (c) 2009-2019 The Bitcoin Core developers
|
2014-12-13 01:09:33 -03:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2012-05-18 10:02:28 -04:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2011-08-11 12:14:53 -04:00
|
|
|
|
2017-11-09 21:57:53 -03:00
|
|
|
#include <protocol.h>
|
2013-04-13 02:13:08 -03:00
|
|
|
|
2018-10-22 19:51:11 -03:00
|
|
|
#include <util/system.h>
|
|
|
|
#include <util/strencodings.h>
|
2013-04-13 02:13:08 -03:00
|
|
|
|
2011-10-07 12:02:21 -03:00
|
|
|
#ifndef WIN32
|
2011-08-11 12:40:12 -04:00
|
|
|
# include <arpa/inet.h>
|
|
|
|
#endif
|
|
|
|
|
2018-02-17 07:28:50 -03:00
|
|
|
static std::atomic<bool> g_initial_block_download_completed(false);
|
2017-10-14 01:48:00 -03:00
|
|
|
|
2015-12-07 11:31:32 -03:00
|
|
|
namespace NetMsgType {
|
|
|
|
const char *VERSION="version";
|
|
|
|
const char *VERACK="verack";
|
|
|
|
const char *ADDR="addr";
|
|
|
|
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";
|
2016-02-12 17:57:15 -03:00
|
|
|
const char *FEEFILTER="feefilter";
|
2016-06-06 04:26:52 -04:00
|
|
|
const char *SENDCMPCT="sendcmpct";
|
|
|
|
const char *CMPCTBLOCK="cmpctblock";
|
|
|
|
const char *GETBLOCKTXN="getblocktxn";
|
|
|
|
const char *BLOCKTXN="blocktxn";
|
2020-05-04 19:47:26 -04:00
|
|
|
const char *GETCFHEADERS="getcfheaders";
|
|
|
|
const char *CFHEADERS="cfheaders";
|
2019-06-30 10:19:40 -04:00
|
|
|
const char *GETCFCHECKPT="getcfcheckpt";
|
|
|
|
const char *CFCHECKPT="cfcheckpt";
|
2017-05-31 16:21:25 -04:00
|
|
|
} // namespace NetMsgType
|
2015-12-07 11:31:32 -03:00
|
|
|
|
|
|
|
/** All known message types. Keep this in the same order as the list of
|
|
|
|
* messages above and in protocol.h.
|
|
|
|
*/
|
|
|
|
const static std::string allNetMessageTypes[] = {
|
|
|
|
NetMsgType::VERSION,
|
|
|
|
NetMsgType::VERACK,
|
|
|
|
NetMsgType::ADDR,
|
|
|
|
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 17:57:15 -03:00
|
|
|
NetMsgType::SENDHEADERS,
|
2016-06-06 04:26:52 -04:00
|
|
|
NetMsgType::FEEFILTER,
|
|
|
|
NetMsgType::SENDCMPCT,
|
|
|
|
NetMsgType::CMPCTBLOCK,
|
|
|
|
NetMsgType::GETBLOCKTXN,
|
|
|
|
NetMsgType::BLOCKTXN,
|
2020-05-04 19:47:26 -04:00
|
|
|
NetMsgType::GETCFHEADERS,
|
|
|
|
NetMsgType::CFHEADERS,
|
2019-06-30 10:19:40 -04:00
|
|
|
NetMsgType::GETCFCHECKPT,
|
|
|
|
NetMsgType::CFCHECKPT,
|
2011-08-11 12:49:03 -04:00
|
|
|
};
|
2015-12-07 11:31:32 -03:00
|
|
|
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));
|
2011-08-11 12:14:53 -04:00
|
|
|
|
2014-10-27 21:24:31 -03:00
|
|
|
CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
|
2011-08-11 12:14:53 -04:00
|
|
|
{
|
2014-10-27 21:24:31 -03:00
|
|
|
memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
|
2011-08-11 12:14:53 -04:00
|
|
|
memset(pchCommand, 0, sizeof(pchCommand));
|
|
|
|
nMessageSize = -1;
|
2016-09-27 09:05:24 -03:00
|
|
|
memset(pchChecksum, 0, CHECKSUM_SIZE);
|
2011-08-11 12:14:53 -04:00
|
|
|
}
|
|
|
|
|
2014-10-27 21:24:31 -03:00
|
|
|
CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
|
2011-08-11 12:14:53 -04:00
|
|
|
{
|
2014-10-27 21:24:31 -03:00
|
|
|
memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
|
2019-09-30 07:27:27 -03:00
|
|
|
|
|
|
|
// Copy the command name, zero-padding to COMMAND_SIZE bytes
|
|
|
|
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
|
|
|
|
for (; i < COMMAND_SIZE; ++i) pchCommand[i] = 0;
|
|
|
|
|
2011-08-11 12:14:53 -04:00
|
|
|
nMessageSize = nMessageSizeIn;
|
2016-09-27 09:05:24 -03:00
|
|
|
memset(pchChecksum, 0, CHECKSUM_SIZE);
|
2011-08-11 12:14:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string CMessageHeader::GetCommand() const
|
|
|
|
{
|
2014-09-16 13:13:05 -03:00
|
|
|
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
|
2011-08-11 12:14:53 -04:00
|
|
|
}
|
|
|
|
|
2014-10-27 21:24:31 -03:00
|
|
|
bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
|
2011-08-11 12:14:53 -04:00
|
|
|
{
|
|
|
|
// Check start string
|
2014-10-27 21:24:31 -03:00
|
|
|
if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
|
2011-08-11 12:14:53 -04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Check the command string for errors
|
|
|
|
for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++)
|
|
|
|
{
|
|
|
|
if (*p1 == 0)
|
|
|
|
{
|
|
|
|
// Must be all zeros after the first zero
|
|
|
|
for (; p1 < pchCommand + COMMAND_SIZE; p1++)
|
|
|
|
if (*p1 != 0)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (*p1 < ' ' || *p1 > 0x7E)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Message size
|
|
|
|
if (nMessageSize > MAX_SIZE)
|
|
|
|
{
|
2015-01-08 07:44:25 -03:00
|
|
|
LogPrintf("CMessageHeader::IsValid(): (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand(), nMessageSize);
|
2011-08-11 12:14:53 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2011-08-11 12:40:12 -04:00
|
|
|
|
|
|
|
|
2018-02-17 07:28:50 -03:00
|
|
|
ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
|
|
|
|
if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
|
|
|
|
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
|
|
|
|
}
|
|
|
|
return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetServiceFlagsIBDCache(bool state) {
|
|
|
|
g_initial_block_download_completed = state;
|
|
|
|
}
|
|
|
|
|
2011-08-11 12:49:03 -04:00
|
|
|
CInv::CInv()
|
|
|
|
{
|
|
|
|
type = 0;
|
2014-12-15 05:11:16 -03:00
|
|
|
hash.SetNull();
|
2011-08-11 12:49:03 -04:00
|
|
|
}
|
|
|
|
|
2017-06-03 19:09:48 -04:00
|
|
|
CInv::CInv(int typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
|
2011-08-11 12:49:03 -04:00
|
|
|
|
|
|
|
bool operator<(const CInv& a, const CInv& b)
|
|
|
|
{
|
|
|
|
return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
|
|
|
|
}
|
|
|
|
|
2015-11-05 21:32:04 -03:00
|
|
|
std::string CInv::GetCommand() const
|
2011-08-11 12:49:03 -04:00
|
|
|
{
|
2015-11-05 21:32:04 -03: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);
|
|
|
|
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 07:44:25 -03:00
|
|
|
throw std::out_of_range(strprintf("CInv::GetCommand(): type=%d unknown type", type));
|
2015-11-05 21:32:04 -03:00
|
|
|
}
|
2011-08-11 12:49:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string CInv::ToString() const
|
|
|
|
{
|
2016-11-09 07:09:16 -03: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 12:49:03 -04:00
|
|
|
}
|
2015-12-07 11:31:32 -03:00
|
|
|
|
|
|
|
const std::vector<std::string> &getAllNetMessageTypes()
|
|
|
|
{
|
|
|
|
return allNetMessageTypesVec;
|
|
|
|
}
|
2020-02-16 22:53:13 -03:00
|
|
|
|
|
|
|
std::string serviceFlagToStr(const uint64_t mask, const int bit)
|
|
|
|
{
|
|
|
|
switch (ServiceFlags(mask)) {
|
|
|
|
case NODE_NONE: abort(); // impossible
|
|
|
|
case NODE_NETWORK: return "NETWORK";
|
|
|
|
case NODE_GETUTXO: return "GETUTXO";
|
|
|
|
case NODE_BLOOM: return "BLOOM";
|
|
|
|
case NODE_WITNESS: return "WITNESS";
|
|
|
|
case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
|
|
|
|
// Not using default, so we get warned when a case is missing
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ostringstream stream;
|
|
|
|
stream.imbue(std::locale::classic());
|
|
|
|
stream << "UNKNOWN[";
|
|
|
|
if (bit < 8) {
|
|
|
|
stream << mask;
|
|
|
|
} else {
|
|
|
|
stream << "2^" << bit;
|
|
|
|
}
|
|
|
|
stream << "]";
|
|
|
|
return stream.str();
|
|
|
|
}
|