Skip to content

Conversation

@kazcw
Copy link
Contributor

@kazcw kazcw commented Apr 26, 2016

In several places in main.cpp, synchronized data structures are accessed without cs_main being held.

kazcw added 2 commits April 25, 2016 18:06
ProcessMessage calls State(...) and Misbehaving(...) without holding the
required lock; add LOCK(cs_main) blocks.
ActivateBestChain uses chainActive after releasing the lock; reorder operations
to move all access to synchronized object into existing LOCK(cs_main) block.
@gmaxwell
Copy link
Contributor

hmph. peppering cs_main in the middle of functions sounds like a formula for lock inversion. Perhaps Misbehaving() should get its own lock internally and not depend on cs_main?

@kazcw
Copy link
Contributor Author

kazcw commented Apr 26, 2016

A separate nodestate cs is definitely doable; there's a fair amount of code that would need to hold cs_main and nodestate, but no new locks ever need to be acquired within the scope of a cs_nodestate lock. I'll draft a refactor.

@kazcw kazcw changed the title lock cs_main for State/Misbehaving/chainActive [WIP] lock cs_main for State/Misbehaving/chainActive Apr 26, 2016
@kazcw kazcw changed the title [WIP] lock cs_main for State/Misbehaving/chainActive [WIP] locking for CNodeState/chainActive Apr 26, 2016
@kazcw kazcw changed the title [WIP] locking for CNodeState/chainActive locking for Misbehave() and other cs_main locking fixes Apr 27, 2016
@kazcw
Copy link
Contributor Author

kazcw commented Apr 27, 2016

I created a separate mutex, cs_misbehavior. cs_misbehavior is only locked either directly inside a cs_main lock or along with no other locks, so there shouldn't be any deadlocks (and DEBUG_LOCKORDER isn't complaining). cs_misbehavior is the sole mutex guarding the nMisbehavior and fShouldBan fields; modifications to the mapBlockSource container are guarded by both cs_main and cs_misbehavior so that either lock suffices to perform lookups safely.

LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes) {
if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
Copy link
Member

Choose a reason for hiding this comment

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

You can use pindexNewTip->nHeight instead of creating an extra variable.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can use pindexNewTip->nHeight instead of creating an extra variable.

ping @kazcw

@sipa
Copy link
Member

sipa commented Jun 2, 2016

@kazcw I don't see your cs_misbehaviour, but I think the code here is fine as is. We certainly need a separate lock for node states, but I would delay that until the net refactors are done.

@sipa
Copy link
Member

sipa commented Jun 2, 2016

utACK 719de56

@dcousens
Copy link
Contributor

dcousens commented Jun 2, 2016

utACK 719de56, and I concur that I do not see cs_misbehavior

@laanwj
Copy link
Member

laanwj commented Jun 3, 2016

utACK 719de56
Going to merge this, the nit can be done later.

@laanwj laanwj merged commit 719de56 into bitcoin:master Jun 3, 2016
laanwj added a commit that referenced this pull request Jun 3, 2016
719de56 lock cs_main for chainActive (Kaz Wesley)
efb54ba lock cs_main for State/Misbehaving (Kaz Wesley)
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request Feb 20, 2021
ProcessMessage calls State(...) and Misbehaving(...) without holding the
required lock; add LOCK(cs_main) blocks.

zcash: cherry picked from commit efb54ba
zcash: bitcoin/bitcoin#7942
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request Feb 20, 2021
ActivateBestChain uses chainActive after releasing the lock; reorder operations
to move all access to synchronized object into existing LOCK(cs_main) block.

zcash: cherry picked from commit 719de56
zcash: bitcoin/bitcoin#7942
zkbot added a commit to zcash/zcash that referenced this pull request Apr 1, 2021
Bitcoin 0.13 locking PRs

These are locking changes from upstream (bitcoin core) release 0.13, oldest to newest (when they were merged to the master branch).
- bitcoin/bitcoin#7846
- bitcoin/bitcoin#7913
- bitcoin/bitcoin#8016
  - second commit only; first commit, test changes, are already done
- bitcoin/bitcoin#7942

This PR does not include:
 - bitcoin/bitcoin#8244 bitcoin/bitcoin@27f8126
   -  zcash requires locking `cs_main` in this instance (`getrawmempool()` calls `mempoolToJSON()`, which calls `chainActive.Height()`).
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants