Skip to content

Conversation

@practicalswift
Copy link
Contributor

@practicalswift practicalswift commented Nov 14, 2017

Fix missing locking in CTxMemPool::check(const CCoinsViewCache *pcoins):

  • reading variable mapTx requires holding mutex cs
  • reading variable mapNextTx requires holding mutex cs
  • reading variable nCheckFrequency requires holding mutex cs

Fix missing locking in CTxMemPool::setSanityCheck(double dFrequency):

  • writing variable nCheckFrequency requires holding mutex cs

@practicalswift practicalswift changed the title Fix missing locking in CTxMemPool::check(const CCoinsViewCache *pcoins) mempool: Fix missing locking in CTxMemPool::check(const CCoinsViewCache *pcoins) Nov 14, 2017
@promag
Copy link
Contributor

promag commented Nov 15, 2017

ACK 2abe610.

Unrelated, but should read nCheckFrequency with the lock too?

@practicalswift
Copy link
Contributor Author

practicalswift commented Nov 15, 2017

@promag Yes, nCheckFrequency should probably be guarded by the mutex cs too. Good catch!

I'll ping in @MarcoFalke and @TheBlueMatt for a comment. What do you say? :-)

$ git blame src/txmempool.h | grep nCheckFrequency
fada0c42 (MarcoFalke               2016-04-03 11:49:36 +0200 415)     uint32_t nCheckFrequency; //!< Value n means that n times in 2^32 we check.
53a6590f (Matt Corallo             2017-09-11 15:43:49 -0400 510)     void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); }
$ git grep -E '(nCheckFrequency|setSanityCheck)'
src/init.cpp:        mempool.setSanityCheck(1.0 / ratio);
src/qt/test/rpcnestedtests.cpp:    //mempool.setSanityCheck(1.0);
src/test/test_bitcoin.cpp:        mempool.setSanityCheck(1.0);
src/txmempool.cpp:    nCheckFrequency = 0;
src/txmempool.cpp:                if (nCheckFrequency != 0) assert(!coin.IsSpent());
src/txmempool.cpp:    if (nCheckFrequency == 0)
src/txmempool.cpp:    if (GetRand(std::numeric_limits<uint32_t>::max()) >= nCheckFrequency)
src/txmempool.h:    uint32_t nCheckFrequency; //!< Value n means that n times in 2^32 we check.
src/txmempool.h:    void setSanityCheck(double dFrequency = 1.0) { nCheckFrequency = static_cast<uint32_t>(dFrequency * 4294967295.0); }

@promag
Copy link
Contributor

promag commented Nov 15, 2017

Actually nCheckFrequency doesn't change, only set in

src/init.cpp:        mempool.setSanityCheck(1.0 / ratio);

@TheBlueMatt
Copy link
Contributor

Technically there is no issue here - mempool (should only be) modified with cs_main and mempool.check is only called with cs_main. Indeed, probably just move the lock to the top of the function. Unless you want to go to the trouble of making nCheckFrequency a const, best to fix it for the static analysis just like the rest.

@practicalswift practicalswift changed the title mempool: Fix missing locking in CTxMemPool::check(const CCoinsViewCache *pcoins) mempool: Fix missing locking in CTxMemPool::check(…) and CTxMemPool::setSanityCheck(…) Nov 16, 2017
@practicalswift
Copy link
Contributor Author

practicalswift commented Nov 16, 2017

@TheBlueMatt @promag Thanks for reviewing! An updated version has now been pushed taking into account the formal locking requirements of nCheckFrequency too. Please re-review :-)

@practicalswift
Copy link
Contributor Author

Added a commit with the Clang thread safety analysis annotations to facilitate reviewing. @promag, would you mind re-reviewing? :-)

@practicalswift
Copy link
Contributor Author

Updated with annotations moved over to the header files.

The EXCLUSIVE_LOCKS_REQUIRED(mempool.cs) annotations for BlockAssembler::SkipMapTxEntry and BlockAssembler::addPackageTxs should be placed in miner.h rather than miner.cpp, but the existence of mempool (and hence mempool.cs) is not currently not known in miner.h. Would extern CTxMemPool mempool; be acceptable in miner.h?

@TheBlueMatt
Copy link
Contributor

As mentioned before, please do not place EXCLUSIVE_LOCKS_REQUIRED annotations on class member function declarations instead of their definitions. Placing them on declarations makes the annotations incredibly brittle and, thus, largely useless. Better to leave them off than to add them in a place where the order of functions in a file matters.

@practicalswift
Copy link
Contributor Author

@TheBlueMatt Sorry, I had missed moving the annotations for SkipMapTxEntry, addPackageTxs, UpdateChildrenForRemoval and CalculateDescendants. Now fixed! Please re-review :-)

@sipa
Copy link
Member

sipa commented Mar 17, 2018

utACK 661db1d63afcea4016ccb7f97fda6cde7f719826

@practicalswift
Copy link
Contributor Author

Rebased!

* reading variable 'mapTx' requires holding mutex 'cs'
* reading variable 'mapNextTx' requires holding mutex 'cs'
* reading variable 'nCheckFrequency' requires holding mutex 'cs'
* writing variable 'nCheckFrequency' requires holding mutex 'cs'
@practicalswift
Copy link
Contributor Author

@promag @sipa Would you mind re-reviewing?

@MarcoFalke Would you mind reviewing? :-)

@maflcko
Copy link
Member

maflcko commented May 14, 2018

utACK 47782b4

@maflcko maflcko merged commit 47782b4 into bitcoin:master May 14, 2018
maflcko pushed a commit that referenced this pull request May 14, 2018
…d CTxMemPool::setSanityCheck(…)

47782b4 Add Clang thread safety analysis annotations (practicalswift)
0e2dfa8 Fix missing locking in CTxMemPool::setSanityCheck(double dFrequency) (practicalswift)
6bc5b71 Fix missing locking in CTxMemPool::check(const CCoinsViewCache *pcoins) (practicalswift)

Pull request description:

  Fix missing locking in `CTxMemPool::check(const CCoinsViewCache *pcoins)`:
  * reading variable `mapTx` requires holding mutex `cs`
  * reading variable `mapNextTx` requires holding mutex `cs`
  * reading variable `nCheckFrequency` requires holding mutex `cs`

  Fix missing locking in `CTxMemPool::setSanityCheck(double dFrequency)`:
  * writing variable `nCheckFrequency` requires holding mutex `cs`

Tree-SHA512: ce7c365ac89225223fb06e6f469451b121acaa499f35b21ad8a6d2a266c91194639b3703c5428871be033d4f5f7be790cc297bd8c25b2e0c59345ef09c3693d0
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 1, 2020
…k(…) and CTxMemPool::setSanityCheck(…)

47782b4 Add Clang thread safety analysis annotations (practicalswift)
0e2dfa8 Fix missing locking in CTxMemPool::setSanityCheck(double dFrequency) (practicalswift)
6bc5b71 Fix missing locking in CTxMemPool::check(const CCoinsViewCache *pcoins) (practicalswift)

Pull request description:

  Fix missing locking in `CTxMemPool::check(const CCoinsViewCache *pcoins)`:
  * reading variable `mapTx` requires holding mutex `cs`
  * reading variable `mapNextTx` requires holding mutex `cs`
  * reading variable `nCheckFrequency` requires holding mutex `cs`

  Fix missing locking in `CTxMemPool::setSanityCheck(double dFrequency)`:
  * writing variable `nCheckFrequency` requires holding mutex `cs`

Tree-SHA512: ce7c365ac89225223fb06e6f469451b121acaa499f35b21ad8a6d2a266c91194639b3703c5428871be033d4f5f7be790cc297bd8c25b2e0c59345ef09c3693d0
@practicalswift practicalswift deleted the CTxMemPool-check branch April 10, 2021 19:34
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request Apr 26, 2021
* reading variable 'mapTx' requires holding mutex 'cs'
* reading variable 'mapNextTx' requires holding mutex 'cs'
* reading variable 'nCheckFrequency' requires holding mutex 'cs'

zcash: cherry picked from commit 6bc5b71
zcash: bitcoin/bitcoin#11689
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request Apr 26, 2021
* writing variable 'nCheckFrequency' requires holding mutex 'cs'

zcash: cherry picked from commit 0e2dfa8
zcash: bitcoin/bitcoin#11689
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request Apr 26, 2021
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request May 27, 2021
* reading variable 'mapTx' requires holding mutex 'cs'
* reading variable 'mapNextTx' requires holding mutex 'cs'
* reading variable 'nCheckFrequency' requires holding mutex 'cs'

zcash: cherry picked from commit 6bc5b71
zcash: bitcoin/bitcoin#11689
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request May 27, 2021
* writing variable 'nCheckFrequency' requires holding mutex 'cs'

zcash: cherry picked from commit 0e2dfa8
zcash: bitcoin/bitcoin#11689
LarryRuane pushed a commit to LarryRuane/zcash that referenced this pull request May 27, 2021
gades pushed a commit to cosanta/cosanta-core that referenced this pull request Mar 11, 2022
…k(…) and CTxMemPool::setSanityCheck(…)

47782b4 Add Clang thread safety analysis annotations (practicalswift)
0e2dfa8 Fix missing locking in CTxMemPool::setSanityCheck(double dFrequency) (practicalswift)
6bc5b71 Fix missing locking in CTxMemPool::check(const CCoinsViewCache *pcoins) (practicalswift)

Pull request description:

  Fix missing locking in `CTxMemPool::check(const CCoinsViewCache *pcoins)`:
  * reading variable `mapTx` requires holding mutex `cs`
  * reading variable `mapNextTx` requires holding mutex `cs`
  * reading variable `nCheckFrequency` requires holding mutex `cs`

  Fix missing locking in `CTxMemPool::setSanityCheck(double dFrequency)`:
  * writing variable `nCheckFrequency` requires holding mutex `cs`

Tree-SHA512: ce7c365ac89225223fb06e6f469451b121acaa499f35b21ad8a6d2a266c91194639b3703c5428871be033d4f5f7be790cc297bd8c25b2e0c59345ef09c3693d0
@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.

6 participants