Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

made protocol.h more similar to bitcoin #1688

Merged
merged 5 commits into from
May 30, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/addrman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ bool CAddrMan::Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimeP
pinfo->nTime = max((int64_t)0, addr.nTime - nTimePenalty);

// add services
pinfo->nServices |= addr.nServices;
pinfo->nServices = ServiceFlags(pinfo->nServices | addr.nServices);

// do not update if no new information is present
if (!addr.nTime || (pinfo->nTime && addr.nTime <= pinfo->nTime))
Expand Down
8 changes: 5 additions & 3 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ struct LocalServiceInfo {
//
bool fDiscover = true;
bool fUseUPnP = false;
uint64_t nLocalServices = NODE_NETWORK;
ServiceFlags nLocalServices = NODE_NETWORK;
static CCriticalSection cs_mapLocalHost;
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {};
Expand Down Expand Up @@ -159,7 +159,8 @@ bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
// get best local address for a particular peer as a CAddress
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
{
CAddress ret(CService("0.0.0.0",0),0);
ServiceFlags nLocalServices = NODE_NETWORK;
CAddress ret(CService("0.0.0.0",0), nLocalServices);
CService addr;
if (GetLocal(addr, paddrPeer))
{
Expand Down Expand Up @@ -727,8 +728,9 @@ void CNode::PushVersion()
std::string mycpid;
std::string acid;

//TODO: change `PushMessage()` to use ServiceFlags so we don't need to cast nLocalServices
PushMessage("aries", PROTOCOL_VERSION, nonce, pw1,
mycpid, mycpid, acid, nLocalServices, nTime, addrYou, addrMe,
mycpid, mycpid, acid, (uint64_t) nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()),
nBestHeight);

Expand Down
2 changes: 1 addition & 1 deletion src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CRequestTracker
extern bool fDiscover;
void Discover(boost::thread_group& threadGroup);
extern bool fUseUPnP;
extern uint64_t nLocalServices;
extern ServiceFlags nLocalServices;
extern uint64_t nLocalHostNonce;
extern CAddress addrSeenByPeer;
extern CAddrMan addrman;
Expand Down
26 changes: 1 addition & 25 deletions src/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,37 +75,13 @@ bool CMessageHeader::IsValid() const
return true;
}



CAddress::CAddress() : CService()
{
Init();
}

CAddress::CAddress(CService ipIn, uint64_t nServicesIn) : CService(ipIn)
{
Init();
nServices = nServicesIn;
}

void CAddress::Init()
{
nServices = NODE_NETWORK;
nTime = 100000000;
nLastTry = 0;
}

CInv::CInv()
{
type = 0;
hash.SetNull();
}

CInv::CInv(int typeIn, const uint256& hashIn)
{
type = typeIn;
hash = hashIn;
}
CInv::CInv(int typeIn, const uint256& hashIn) : type(typeIn), hash(hashIn) {}

CInv::CInv(const std::string& strType, const uint256& hashIn)
{
Expand Down
54 changes: 23 additions & 31 deletions src/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ extern unsigned char pchMessageStart[4];
class CMessageHeader
{
public:
static constexpr size_t MESSAGE_START_SIZE = 4;
jamescowens marked this conversation as resolved.
Show resolved Hide resolved
static constexpr size_t COMMAND_SIZE = 12;
static constexpr size_t MESSAGE_SIZE_SIZE = 4;
static constexpr size_t CHECKSUM_SIZE = 4;
static constexpr size_t MESSAGE_SIZE_OFFSET = MESSAGE_START_SIZE + COMMAND_SIZE;
static constexpr size_t CHECKSUM_OFFSET = MESSAGE_SIZE_OFFSET + MESSAGE_SIZE_SIZE;
static constexpr size_t HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE;

CMessageHeader();
CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);

Expand All @@ -52,47 +60,36 @@ class CMessageHeader
READWRITE(nChecksum);
}

// TODO: make private (improves encapsulation)
//HALFORD: 12-26-2014 - Add Encryption to messages - Increase size by 32 for checksum + delimiters + 10 for timestamp = 50 = 62 (vs 12)
public:
enum {
MESSAGE_START_SIZE=sizeof(::pchMessageStart),
COMMAND_SIZE=12,
MESSAGE_SIZE_SIZE=sizeof(int),
CHECKSUM_SIZE=sizeof(int),

MESSAGE_SIZE_OFFSET=MESSAGE_START_SIZE+COMMAND_SIZE,
CHECKSUM_OFFSET=MESSAGE_SIZE_OFFSET+MESSAGE_SIZE_SIZE,
HEADER_SIZE=MESSAGE_START_SIZE+COMMAND_SIZE+MESSAGE_SIZE_SIZE+CHECKSUM_SIZE
};
char pchMessageStart[MESSAGE_START_SIZE];
char pchCommand[COMMAND_SIZE];
unsigned int nMessageSize;
uint32_t nMessageSize;
unsigned int nChecksum;
};

/** nServices flags */
enum
{
enum ServiceFlags : uint64_t {
// NODE_NETWORK means that the node is capable of serving the complete block chain.
NODE_NETWORK = (1 << 0),
};

/** A CService with information about it as peer */
class CAddress : public CService
{
public:
CAddress();
explicit CAddress(CService ipIn, uint64_t nServicesIn=NODE_NETWORK);
static constexpr uint32_t TIME_INIT{100000000};

void Init();
public:
CAddress() : CService{} {};
explicit CAddress(CService ipIn, ServiceFlags nServicesIn=NODE_NETWORK): CService{ipIn}, nServices{nServicesIn} {};

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action)
{
if (ser_action.ForRead()) {
Init();
nServices = NODE_NETWORK;
nTime = 100000000;
nLastTry = 0;
jamescowens marked this conversation as resolved.
Show resolved Hide resolved
}

int nVersion = s.GetVersion();
Expand All @@ -106,21 +103,17 @@ class CAddress : public CService
READWRITE(nTime);
}

READWRITE(nServices);
READWRITE(Using<CustomUintFormatter<8>>(nServices));
READWRITEAS(CService, *this);
}

void print() const;

// TODO: make private (improves encapsulation)
public:
uint64_t nServices;

ServiceFlags nServices{NODE_NETWORK};
// disk and network only
unsigned int nTime;

uint32_t nTime{TIME_INIT};
// memory only
int64_t nLastTry;
int64_t nLastTry = 0;
};

/** inv message data */
Expand All @@ -147,10 +140,9 @@ class CInv
std::string ToString() const;
void print() const;

// TODO: make private (improves encapsulation)
public:
int type;
uint256 hash;
};


#endif // __INCLUDED_PROTOCOL_H__
70 changes: 70 additions & 0 deletions src/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,33 @@ I ReadVarInt(Stream& is)
}
}

/** Simple wrapper class to serialize objects using a formatter; used by Using(). */
template<typename Formatter, typename T>
class Wrapper
{
static_assert(std::is_lvalue_reference<T>::value, "Wrapper needs an lvalue reference type T");
protected:
T m_object;
public:
explicit Wrapper(T obj) : m_object(obj) {}
template<typename Stream> void Serialize(Stream &s) const { Formatter().Ser(s, m_object); }
template<typename Stream> void Unserialize(Stream &s) { Formatter().Unser(s, m_object); }
};


/** Cause serialization/deserialization of an object to be done using a specified formatter class.
*
* To use this, you need a class Formatter that has public functions Ser(stream, const object&) for
* serialization, and Unser(stream, object&) for deserialization. Serialization routines (inside
* READWRITE, or directly with << and >> operators), can then use Using<Formatter>(object).
*
* This works by constructing a Wrapper<Formatter, T>-wrapped version of object, where T is
* const during serialization, and non-const during deserialization, which maintains const
* correctness.
*/
template<typename Formatter, typename T>
static inline Wrapper<Formatter, T&> Using(T&& t) { return Wrapper<Formatter, T&>(t); }

#define VARINT(obj, ...) WrapVarInt<__VA_ARGS__>(REF(obj))
#define COMPACTSIZE(obj) CCompactSize(REF(obj))
#define LIMITED_STRING(obj,n) LimitedString< n >(REF(obj))
Expand Down Expand Up @@ -499,6 +526,49 @@ class CCompactSize
}
};

/** Serialization wrapper class for custom integers and enums.
*
* It permits specifying the serialized size (1 to 8 bytes) and endianness.
*
* Use the big endian mode for values that are stored in memory in native
* byte order, but serialized in big endian notation. This is only intended
* to implement serializers that are compatible with existing formats, and
* its use is not recommended for new data structures.
*/
template<int Bytes, bool BigEndian = false>
struct CustomUintFormatter
{
static_assert(Bytes > 0 && Bytes <= 8, "CustomUintFormatter Bytes out of range");
static constexpr uint64_t MAX = 0xffffffffffffffff >> (8 * (8 - Bytes));

template <typename Stream, typename I> void Ser(Stream& s, I v)
{
if (v < 0 || v > MAX) throw std::ios_base::failure("CustomUintFormatter value out of range");
if (BigEndian) {
uint64_t raw = htobe64(v);
s.write(((const char*)&raw) + 8 - Bytes, Bytes);
} else {
uint64_t raw = htole64(v);
s.write((const char*)&raw, Bytes);
}
}

template <typename Stream, typename I> void Unser(Stream& s, I& v)
{
using U = typename std::conditional<std::is_enum<I>::value, std::underlying_type<I>, std::common_type<I>>::type::type;
static_assert(std::numeric_limits<U>::max() >= MAX && std::numeric_limits<U>::min() <= 0, "Assigned type too small");
uint64_t raw = 0;
if (BigEndian) {
s.read(((char*)&raw) + 8 - Bytes, Bytes);
v = static_cast<I>(be64toh(raw));
} else {
s.read((char*)&raw, Bytes);
v = static_cast<I>(le64toh(raw));
}
}
};


template<size_t Limit>
class LimitedString
{
Expand Down