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
    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:

    • #30111 (locks: introduce mutex for tx download, flush rejection filters on UpdatedBlockTip by glozow)
    • #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:226 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. 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.
    51a2a287ce
  13. sr-gi force-pushed on Jun 20, 2024
  14. 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
  15. DrahtBot removed the label Needs rebase on Jun 20, 2024

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-06-29 07:13 UTC

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