aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2017-08-24 14:12:21 -0400
committerRussell Yanofsky <russ@yanofsky.org>2017-08-24 14:12:21 -0400
commitde9a1db2ed14e0c75ffd82dc031f7ad30c56d195 (patch)
treea1da4e7317799469c078b5923a4aba3ae7ffc0aa /src/wallet/wallet.cpp
parent41496e20f36987d27bed6cb83c06a6a978bfdf42 (diff)
downloadbitcoin-de9a1db2ed14e0c75ffd82dc031f7ad30c56d195.tar.xz
Acquire cs_main lock before cs_wallet during wallet initialization
CWallet::MarkConflicted may acquire the cs_main lock after CWalletDB::LoadWallet acquires the cs_wallet lock during wallet initialization. (CWalletDB::LoadWallet calls ReadKeyValue which calls CWallet::LoadToWallet which calls CWallet::MarkConflicted). This is the opposite order that cs_main and cs_wallet locks are acquired in the rest of the code, and so leads to POTENTIAL DEADLOCK DETECTED errors if bitcoin is built with -DDEBUG_LOCKORDER. This commit changes CWallet::LoadWallet (which calls CWalletDB::LoadWallet) to acquire both locks in the standard order. It also fixes some tests that were acquiring wallet and main locks out of order and failed with the new locking in CWallet::LoadWallet. Error was reported by Luke Dashjr <luke-jr@utopios.org> in https://botbot.me/freenode/bitcoin-core-dev/msg/90244330/
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 291bcc7a20..ecf473a96e 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -3107,13 +3107,14 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, const CCoinControl& coin_c
DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
{
+ LOCK2(cs_main, cs_wallet);
+
fFirstRunRet = false;
DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this);
if (nLoadWalletRet == DB_NEED_REWRITE)
{
if (dbw->Rewrite("\x04pool"))
{
- LOCK(cs_wallet);
setInternalKeyPool.clear();
setExternalKeyPool.clear();
m_pool_key_to_index.clear();