Skip to content

Commit

Permalink
Merge bitcoin#16562: Refactor message transport packaging
Browse files Browse the repository at this point in the history
16d6113 Refactor message transport packaging (Jonas Schnelli)

Pull request description:

  This PR factors out transport packaging logic from `CConnman::PushMessage()`.
  It's similar to bitcoin#16202 (where we refactor deserialization).

  This allows implementing a new message transport protocol like BIP324.

ACKs for top commit:
  dongcarl:
    ACK 16d6113 FWIW
  ariard:
    Code review ACK 16d6113
  elichai:
    semiACK 16d6113 ran functional+unit tests.
  MarcoFalke:
    ACK 16d6113 🙎

Tree-SHA512: 8c2f8ab9f52e9b94327973ae15019a08109d5d9f9247492703a842827c5b5d634fc0411759e0bb316d824c586614b0220c2006410851933613bc143e58f7e6c1
  • Loading branch information
MarcoFalke authored and sidhujag committed Feb 29, 2020
1 parent 45b7587 commit 78a5556
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,19 @@ CNetMessage V1TransportDeserializer::GetMessage(const CMessageHeader::MessageSta
return msg;
}

void V1TransportSerializer::prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) {
// create dbl-sha256 checksum
uint256 hash = Hash(msg.data.begin(), msg.data.end());

// create header
CMessageHeader hdr(Params().MessageStart(), 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)
{
auto it = pnode->vSendMsg.begin();
Expand Down Expand Up @@ -2814,6 +2827,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
}

m_deserializer = MakeUnique<V1TransportDeserializer>(V1TransportDeserializer(Params().MessageStart(), SER_NETWORK, INIT_PROTO_VERSION));
m_serializer = MakeUnique<V1TransportSerializer>(V1TransportSerializer());
}

CNode::~CNode()
Expand All @@ -2829,16 +2843,12 @@ bool CConnman::NodeFullyConnected(const CNode* pnode)
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<unsigned char> serializedHeader;
serializedHeader.reserve(CMessageHeader::HEADER_SIZE);
uint256 hash = Hash(msg.data.data(), msg.data.data() + nMessageSize);
CMessageHeader hdr(Params().MessageStart(), 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(msg, serializedHeader);
size_t nTotalSize = nMessageSize + serializedHeader.size();

size_t nBytesSent = 0;
{
Expand Down
15 changes: 15 additions & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,12 +787,27 @@ class V1TransportDeserializer final : public TransportDeserializer
CNetMessage GetMessage(const CMessageHeader::MessageStartChars& message_start, 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(CSerializedNetMsg& msg, std::vector<unsigned char>& header) = 0;
virtual ~TransportSerializer() {}
};

class V1TransportSerializer : public TransportSerializer {
public:
void prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) override;
};

/** Information about a peer */
class CNode
{
friend class CConnman;
public:
std::unique_ptr<TransportDeserializer> m_deserializer;
std::unique_ptr<TransportSerializer> m_serializer;

// socket
std::atomic<ServiceFlags> nServices{NODE_NONE};
Expand Down

0 comments on commit 78a5556

Please sign in to comment.