Skip to content

Conversation

@vasild
Copy link
Contributor

@vasild vasild commented May 1, 2025

The only case of a recursive lock was a nested ForNode() call to trim
the size of lNodesAnnouncingHeaderAndIDs to <= 3. This need not be
nested, so take it out.

Before:

fornode(newnode)
    if (size >= 3)
        fornode(front) handle removal of front
        pop front
    push back newnode

After:

fornode(newnode)
    push back newnode
if (size > 3)
    fornode(front) handle removal of front
    pop front

lNodesAnnouncingHeaderAndIDs is protected by cs_main which is locked
during the entire operation.

Partially resolves: #19303


This PR included #32326 (first 3 commits in this PR). That PR was merged first, so the size of this was reduced.

@DrahtBot
Copy link
Contributor

DrahtBot commented May 1, 2025

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

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32394.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK Crypt-iQ, hodlinator
Concept ACK hebasto
Approach ACK w0xlt

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #32278 (doc: better document NetEventsInterface and the deletion of "CNode"s by vasild)
  • #29415 (Broadcast own transactions only via short-lived Tor or I2P connections by vasild)
  • #28463 (p2p: Increase inbound capacity for block-relay only connections by mzumsande)

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.

Bonobirho99

This comment was marked as spam.

@hebasto
Copy link
Member

hebasto commented May 1, 2025

Partially resolves: #19303

Concept ACK on that.

@vasild
Copy link
Contributor Author

vasild commented May 21, 2025

98bba932bf...22d4c57a99: rebase due to conflicts

@vasild
Copy link
Contributor Author

vasild commented Sep 29, 2025

22d4c57a99...9a49877f26: rebase due to conflicts

@hebasto
Copy link
Member

hebasto commented Oct 2, 2025

Time to rebase once more?

@vasild
Copy link
Contributor Author

vasild commented Oct 7, 2025

aaa75c1a41...492be23a18: rebase due to conflicts

Copy link
Contributor

@hodlinator hodlinator left a comment

Choose a reason for hiding this comment

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

Concept ACK 492be23a1873d7165e6cc75d1282f4feb63f87b9

@vasild
Copy link
Contributor Author

vasild commented Oct 15, 2025

492be23a18...4aad3714d6: split in two commits: #32394 (comment)

Copy link
Contributor

@hodlinator hodlinator left a comment

Choose a reason for hiding this comment

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

Reviewed 4aad3714d66cc80c08cb1c827fb49fba7dcf8d50

All annotations make sense, but left Q regarding 1-2 potentially missing ones.

@vasild
Copy link
Contributor Author

vasild commented Oct 16, 2025

4aad3714d6...4b3a2c2360: do #32394 (comment)

Copy link
Contributor

@hodlinator hodlinator left a comment

Choose a reason for hiding this comment

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

ACK 4b3a2c23608e709a63b9d5bd69c3eb16cf08e462

Manually went through all functions using CConnman::m_nodes_mutex and only remaining issue I could find is now fixed (https://github.com/bitcoin/bitcoin/pull/32394/files#r2433600255).

Also checked out first commit and only cherrypicked mutex type change to re-confirm Clang spews warnings about missing annotations (and no warnings at HEAD of PR).

@w0xlt
Copy link
Contributor

w0xlt commented Nov 4, 2025

Approach ACK

@vasild
Copy link
Contributor Author

vasild commented Nov 5, 2025

4b3a2c2360...1a9274f391: rebase due to conflicts

Copy link
Contributor

@hodlinator hodlinator left a comment

Choose a reason for hiding this comment

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

re-ACK 1a9274f391df0465c17b6b6664988af70910e39b

Changes since previous review (#32394 (review)):

  • Resolves conflict with #32983.

Copy link
Contributor

@Crypt-iQ Crypt-iQ left a comment

Choose a reason for hiding this comment

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

crACK 1a9274f391df0465c17b6b6664988af70910e39b

Needs a small rebase since #33956 added 2 annotations.

pnodeStop->m_bip152_highbandwidth_to = false;
return true;
});
lNodesAnnouncingHeaderAndIDs.pop_front();
Copy link
Contributor

@Crypt-iQ Crypt-iQ Dec 5, 2025

Choose a reason for hiding this comment

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

I was initially concerned that maybe lNodesAnnouncingHeaderAndIDs.front() could have been removed from in between releasing the lock and acquiring the lock again. It seems fine since if we do not find lNodesAnnouncingHeaderAndIDs.front(), we don't need to set m_bip152_highbandwidth_to false and we still remove it from the list. There was some previous discussion about the locking here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed from in between releasing the lock and acquiring the lock again

How? lNodesAnnouncingHeaderAndIDs is protected by cs_main which is held in the entire PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs().

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I was a little unclear. I meant that the CNode* that lNodesAnnouncingHeaderAndIDs.front() refers to might have been removed from in m_nodes if we're not holding m_nodes_mutex the entire time. Though I did not write a test to check if this is actually possible, so I might be wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that seems to be fine - if the last m_connman.ForNode(...front()) does nothing (the one at the end, just before pop_front()).

The only recursive usage of `CConnman::m_nodes_mutex` is from
`PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs()` which uses
nested calls to `CConnman::ForNode()` to trim the size of
`lNodesAnnouncingHeaderAndIDs` to `<= 3`. This need not be nested, so
take it out.

Before:
```
fornode(newnode)
    if (size >= 3)
        fornode(front) handle removal of front
        pop front
    push back newnode
```

After:
```
fornode(newnode)
    push back newnode
if (size > 3)
    fornode(front) handle removal of front
    pop front
```

`lNodesAnnouncingHeaderAndIDs` is protected by `cs_main` which is locked
during the entire operation.
This change includes `s/RecursiveMutex/Mutex/` and a pile of
annotations to keep the compiler happy after the type change.

Partially resolves: bitcoin#19303
@vasild
Copy link
Contributor Author

vasild commented Dec 9, 2025

1a9274f391...a6ccd6fdbf: rebase due to conflicts

@Crypt-iQ
Copy link
Contributor

Crypt-iQ commented Dec 9, 2025

re-ACK a6ccd6f

@DrahtBot DrahtBot requested a review from hodlinator December 9, 2025 16:34
Copy link
Contributor

@hodlinator hodlinator left a comment

Choose a reason for hiding this comment

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

re-ACK a6ccd6f

Rebase to fix conflict with #33956

@DrahtBot
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace all of the RecursiveMutex instances with the Mutex ones

8 participants