-
Notifications
You must be signed in to change notification settings - Fork 37.7k
p2p: Refactor network message deserialization #16202
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
p2p: Refactor network message deserialization #16202
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
3fa744d
to
7bd4dd2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for the adapter pattern, there may still room for few interfaces improvements.
Current draft of BIP 324 : https://gist.github.com/jonasschnelli/c530ea8421b8d0e80c51486325587c52 (a help for review and not yet in bips repo I think)
4cbe0af
to
e85d88d
Compare
Thanks @ariard for the review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK e85d88d
Concept and approach ACK. I'll go through the code in more detail soon, but one thing I noticed is that this introduces an unnecessary copy of the message payload in the |
5f34746
to
1396bd4
Compare
Concept ACK, following #14046 (comment) does makes sense vs #14046. |
1396bd4
to
7370bed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 7370bed
Reviewed code, ran unit tests and functional tests successfully.
@@ -3280,7 +3280,7 @@ bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& inter | |||
return false; | |||
// Just take one message | |||
msgs.splice(msgs.begin(), pfrom->vProcessMsg, pfrom->vProcessMsg.begin()); | |||
pfrom->nProcessQueueSize -= msgs.front().m_recv.size() + CMessageHeader::HEADER_SIZE; | |||
pfrom->nProcessQueueSize -= msgs.front().m_raw_message_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to do a double-take here... But this shouldn't change behaviour as msgs.front().m_recv.size()
is always equal to msgs.front().m_message_size
because the msgs.front().m_recv
hasn't advanced its nReadPos
yet. Verified by placing an assert and running the unit and functional tests.
ACK 7370bed Approach is very clean. All unit and functional tests pass. Manually tested some P2P functionality to provide additional confidence. |
src/net.h
Outdated
std::string m_command; | ||
|
||
CNetMessage(const CDataStream& recv_in) : m_recv(std::move(recv_in)) { | ||
m_time = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Use default member initializers for these rather than repeating the members in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if more refactoring would be first required, but it would be nice if StatusOr<CNetMessage> Deserialize(CDataStream& stream); Where StatusOr is essentially a variant type of error or result, though I suppose exceptions could be used instead. An output parameter for the result is another possibility. I'm not sure what the project conventions are for the error or result pattern. Then Otherwise, the client is responsible for knowing in which order the methods of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 7370bed, reviewed code, ran unit and functional tests both at the mentioned commit and also rebased on current master fdfaeb6, with additional asserts and custom logging as a sanity check. I am currently observing a running node with these changes rebased on master with custom logging and asserts.
I do agree that continued refactoring to simplify handling of state might potentially be worthwhile. Given this PR is the result of at least one previous refactoring attempt and has been in review since June (and depending on the author's motivation to keep reworking it), it might be more flexible to try it in a follow-up PR if merging this one as-is can further v2 p2p progress.
src/net_processing.cpp
Outdated
SanitizeString(strCommand), nMessageSize, | ||
HexStr(hash.begin(), hash.begin()+CMessageHeader::CHECKSUM_SIZE), | ||
HexStr(hdr.pchChecksum, hdr.pchChecksum+CMessageHeader::CHECKSUM_SIZE)); | ||
LogPrint(BCLog::NET, "%s(%s, %u bytes): CHECKSUM ERROR\n", __func__, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be useful to print pfrom->GetId()
in here also.
ACK 7370bed Reviewed code and ran tests at each commit. I also agree with other reviewers that a stateless deserializer would be nice for a potential follow-up. |
16d6113 Refactor message transport packaging (Jonas Schnelli) Pull request description: This PR factors out transport packaging logic from `CConnman::PushMessage()`. It's similar to #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
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
Summary: Partial backport 1/7 of core [[bitcoin/bitcoin#16202 | PR16202]]: bitcoin/bitcoin@6294ecd Adapted to match our codebase. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK, jasonbcox Reviewed By: #bitcoin_abc, PiRK, jasonbcox Subscribers: jasonbcox Differential Revision: https://reviews.bitcoinabc.org/D8222
Summary: Partial backport 2/7 of core [[bitcoin/bitcoin#16202 | PR16202]]: bitcoin/bitcoin@1a5c656 Depends on D8222. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK, jasonbcox Reviewed By: #bitcoin_abc, PiRK, jasonbcox Differential Revision: https://reviews.bitcoinabc.org/D8223
Summary: Partial backport 3/7 of core [[bitcoin/bitcoin#16202 | PR16202]]: bitcoin/bitcoin@efecb74 Depends on D8223. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK, jasonbcox Reviewed By: #bitcoin_abc, PiRK, jasonbcox Differential Revision: https://reviews.bitcoinabc.org/D8224
Summary: Partial backport 4/7 of core [[bitcoin/bitcoin#16202 | PR16202]]: bitcoin/bitcoin@b0e10ff Depends on D8224. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK, jasonbcox Reviewed By: #bitcoin_abc, PiRK, jasonbcox Differential Revision: https://reviews.bitcoinabc.org/D8225
Summary: Partial backport 5/7 of core [[bitcoin/bitcoin#16202 | PR16202]]: bitcoin/bitcoin@6a91499 Depends on D8225. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK, jasonbcox Reviewed By: #bitcoin_abc, PiRK, jasonbcox Subscribers: jasonbcox Differential Revision: https://reviews.bitcoinabc.org/D8226
Summary: Partial backport 6/7 of core [[bitcoin/bitcoin#16202 | PR16202]]: bitcoin/bitcoin@f342a5e Depends on D8226. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK, jasonbcox Reviewed By: #bitcoin_abc, PiRK, jasonbcox Differential Revision: https://reviews.bitcoinabc.org/D8227
Summary: Completes backport (7/7) of core [[bitcoin/bitcoin#16202 | PR16202]]: bitcoin/bitcoin@ed2dc5e Depends on D8227. Test Plan: ninja all check-all Reviewers: #bitcoin_abc, PiRK, jasonbcox Reviewed By: #bitcoin_abc, PiRK, jasonbcox Differential Revision: https://reviews.bitcoinabc.org/D8228
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
Reset(); | ||
} | ||
|
||
bool Complete() const override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this function in the .h instead of the .cpp?
|
||
int readHeader(const char *pch, unsigned int nBytes); | ||
int readData(const char *pch, unsigned int nBytes); | ||
int Read(const char *pch, unsigned int nBytes) override { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this function in the .h instead of in the .cpp?
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This refactors the network message deserialization.
CNetMessage
into a transport protocol agnostic message container.TransportDeserializer
(unique pointer ofCNode
) is introduced, handling the network buffer reading and the decomposing to aCNetMessage
SocketHandler
thread (finalizing was inProcessMessages
before)The optional last commit makes the
TransportDeserializer
following an adapter pattern (polymorphic interface) to make it easier to later add a V2 transport protocol deserializer.Intentionally not touching the sending part.
Pre-Requirement for BIP324 (v2 message transport protocol).
Replacement for #14046 and inspired by a comment from sipa