#include <protocol.h>
#include <common/system.h>
CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* msg_type, unsigned int nMessageSizeIn)
: pchMessageStart{pchMessageStartIn}
{
size_t i = 0;
for (; i < MESSAGE_TYPE_SIZE && msg_type[i] != 0; ++i) m_msg_type[i] = msg_type[i];
assert(msg_type[i] == 0);
nMessageSize = nMessageSizeIn;
}
std::string CMessageHeader::GetMessageType() const
{
return std::string(m_msg_type, m_msg_type + strnlen(m_msg_type, MESSAGE_TYPE_SIZE));
}
bool CMessageHeader::IsMessageTypeValid() const
{
for (const char* p1 = m_msg_type; p1 < m_msg_type + MESSAGE_TYPE_SIZE; ++p1) {
if (*p1 == 0) {
for (; p1 < m_msg_type + MESSAGE_TYPE_SIZE; ++p1) {
if (*p1 != 0) {
return false;
}
}
} else if (*p1 < ' ' || *p1 > 0x7E) {
return false;
}
}
return true;
}
CInv::CInv()
{
type = 0;
hash.SetNull();
}
CInv::CInv(uint32_t typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}
bool operator<(const CInv& a, const CInv& b)
{
return (a.type < b.type || (a.type == b.type && a.hash < b.hash));
}
std::string CInv::GetMessageType() const
{
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_WTX: return cmd.append("wtx");
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:
throw std::out_of_range(strprintf("CInv::GetMessageType(): type=%d unknown type", type));
}
}
std::string CInv::ToString() const
{
try {
return strprintf("%s %s", GetMessageType(), hash.ToString());
} catch(const std::out_of_range &) {
return strprintf("0x%08x %s", type, hash.ToString());
}
}
static std::string serviceFlagToStr(size_t bit)
{
const uint64_t service_flag = 1ULL << bit;
switch ((ServiceFlags)service_flag) {
case NODE_NONE: abort(); case NODE_NETWORK: return "NETWORK";
case NODE_BLOOM: return "BLOOM";
case NODE_WITNESS: return "WITNESS";
case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
case NODE_P2P_V2: return "P2P_V2";
}
return strprintf("UNKNOWN[2^%u]", bit);
}
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;
}
GenTxid ToGenTxid(const CInv& inv)
{
assert(inv.IsGenTxMsg());
return inv.IsMsgWtx() ? GenTxid{Wtxid::FromUint256(inv.hash)} : GenTxid{Txid::FromUint256(inv.hash)};
}