@@ -259,8 +259,7 @@ class Transport {
259259 virtual ~Transport () {}
260260
261261 // 1. Receiver side functions, for decoding bytes received on the wire into transport protocol
262- // agnostic CNetMessage (message type & payload) objects. Callers must guarantee that none of
263- // these functions are called concurrently w.r.t. one another.
262+ // agnostic CNetMessage (message type & payload) objects.
264263
265264 // returns true if the current deserialization is complete
266265 virtual bool Complete () const = 0;
@@ -282,20 +281,22 @@ class V1Transport final : public Transport
282281private:
283282 const CChainParams& m_chain_params;
284283 const NodeId m_node_id; // Only for logging
285- mutable CHash256 hasher;
286- mutable uint256 data_hash;
287- bool in_data; // parsing header (false) or data (true)
288- CDataStream hdrbuf; // partially received header
289- CMessageHeader hdr; // complete header
290- CDataStream vRecv; // received message data
291- unsigned int nHdrPos;
292- unsigned int nDataPos;
293-
294- const uint256& GetMessageHash () const ;
295- int readHeader (Span<const uint8_t > msg_bytes);
296- int readData (Span<const uint8_t > msg_bytes);
297-
298- void Reset () {
284+ mutable Mutex m_recv_mutex; // !< Lock for receive state
285+ mutable CHash256 hasher GUARDED_BY (m_recv_mutex);
286+ mutable uint256 data_hash GUARDED_BY (m_recv_mutex);
287+ bool in_data GUARDED_BY (m_recv_mutex); // parsing header (false) or data (true)
288+ CDataStream hdrbuf GUARDED_BY (m_recv_mutex); // partially received header
289+ CMessageHeader hdr GUARDED_BY (m_recv_mutex); // complete header
290+ CDataStream vRecv GUARDED_BY (m_recv_mutex); // received message data
291+ unsigned int nHdrPos GUARDED_BY (m_recv_mutex);
292+ unsigned int nDataPos GUARDED_BY (m_recv_mutex);
293+
294+ const uint256& GetMessageHash () const EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
295+ int readHeader (Span<const uint8_t > msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
296+ int readData (Span<const uint8_t > msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
297+
298+ void Reset () EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex) {
299+ AssertLockHeld (m_recv_mutex);
299300 vRecv.clear ();
300301 hdrbuf.clear ();
301302 hdrbuf.resize (24 );
@@ -306,29 +307,42 @@ class V1Transport final : public Transport
306307 hasher.Reset ();
307308 }
308309
310+ bool CompleteInternal () const noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
311+ {
312+ AssertLockHeld (m_recv_mutex);
313+ if (!in_data) return false ;
314+ return hdr.nMessageSize == nDataPos;
315+ }
316+
309317public:
310318 V1Transport (const CChainParams& chain_params, const NodeId node_id, int nTypeIn, int nVersionIn)
311319 : m_chain_params(chain_params),
312320 m_node_id (node_id),
313321 hdrbuf(nTypeIn, nVersionIn),
314322 vRecv(nTypeIn, nVersionIn)
315323 {
324+ LOCK (m_recv_mutex);
316325 Reset ();
317326 }
318327
319- bool Complete () const override
328+ bool Complete () const override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
320329 {
321- if (!in_data)
322- return false ;
323- return (hdr.nMessageSize == nDataPos);
330+ AssertLockNotHeld (m_recv_mutex);
331+ return WITH_LOCK (m_recv_mutex, return CompleteInternal ());
324332 }
325- void SetVersion (int nVersionIn) override
333+
334+ void SetVersion (int nVersionIn) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
326335 {
336+ AssertLockNotHeld (m_recv_mutex);
337+ LOCK (m_recv_mutex);
327338 hdrbuf.SetVersion (nVersionIn);
328339 vRecv.SetVersion (nVersionIn);
329340 }
330- int Read (Span<const uint8_t >& msg_bytes) override
341+
342+ int Read (Span<const uint8_t >& msg_bytes) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
331343 {
344+ AssertLockNotHeld (m_recv_mutex);
345+ LOCK (m_recv_mutex);
332346 int ret = in_data ? readData (msg_bytes) : readHeader (msg_bytes);
333347 if (ret < 0 ) {
334348 Reset ();
@@ -337,7 +351,7 @@ class V1Transport final : public Transport
337351 }
338352 return ret;
339353 }
340- CNetMessage GetMessage (std::chrono::microseconds time, bool & reject_message) override ;
354+ CNetMessage GetMessage (std::chrono::microseconds time, bool & reject_message) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex) ;
341355
342356 void prepareForTransport (CSerializedNetMsg& msg, std::vector<unsigned char >& header) const override ;
343357};
0 commit comments