Fix deadlocks in setaccount, sendfrom RPC calls

SendMoney*() now requires caller to acquire cs_main.
GetAccountAddress() now requires caller to acquire cs_main, cs_mapWallet.

Ordering is intended to match these two callchains[1]:

1. CRITICAL_BLOCK(cs_main)
    ProcessMessage(pfrom, strCommand, vMsg)
        AddToWalletIfMine()
              AddToWallet(wtx)
                  CRITICAL_BLOCK(cs_mapWallet)

2. CRITICAL_BLOCK(cs_main)
    ProcessMessage(pfrom, strCommand, vMsg)
        AddToWalletIfMine()
              AddToWallet(wtx)
                  CRITICAL_BLOCK(cs_mapWallet)
                      walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "")
                          CRITICAL_BLOCK(cs_mapAddressBook)

Spotted by ArtForz.  Additional deadlock fixes by Gavin.

[1] http://www.bitcoin.org/smf/index.php?topic=4904.msg71897#msg71897
This commit is contained in:
Jeff Garzik
2011-04-04 22:24:35 -04:00
committed by Jeff Garzik
parent 454bc86479
commit f5f1878ba1
4 changed files with 86 additions and 69 deletions

2
db.cpp
View File

@@ -668,8 +668,8 @@ bool CWalletDB::LoadWallet()
#endif
//// todo: shouldn't we catch exceptions and try to recover and continue?
CRITICAL_BLOCK(cs_mapKeys)
CRITICAL_BLOCK(cs_mapWallet)
CRITICAL_BLOCK(cs_mapKeys)
{
// Get cursor
Dbc* pcursor = GetCursor();