Skip to content

Conversation

troygiorshev
Copy link
Contributor

This PR contains a few follow-ups to #19107.

Most notable is a change to GetMessage, where it no longer returns an optional. Ultimately this was done in a heavy-handed way that didn't improve readability and would probably cause more problems than it would save.

@DrahtBot DrahtBot added the P2P label Nov 10, 2020
@DrahtBot
Copy link
Contributor

DrahtBot commented Nov 11, 2020

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

Conflicts

Reviewers, 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.

@troygiorshev
Copy link
Contributor Author

CI fails with "Timed out!" when running the fuzz tests, at exactly 2h of running time. Looks to be unrelated to this PR.

@maflcko
Copy link
Member

maflcko commented Nov 11, 2020

You can fix that by rebasing on current master

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

Code review ACK ec4fd8a. Thanks for followups #19107 (comment) and #19107 (comment)!

@troygiorshev troygiorshev force-pushed the 2020-11-19107-follow-ups branch from ec4fd8a to a10135e Compare November 17, 2020 05:40
@troygiorshev
Copy link
Contributor Author

git range-diff master ec4fd8a a10135e

  • Trivial rebase to master, to fix the CI error

GetMesage no longer returns an optional.

Additionally, we now access mapRecvBytesPerMsgCmd with `.at` not
`.find`.

This is shorter and more clear.
This throws an error if COMMAND_OTHER doesn't exist, which should never
happen.  `.find` instead just accessed the last element, which could
make debugging more difficult.

For this part, I think this is a definite improvement, but I'm not sure
it's the best solution.  Open to suggestions.
@troygiorshev troygiorshev force-pushed the 2020-11-19107-follow-ups branch from a10135e to 78fb468 Compare November 17, 2020 05:52
@troygiorshev
Copy link
Contributor Author

git range-diff master a10135e 78fb468

  • Initialized out parameter reject_message
  • Renamed COMMAND to MSGTYPE in error logs

Copy link
Contributor

@ajtowns ajtowns left a comment

Choose a reason for hiding this comment

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

PR title/description should summarise what was actually being done in this PR -- I think it's "[refactor] net.cpp: various minor cleanups" or similar?

I think you could split out ".find() to .at()" and "drop redundant out_err_raw_size" as separate commits; they seem pretty independent. I'm not sure having "this function might throw, but we're sure it never will" is better than "this function might deref end() but we're sure it never will" is better. Maybe an Assert() would be better, or maybe using &map[NET_MESSAGE_COMMAND_OTHER] (which creates it if missing) would be better.

I'm not seeing what the benefit of dropping the optional is though, it just changes:

    Optional<CNetMessage> x = GetMessage(time);
    if (!x) { ...; return; }
    do_stuff(*x);

to

    bool reject_message;
    CNetMessage x = GetMessage(time, reject_message);
    if (reject_message) { ...; return; }
    do_stuff(x);

which doesn't seem like an improvement to me?

@@ -2980,7 +2980,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
LogPrint(BCLog::NET, "Added connection peer=%d\n", id);
}

m_deserializer = MakeUnique<V1TransportDeserializer>(V1TransportDeserializer(Params(), GetId(), SER_NETWORK, INIT_PROTO_VERSION));
m_deserializer = MakeUnique<V1TransportDeserializer>(V1TransportDeserializer(Params(), id, SER_NETWORK, INIT_PROTO_VERSION));
Copy link
Contributor

Choose a reason for hiding this comment

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

GetId() is an inline method that returns id already; this change seems pretty pointless?

Copy link
Contributor

Choose a reason for hiding this comment

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

We should remove GetId() entirely. id is a const member so should just be made public.

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-get

We certainly shouldn't be using trivial getters inside CNode methods. They can access member variables directly.

continue;
}

//store received bytes per message command
//to prevent a memory DOS, only allow valid commands
mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(result->m_command);
mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.m_command);
if (i == mapRecvBytesPerMsgCmd.end())
i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should change this .find() to .at() as well?

Copy link
Contributor

Choose a reason for hiding this comment

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

std::map::at returns a reference to the value, not an iterator on the map, which is what is required here for the i->second call below. Alternatively:

diff --git a/src/net.cpp b/src/net.cpp
index 9c2a79b809..e6a3d69810 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -670,11 +670,11 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
 
             //store received bytes per message command
             //to prevent a memory DOS, only allow valid commands
-            mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.m_command);
-            if (i == mapRecvBytesPerMsgCmd.end())
-                i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
-            assert(i != mapRecvBytesPerMsgCmd.end());
-            i->second += msg.m_raw_message_size;
+            if (auto i = mapRecvBytesPerMsgCmd.find(msg.m_command); i != mapRecvBytesPerMsgCmd.end()) {
+                i->second += msg.m_raw_message_size;
+            } else {
+                mapRecvBytesPerMsgCmd.at(NET_MESSAGE_COMMAND_OTHER) += msg.m_raw_message_size;
+            }

@ryanofsky
Copy link
Contributor

I'm not seeing what the benefit of dropping the optional is though, it just changes:

The benefit of dropping optional is that the calling code can reliably use msg.m_raw_message_size, instead of sometimes using m_raw_message_size and sometimes having to look in out_err_raw_size depending on the code path. It is easy to imagine a future change changing the logic a little and causing the wrong size to be read from the wrong location. Getting rid of optional also would have reduced the size of #19107 diff, which was the original reason for the suggestion, but that ship already sailed.

I'm not sure having "this function might throw, but we're sure it never will" is better than "this function might deref end() but we're sure it never will" is better.

I won't die on this hill but I do think an error is better than undefined behavior

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

Code review ACK 78fb468. Only changes since last review are resetting output parameter and tweaking log messages

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 7, 2021

🐙 This pull request conflicts with the target branch and needs rebase.

Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft".

@jnewbery
Copy link
Contributor

jnewbery commented Feb 4, 2021

Code review ACK 78fb468

Needs rebase

@jnewbery
Copy link
Contributor

jnewbery commented Feb 4, 2021

Suggest you remove "For this part, I think this is a definite improvement, but I'm not sure it's the best solution. Open to suggestions." from the first commit log. The commit messages should be used to explain the code changes, and github should be used for review/meta-commentary.

@fanquake
Copy link
Member

Closing this as up for grabs.

maflcko pushed a commit to bitcoin-core/gui that referenced this pull request Nov 2, 2021
…sportDeserializer::GetMessage()

f3e451b [net] Replace GetID() with id in TransportDeserializer constructor (Troy Giorshev)
8c96008 [net] Don't return an optional from TransportDeserializer::GetMessage() (Troy Giorshev)

Pull request description:

  Also, access mapRecvBytesPerMsgCmd with `at()` not `find()`. This
  throws an error if COMMAND_OTHER doesn't exist, which should never
  happen. `find()` instead just accessed the last element, which could make
  debugging more difficult.

  Resolves review comments from PR19107:

  - bitcoin/bitcoin#19107 (comment)
  - bitcoin/bitcoin#19107 (comment)

ACKs for top commit:
  theStack:
    Code-review ACK f3e451b
  ryanofsky:
    Code review ACK f3e451b. Changes since last review in bitcoin/bitcoin#20364 (review) were simplifying by dropping the third commit, rebasing, and cleaning up some style & comments in the first commit.

Tree-SHA512: 37de4b25646116e45eba50206e82ed215b0d9942d4847a172c104da4ed76ea4cee29a6fb119f3c34106a9b384263c576cb8671d452965a468f358d4a3fa3c003
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants