Skip to content
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

net: Refactor message parsing (CNetMessage), adds flexibility #14046

Closed

Conversation

jonasschnelli
Copy link
Contributor

This refactors the code how incoming messages gets handled.
It adds flexibility for adding new transport types (encryption handshake, new message format).

This is a subset of #14032 and a pre-requirement for BIP151.

@promag
Copy link
Member

promag commented Aug 24, 2018

Any reason to not use unique_ptr instead? I don't see sharing of message ownership.

@jonasschnelli
Copy link
Contributor Author

I think shared is fine here and does allow more flexible handling in future with little cost (ref counting)

@maflcko maflcko changed the title Refactor message parsing (CNetMessage), adds flexibility net: Refactor message parsing (CNetMessage), adds flexibility Aug 24, 2018
@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 24, 2018

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #16562 (Refactor message transport packaging by jonasschnelli)
  • #16324 (Get cs_main out of the critical path in ProcessMessages by TheBlueMatt)
  • #16323 (Call ProcessNewBlock() asynchronously by TheBlueMatt)
  • #16273 (refactor: Remove unused includes by practicalswift)
  • #16248 (Make whitebind/whitelist permissions more flexible by NicolasDorier)
  • #16202 (Refactor network message deserialization by jonasschnelli)
  • #15206 (Immediately disconnect on invalid net message checksum by jonasschnelli)
  • #15197 (Refactor and slightly stricter p2p message processing by jonasschnelli)

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.

@maflcko
Copy link
Member

maflcko commented Aug 24, 2018

utACK 59a7ce0f9de950b64c5e89dd29ebcd0b607b982e

@gmaxwell
Copy link
Contributor

Adding an extra memory allocation for every network message isn't free. I'm concerned that we may be falling into overusing sharedptr "just in case", which is bad because it leaks performance in a diffuse way that doesn't show up well in profiles. Please don't use sharedptr where unique will work. If something new comes in in the future that needs a sharedptr then we can switch then.

@sipa
Copy link
Member

sipa commented Aug 24, 2018

@gmaxwell unique_ptr and shared_ptr have the same number of allocations (if make_shared is used, at least), though shared_ptr uses more memory (both for the pointer itself and for the allocated memory), and has atomics to update the refcounts (which may reduce performance).

To be clear, I agree we should avoid shared_ptr unless there is a good reason.

src/net.cpp Outdated Show resolved Hide resolved
src/net_processing.cpp Outdated Show resolved Hide resolved
src/net_message.h Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
src/net_message.h Outdated Show resolved Hide resolved
@jonasschnelli
Copy link
Contributor Author

@sipa, @gmaxwell:
The reason why I used shared_ptr over unique_ptr is the polymorphism I'd like to use for the net messages and I once read that shared_ptr are recommended for polymorphic inheritance.

However, I changed this PR now to use unique_ptr.

Thanks @251labs for the review, implemented all your suggestions.

@jonasschnelli jonasschnelli force-pushed the 2018/08/bip151_pre_refactor branch 2 times, most recently from e43f3b7 to 837beb4 Compare August 27, 2018 11:33
Copy link
Member

@promag promag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix commit message "Use shared pointers for CNetMessage handling".

src/net.h Outdated Show resolved Hide resolved
@jonasschnelli
Copy link
Contributor Author

Fixed commit message issue reported by @promag

src/net.h Outdated Show resolved Hide resolved
src/net_message.cpp Outdated Show resolved Hide resolved
@jonasschnelli jonasschnelli force-pushed the 2018/08/bip151_pre_refactor branch 2 times, most recently from 7c1f556 to c2f9c04 Compare September 18, 2018 07:52
@promag
Copy link
Member

promag commented Oct 19, 2018

utACK c2f9c04.

@sipa
Copy link
Member

sipa commented Oct 19, 2018

Is it really necessary to make CNetMessage a virtual class? This seems very much overkill. Only the network deserializers should change based on what protocol is used; we don't need to have that variability put a burden on every separate message.

Seems like you could just create a CNetMessageSerializer class (with different instances), to which some of the current CNetMessage logic is moved. This class is then responsible for turning the network byte stream into packets, and the other way around, but the CNetMessage objects remain independent of the protocol used.

@maflcko
Copy link
Member

maflcko commented Nov 7, 2018

@jonasschnelli Mind to follow up on @sipa's question? I have removed this from high priority for now, but happy to add back when you addressed the question.

@jonasschnelli
Copy link
Contributor Author

Rebased

@sipa
Copy link
Member

sipa commented May 20, 2019

Approach NACK. This is overkill; the message parsing/serializing logic can just move out of CNetMessage to avoid turning it into a virtual class.

@jonasschnelli
Copy link
Contributor Author

@sipa: Thanks for the review. Currently turning this into the approach you mentioned. I think it's doable though not super convinced right now due to the state necessary in parsing/serialization (hash, MAC).
Until I'm finished I keep this rebased to not lose testability of other elements in the pipeline.

@jonasschnelli
Copy link
Contributor Author

#16202 seems to a superior solution. Will close this PR as soon as #14032 is rebased on top of #16202.

@fanquake fanquake added this to In progress in P2P refactor Jun 17, 2019
@DrahtBot
Copy link
Contributor

Needs rebase

fanquake added a commit that referenced this pull request Oct 28, 2019
ed2dc5e Add override/final modifiers to V1TransportDeserializer (Pieter Wuille)
f342a5e Make resetting implicit in TransportDeserializer::Read() (Pieter Wuille)
6a91499 Remove oversized message detection from log and interface (Pieter Wuille)
b0e10ff Force CNetMessage::m_recv to use std::move (Jonas Schnelli)
efecb74 Use adapter pattern for the network deserializer (Jonas Schnelli)
1a5c656 Remove transport protocol knowhow from CNetMessage / net processing (Jonas Schnelli)
6294ecd Refactor: split network transport deserializing from message container (Jonas Schnelli)

Pull request description:

  **This refactors the network message deserialization.**

  * It transforms the `CNetMessage` into a transport protocol agnostic message container.
  * A new class `TransportDeserializer` (unique pointer of `CNode`)  is introduced, handling the network buffer reading and the decomposing to a `CNetMessage`
  * **No behavioral changes** (in terms of disconnecting, punishing)
  * Moves the checksum finalizing into the `SocketHandler` thread (finalizing was in `ProcessMessages` 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](#14046 (comment)) from sipa

ACKs for top commit:
  promag:
    Code review ACK ed2dc5e.
  marcinja:
    Code review ACK ed2dc5e
  ryanofsky:
    Code review ACK ed2dc5e. 4 cleanup commits added since last review. Unaddressed comments:
  ariard:
    Code review and tested ACK ed2dc5e.

Tree-SHA512: bab8d87464e2e8742529e488ddcdc8650f0c2025c9130913df00a0b17ecdb9a525061cbbbd0de0251b76bf75a8edb72e3ad0dbf5b79e26f2ad05d61b4e4ded6d
@jonasschnelli
Copy link
Contributor Author

Superseded. Closing.

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
@dhruv dhruv added this to Closed unmerged in P2P encryption Mar 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
P2P encryption
Closed unmerged (Superseded)
Status: Closed unmerged (Superseded)
P2P refactor
In progress
Development

Successfully merging this pull request may close these issues.

None yet