Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

wallet: Add missing cs_wallet/cs_KeyStore locks to wallet #11634

Open
wants to merge 2 commits into
from

Conversation

Projects
None yet
3 participants
Contributor

practicalswift commented Nov 8, 2017

Add missing cs_wallet/cs_KeyStore locks to wallet:

  1. Reading the variables mapTxSpends and mapWallet (via the IsSpent(...) call) require holding the mutex cs_wallet.
  2. Reading the variables mapKeys and mapCryptedKeys require holding the mutex cs_KeyStore.
  3. Reading the variable nTimeFirstKey requires holding the mutex cs_wallet.
  4. Reading the variable mapWallet requires holding the mutex cs_wallet.

@fanquake fanquake added the Wallet label Nov 8, 2017

src/wallet/wallet.cpp
@@ -3953,6 +3960,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
for (const CWalletTx& wtxOld : vWtx)
{
uint256 hash = wtxOld.GetHash();
+ LOCK(walletInstance->cs_wallet);
@promag

promag Nov 8, 2017

Contributor

Either:

  • lock once before the loop;
  • loop first with the lock to mapWallet.find(hash) for all vWtx and then loop again without the lock to walletdb.WriteTx();
  • lock only the mapWallet.find(hash).
Contributor

practicalswift commented Nov 8, 2017

@promag Thanks for reviewing! Feedback addressed. Looks good? :-)

src/wallet/wallet.cpp
@@ -3950,6 +3957,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
{
CWalletDB walletdb(*walletInstance->dbw);
+ LOCK(walletInstance->cs_wallet);
@promag

promag Nov 8, 2017

Contributor

This should be before the line above. Anyway, there is no need to lock this wallet since it's a fresh instance, unknown to the remaining system. Unless you are adding the lock because of other asserts and if so please commit them to justify this change?

@practicalswift

practicalswift Nov 8, 2017

Contributor

Now moved before the line above. Without that lock we'll trigger Clang thread safety analysis warnings when #11634 is merged due to:

src/wallet/wallet.h:    std::map<uint256, CWalletTx> mapWallet GUARDED_BY(cs_wallet);

As agreed upon in #11226 (comment) all guard/lock annotations are added in #11634 and all extra locking is submitted as separate PR:s (such as this one).

The annotations are compile-time only whereas the locks change run-time behaviour (and thus needs extra scrunity!).

@promag

promag Nov 8, 2017

Contributor

As agreed upon in #11226 (comment) all guard/lock annotations are added in #11634 and all extra locking is submitted as separate PR:s (such as this one)

I think you swapped the PR numbers?

@practicalswift

practicalswift Nov 8, 2017

Contributor

Yes, you're right - the annotations are added in #11226 :-)

Contributor

promag commented Nov 8, 2017

utACK 007fcbf.

luke-jr added a commit to bitcoinknots/bitcoin that referenced this pull request Nov 11, 2017

wallet: Add missing cs_wallet/cs_KeyStore locks to wallet
* Reading the variables mapTxSpends and mapWallet (via IsSpent(...) call) require holding the mutex cs_wallet.
* Reading the variables mapKeys and mapCryptedKeys require holding the mutex cs_KeyStore.
* Reading the variable nTimeFirstKey requires holding the mutex cs_wallet.
* Reading the variable mapWallet requires holding the mutex cs_wallet.

Github-Pull: #11634
Rebased-From: 007fcbf

practicalswift added some commits Nov 8, 2017

wallet: Add missing cs_wallet/cs_KeyStore locks to wallet
* Reading the variables mapTxSpends and mapWallet (via IsSpent(...) call) require holding the mutex cs_wallet.
* Reading the variables mapKeys and mapCryptedKeys require holding the mutex cs_KeyStore.
* Reading the variable nTimeFirstKey requires holding the mutex cs_wallet.
* Reading the variable mapWallet requires holding the mutex cs_wallet.
wallet: Add missing locks in wallet.{cpp,h}
* calling function 'IsSpent' requires holding mutex 'pwallet->cs_wallet' exclusively
* writing variable 'nWalletVersion', 'nWalletMaxVersion', 'nOrderPosNext' and 'nTimeFirstKey' require holding mutex 'cs_wallet'
Contributor

practicalswift commented Nov 21, 2017

Added another commit with two more missing locks:

  • calling function IsSpent requires holding mutex pwallet->cs_wallet exclusively
  • writing variable nWalletVersion, nWalletMaxVersion, nOrderPosNext and nTimeFirstKey require holding mutex cs_wallet
Contributor

practicalswift commented Nov 21, 2017

@promag Would you mind re-reviewing? :-)

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