refactor: move m_is_inbound out of CNodeState #30233

pull sr-gi wants to merge 1 commits into bitcoin:master from sr-gi:202406-refactor-inbound changing 1 files +18 −24
  1. sr-gi commented at 5:01 pm on June 5, 2024: member

    m_is_inbound cannot be changed throughout the life of a Peer. However, we are currently storing it in CNodeState, which requires locking cs_main in order to access it. This can be moved to the outside scope and only require m_peer_mutex.

    This is a refactor in preparation for Erlay reworks.

  2. DrahtBot commented at 5:01 pm on June 5, 2024: contributor

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

    Code Coverage

    For detailed information about the code coverage, see the test coverage report.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK marcofleon, naumenkogs, maflcko, achow101
    Concept ACK tdb3

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #27052 (test: rpc: add last block announcement time to getpeerinfo result by LarryRuane)

    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.

  3. DrahtBot added the label Refactoring on Jun 5, 2024
  4. sr-gi force-pushed on Jun 5, 2024
  5. DrahtBot added the label CI failed on Jun 5, 2024
  6. DrahtBot removed the label CI failed on Jun 5, 2024
  7. tdb3 commented at 3:51 am on June 6, 2024: contributor

    Concept ACK. Mind sharing how you see this fitting in with Erlay work?

    Will review in more depth soon.

  8. in src/net_processing.cpp:1940 in a0e4333d6b outdated
    1943             // Exempt HB compact block peers. Manual connections are always protected from discouragement.
    1944-            if (!via_compact_block && !node_state->m_is_inbound) {
    1945-                if (peer) Misbehaving(*peer, 100, message);
    1946+            if (peer && !via_compact_block && !peer->m_is_inbound) {
    1947+                Misbehaving(*peer, 100, message);
    1948                 return true;
    


    maflcko commented at 9:48 am on June 6, 2024:
    Can you explain why this change in behavior is correct? Previously, if the peer was missing, it would return true. Now, it would return false.

    sr-gi commented at 2:11 pm on June 6, 2024:

    You’re right. This was an oversimplification. However, CNodeState and Peer should be tightly coupled, shouldn’t they? Both are wiped in PeerManagerImpl::FinalizeNode (synchronously I assume), so I think there shouldn’t have been a way to trigger that true when peer was a nullptr.

    Zooming out a little bit, MaybePunishNodeForBlock return value is never used in the codebase (AFAICT at least), plus the docs also seem to be confusing when true needs to be returned:

    https://github.com/bitcoin/bitcoin/blob/1040a1fc807ed984020eeaa6e90b5bf070b61b05/src/net_processing.cpp#L568


    maflcko commented at 2:58 pm on June 6, 2024:
    If the return value is wrong or unused, it could make sense to remove it? Also, it could make sense to update the pattern if (peer && ... in the other cases as well for consistency, if this is correct.

    sr-gi commented at 6:55 pm on June 6, 2024:

    #29575 (comment)

    Will rebase on top of that


    sr-gi commented at 6:47 pm on June 20, 2024:
    Rebased
  9. sr-gi commented at 2:28 pm on June 6, 2024: member

    Concept ACK. Mind sharing how you see this fitting in with Erlay work?

    Will review in more depth soon.

    Sure. For Erlay purposes, some transactions need to be sent via fanout even to Erlay-enabled peers. In order to know to how many peers to send this via fanout, we need to count the amount of tx-relaying peers that we have, both inbound and outbound.

    This is done, in the current patch, by going over all peers when constructing their corresponding INV message and deciding whether to add the transaction or not (this requires accesing the CNodeState, which involves locking cs_main). In the new revision, this would be done in PeerManagerImpl::RelayTransaction, and two sets will be kept, per peer, one for fanout and one for reconciliation.

    TL;DR; checking if a peer is inbound from the PeerManager perspective should not require locking cs_main

  10. in src/net_processing.cpp:228 in a0e4333d6b outdated
    222@@ -223,6 +223,9 @@ struct Peer {
    223     /** Services this peer offered to us. */
    224     std::atomic<ServiceFlags> m_their_services{NODE_NONE};
    225 
    226+    //! Whether this peer is an inbound connection
    227+    const bool m_is_inbound;
    


    mzumsande commented at 3:13 pm on June 10, 2024:
    The primary source of that information is CNode::m_conn_type. Is it necessary to have a partial copy of that in Peer? If not, an alternative approach might be to use that, as is done for various other spots in net_processing that call IsInboundConn(). We might also need helper functions similar to GetExtraBlockRelayCount but for inbounds. I haven’t tried it or looked into it in depth, but just wanted to bring up where you’ve considered that option.

    sr-gi commented at 5:08 pm on June 10, 2024:

    We do, at least to my understanding, given some PeerMan methods that are not called with any CNode reference need to check whether the peer that sent us the data they are processing is inbound or outbound.

    A good example is PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs, which is called from PeerManagerImpl::BlockChecked and is passed a NodeId grabbed from mapBlockSource


    mzumsande commented at 5:46 pm on June 10, 2024:
    Yes, but we could attempt to retrieve the CNode by NodeId from m_nodes, as the current code does it for Peer from m_peer_map. I think the lookup would be O(N) for iterating through the vector m_nodes instead of O(log N) for the std::map, so maybe that is the reason for the redundancy?

    sr-gi commented at 6:22 pm on June 10, 2024:
    Yeah, that’d make sense. I don’t think increasing the lookup complexity for this, even if we are talking about a vector of hundreds of nodes at most, is worth not keeping a boolean in Peer
  11. DrahtBot added the label Needs rebase on Jun 20, 2024
  12. sr-gi force-pushed on Jun 20, 2024
  13. sr-gi commented at 6:48 pm on June 20, 2024: member
    Rebased on top of master to cover #30233 (review), which was addressed by #29575
  14. DrahtBot removed the label Needs rebase on Jun 20, 2024
  15. DrahtBot added the label Needs rebase on Jul 24, 2024
  16. sr-gi force-pushed on Jul 24, 2024
  17. sr-gi commented at 3:03 pm on July 24, 2024: member
    Rebased to deal with merge conflicts
  18. DrahtBot removed the label Needs rebase on Jul 24, 2024
  19. naumenkogs approved
  20. naumenkogs commented at 7:06 am on September 12, 2024: member
    ACK 129f73cc6e2ed4147f57c3d1dfe2841b8a46e9fe
  21. DrahtBot requested review from tdb3 on Sep 12, 2024
  22. in src/net_processing.cpp:1376 in 129f73cc6e outdated
    1374-        if (state != nullptr && !state->m_is_inbound) ++num_outbound_hb_peers;
    1375+        PeerRef peer{GetPeerRef(*it)};
    1376+        if (peer && !peer->m_is_inbound) ++num_outbound_hb_peers;
    1377     }
    1378-    if (nodestate->m_is_inbound) {
    1379+    PeerRef peer{GetPeerRef(nodeid)};
    


    maflcko commented at 11:12 am on September 12, 2024:
    nit: It would be nice to keep the PeerRef construction always at the same place as the previous CNodeState construction. This makes this review easier and also follow-up changes that move more state into Peer. Otherwise, this will have to be moved up again in the future anyway.

    sr-gi commented at 3:21 pm on September 12, 2024:
    I moved it up in 07f4ceb and renamed the internal peer to peer_ref to avoid a conflict
  23. in src/net_processing.cpp:1679 in 129f73cc6e outdated
    1675@@ -1676,7 +1676,7 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service
    1676     NodeId nodeid = node.GetId();
    1677     {
    1678         LOCK(cs_main); // For m_node_states
    1679-        m_node_states.emplace_hint(m_node_states.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(node.IsInboundConn()));
    1680+        m_node_states.emplace_hint(m_node_states.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple());
    


    maflcko commented at 12:01 pm on September 12, 2024:

    nit: Now that C++17 is available, you can just use the equivalent try_emplace (5) from https://en.cppreference.com/w/cpp/container/map/try_emplace

     0diff --git a/src/net_processing.cpp b/src/net_processing.cpp
     1index 23f5265ccd..2b9147b590 100644
     2--- a/src/net_processing.cpp
     3+++ b/src/net_processing.cpp
     4@@ -1720,7 +1720,7 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service
     5     NodeId nodeid = node.GetId();
     6     {
     7         LOCK(cs_main); // For m_node_states
     8-        m_node_states.emplace_hint(m_node_states.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple());
     9+        m_node_states.try_emplace(m_node_states.end(), nodeid);
    10     }
    11     {
    12         LOCK(m_tx_download_mutex);
    

    sr-gi commented at 3:21 pm on September 12, 2024:
    Addressed in 07f4ceb
  24. maflcko approved
  25. maflcko commented at 12:02 pm on September 12, 2024: member

    review ACK 129f73cc6e2ed4147f57c3d1dfe2841b8a46e9fe 💼

    Signature:

    0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    2trusted comment: review ACK 129f73cc6e2ed4147f57c3d1dfe2841b8a46e9fe 💼
    33fNrvhGgwV/rlyCL2reeVteCqpRAZlpmoMI8JHAIWCqKWygCm+5M3v3l0MFsTZYLbjBCz0smaZA1gVcmFLWNCA==
    
  26. refactor: move m_is_inbound out of CNodeState
    `m_is_inbound` cannot be changed throughout the life of a `Peer`. However, we
    are currently storing it in `CNodeState`, which requires locking `cs_main` in
    order to access it. This can be moved to the outside scope and only require
    `m_peer_mutex`.
    
    This is a refactor in preparation for Erlay reworks.
    07f4cebe57
  27. sr-gi force-pushed on Sep 12, 2024
  28. sr-gi commented at 3:22 pm on September 12, 2024: member
    Amended to cover @maflcko nits and rebased to include cmake
  29. marcofleon approved
  30. marcofleon commented at 8:57 pm on September 12, 2024: contributor

    ACK 07f4cebe5780f1039541d989e64b70eccc5b4eb5

    I took a look at c308e3200d6968be553ed031d09b4bccb46b504b and 2e0b6742b82e60ea685afd25f2d19b8b558678ce in #30116 (assuming those commits are mostly final) to understand a bit better how m_is_inbound will be used for Erlay. Based on that, I’d say the changes in this PR make sense.

  31. DrahtBot requested review from naumenkogs on Sep 12, 2024
  32. DrahtBot requested review from maflcko on Sep 12, 2024
  33. in src/net_processing.cpp:1723 in 07f4cebe57
    1719@@ -1720,7 +1720,7 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service
    1720     NodeId nodeid = node.GetId();
    1721     {
    1722         LOCK(cs_main); // For m_node_states
    1723-        m_node_states.emplace_hint(m_node_states.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(node.IsInboundConn()));
    1724+        m_node_states.try_emplace(m_node_states.end(), nodeid);
    


    naumenkogs commented at 7:46 am on September 13, 2024:
    nit should we assert the result of this code instead of dropping it on the floor?

    sr-gi commented at 3:11 pm on September 13, 2024:
    We were not checking it before, nor are we doing so later when emplacing it in m_peer_map either, so I’d lean towards no for consistency, but I don’t have a strong opinion about it

    jonatack commented at 0:50 am on September 14, 2024:

    FWIW I tried adding an assert here while reviewing this pull and found it unexpectedly difficult. Happy to review if someone does it.

    As a sanity check verified both unit and functional tests appear to fail if this line is changed or omitted.

  34. DrahtBot requested review from naumenkogs on Sep 13, 2024
  35. naumenkogs approved
  36. naumenkogs commented at 7:46 am on September 13, 2024: member
    ACK 07f4cebe5780f1039541d989e64b70eccc5b4eb5
  37. maflcko commented at 3:29 pm on September 13, 2024: member

    ACK 07f4cebe5780f1039541d989e64b70eccc5b4eb5 🗞

    Signature:

    0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    2trusted comment: ACK 07f4cebe5780f1039541d989e64b70eccc5b4eb5 🗞
    3vc3UpVVyQ+RrINm3XUgOY7h0eDX56YxXxoCxlgTWq0GWjKWtW1knsO2+FfWuSpoj41wZ7jBq6X9Tfpn3fXFCCw==
    
  38. achow101 commented at 6:58 pm on September 13, 2024: member
    ACK 07f4cebe5780f1039541d989e64b70eccc5b4eb5
  39. achow101 merged this on Sep 13, 2024
  40. achow101 closed this on Sep 13, 2024

  41. jonatack commented at 0:46 am on September 14, 2024: member
    Post-merge ACK 07f4cebe5780f1039541d989e64b70eccc5b4eb5

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-26 15:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me