diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -756,12 +756,32 @@ CNetMessage GetMessage(const Config &config, int64_t time) override; }; +/** + * The TransportSerializer prepares messages for the network transport + */ +class TransportSerializer { +public: + // prepare message for transport (header construction, error-correction + // computation, payload encryption, etc.) + virtual void prepareForTransport(const Config &config, + CSerializedNetMsg &msg, + std::vector &header) = 0; + virtual ~TransportSerializer() {} +}; + +class V1TransportSerializer : public TransportSerializer { +public: + void prepareForTransport(const Config &config, CSerializedNetMsg &msg, + std::vector &header) override; +}; + /** Information about a peer */ class CNode { friend class CConnman; public: std::unique_ptr m_deserializer; + std::unique_ptr m_serializer; // socket std::atomic nServices{NODE_NONE}; diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -750,6 +750,22 @@ return msg; } +void V1TransportSerializer::prepareForTransport(const Config &config, + CSerializedNetMsg &msg, + std::vector &header) { + // create dbl-sha256 checksum + uint256 hash = Hash(msg.data.begin(), msg.data.end()); + + // create header + CMessageHeader hdr(config.GetChainParams().NetMagic(), msg.command.c_str(), + msg.data.size()); + memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE); + + // serialize header + header.reserve(CMessageHeader::HEADER_SIZE); + CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, header, 0, hdr}; +} + size_t CConnman::SocketSendData(CNode *pnode) const EXCLUSIVE_LOCKS_REQUIRED(pnode->cs_vSend) { size_t nSentSize = 0; @@ -2932,6 +2948,8 @@ m_deserializer = std::make_unique( V1TransportDeserializer(GetConfig().GetChainParams().NetMagic(), SER_NETWORK, INIT_PROTO_VERSION)); + m_serializer = + std::make_unique(V1TransportSerializer()); } CNode::~CNode() { @@ -2944,18 +2962,13 @@ void CConnman::PushMessage(CNode *pnode, CSerializedNetMsg &&msg) { size_t nMessageSize = msg.data.size(); - size_t nTotalSize = nMessageSize + CMessageHeader::HEADER_SIZE; LogPrint(BCLog::NET, "sending %s (%d bytes) peer=%d\n", SanitizeString(msg.command), nMessageSize, pnode->GetId()); + // make sure we use the appropriate network transport format std::vector serializedHeader; - serializedHeader.reserve(CMessageHeader::HEADER_SIZE); - uint256 hash = Hash(msg.data.data(), msg.data.data() + nMessageSize); - CMessageHeader hdr(config->GetChainParams().NetMagic(), msg.command.c_str(), - nMessageSize); - memcpy(hdr.pchChecksum, hash.begin(), CMessageHeader::CHECKSUM_SIZE); - - CVectorWriter{SER_NETWORK, INIT_PROTO_VERSION, serializedHeader, 0, hdr}; + pnode->m_serializer->prepareForTransport(*config, msg, serializedHeader); + size_t nTotalSize = nMessageSize + serializedHeader.size(); size_t nBytesSent = 0; {