diff options
author | Jeff Garzik <jeff@garzik.org> | 2011-04-04 22:24:35 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2011-04-04 22:24:35 -0400 |
commit | f5f1878ba104a5d6a32eeb20b341326dca6086a5 (patch) | |
tree | 39284fb8f9a1e82e7f66c49de833c2373dc54b8e /main.cpp | |
parent | 454bc86479a387893604cd662aae994d37699672 (diff) |
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
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 36 |
1 files changed, 18 insertions, 18 deletions
@@ -4046,35 +4046,35 @@ bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) +// requires cs_main lock string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { - CRITICAL_BLOCK(cs_main) + CReserveKey reservekey; + int64 nFeeRequired; + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) { - CReserveKey reservekey; - int64 nFeeRequired; - if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) - { - string strError; - if (nValue + nFeeRequired > GetBalance()) - strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str()); - else - strError = _("Error: Transaction creation failed "); - printf("SendMoney() : %s", strError.c_str()); - return strError; - } + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str()); + else + strError = _("Error: Transaction creation failed "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } - if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) - return "ABORTED"; + if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) + return "ABORTED"; + + if (!CommitTransaction(wtxNew, reservekey)) + return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); - if (!CommitTransaction(wtxNew, reservekey)) - return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); - } MainFrameRepaint(); return ""; } +// requires cs_main lock string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { // Check amount |