Node Message Handling

I worked on moving the new Serialization code into the node message handling which went pretty smooth. I had a buffer before with structures pointing directly into it and had a lot of boilerplate code to handle each specific message. With the new serialization code I decided I wanted to do it a bit more Objected Orientated and with less code.

Now I can have a single place that does everything in regards to a message, which is a lot easier to manage and read.

struct CMSG_Version : public CMessage
{
UINT32 dwVersion;
UINT64 qwTXConfirmed;
UINT64 qwTime;
CMSG_Version() : CMessage(MSGID_VERSION) {}
void Serialize(CSerialize &ser) const
{
ser & dwVersion;
ser & qwTXConfirmed;
ser & qwTime;
}
bool Verify() const
{
return true;
}
};

This is the “version” message that is the first message that nodes send to each other after they have swapped their encyption/decryption keys. In the function Serialize() you can see how easy it is to write out data, it’s similar to how Boost does it but I wrote my own for MicroCash because no one needs the Boost bloat or dependancy.

All messages sent between nodes in MicroCash are encrypted using a custom TEA-CBC . Anyone who reads the network data sent will always have completely random looking messages between nodes, at ALL stages. There is no time when a non random looking packet is sent, no time for someone to peek at any unencrypted data which is a feature I like a lot.

Each packet contains a partial SHA-3 hash which is used for verification of the contents inside, after verifying the checksum matches what was sent the decryption process uses another part of the SHA-3 hash as the Initialization Vector to decrypt the contents of the packet. Also contained in each message is a bit of randomness, this means even if you sent the same message with the exact same data to a node it will look different “on the wire”.

Node messages are queued in such a way that you can throw as many threads as you want at it and each one should linearly decrease the work done. There is very little resource contention in the current design. There is no dynamic memory allocated once a thread owns a node to ensure it can do all its work without resource centralization. I had to use a little C++ trick with “placement new” to do this, by allocating a buffer before hand and then allowing polymorphism with this buffer later on when processing it.

All of these techniques are designed to hide what you are actually running which may be important in the future. They are also  very efficient which means even a modest home computer would be able to be in contact with a thousand other nodes and barely notice any performance degradation. In a next blog post I will discuss my bandwidth optimization and mesh network repair method to ensure the MicroCash network stays healthy and decentralized around the Earth to a high extent.

Advertisements
%d bloggers like this: