Merge branch 'master' of https://github.com/bitcoin/bitcoin
authorWladimir J. van der Laan <laanwj@gmail.com>
Fri, 2 Sep 2011 15:35:30 +0000 (17:35 +0200)
committerWladimir J. van der Laan <laanwj@gmail.com>
Fri, 2 Sep 2011 15:35:30 +0000 (17:35 +0200)
Conflicts:
src/main.cpp

1  2 
src/bitcoinrpc.cpp
src/main.cpp
src/script.cpp
src/serialize.h
src/util.cpp
src/util.h
src/wallet.cpp
src/wallet.h

diff --combined src/bitcoinrpc.cpp
@@@ -50,13 -50,13 +50,13 @@@ Object JSONRPCError(int code, const str
  }
  
  
 -void PrintConsole(const char* format, ...)
 +void PrintConsole(const std::string &format, ...)
  {
      char buffer[50000];
      int limit = sizeof(buffer);
      va_list arg_ptr;
      va_start(arg_ptr, format);
 -    int ret = _vsnprintf(buffer, limit, format, arg_ptr);
 +    int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr);
      va_end(arg_ptr);
      if (ret < 0 || ret >= limit)
      {
@@@ -331,71 -331,59 +331,59 @@@ Value getnewaddress(const Array& params
              "If [account] is specified (recommended), it is added to the address book "
              "so payments received with the address will be credited to [account].");
  
-     if (!pwalletMain->IsLocked())
-         pwalletMain->TopUpKeyPool();
-     if (pwalletMain->GetKeyPoolSize() < 1)
-         throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
      // Parse the account first so we don't generate a key if there's an error
      string strAccount;
      if (params.size() > 0)
          strAccount = AccountFromValue(params[0]);
  
+     if (!pwalletMain->IsLocked())
+         pwalletMain->TopUpKeyPool();
      // Generate a new key that is added to wallet
-     CBitcoinAddress address(pwalletMain->GetOrReuseKeyFromPool());
+     std::vector<unsigned char> newKey;
+     if (!pwalletMain->GetKeyFromPool(newKey, false))
+         throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
+     CBitcoinAddress address(newKey);
  
-     // This could be done in the same main CS as GetKeyFromKeyPool.
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
-        pwalletMain->SetAddressBookName(address, strAccount);
+     pwalletMain->SetAddressBookName(address, strAccount);
  
      return address.ToString();
  }
  
  
- // requires cs_main, cs_mapWallet, cs_mapAddressBook locks
  CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
  {
      CWalletDB walletdb(pwalletMain->strWalletFile);
  
      CAccount account;
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
-     {
-         walletdb.ReadAccount(strAccount, account);
+     walletdb.ReadAccount(strAccount, account);
  
-         bool bKeyUsed = false;
+     bool bKeyUsed = false;
  
-         // Check if the current key has been used
-         if (!account.vchPubKey.empty())
+     // Check if the current key has been used
+     if (!account.vchPubKey.empty())
+     {
+         CScript scriptPubKey;
+         scriptPubKey.SetBitcoinAddress(account.vchPubKey);
+         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
+              it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
+              ++it)
          {
-             CScript scriptPubKey;
-             scriptPubKey.SetBitcoinAddress(account.vchPubKey);
-             for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
-                  it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
-                  ++it)
-             {
-                 const CWalletTx& wtx = (*it).second;
-                 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
-                     if (txout.scriptPubKey == scriptPubKey)
-                         bKeyUsed = true;
-             }
+             const CWalletTx& wtx = (*it).second;
+             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+                 if (txout.scriptPubKey == scriptPubKey)
+                     bKeyUsed = true;
          }
+     }
  
-         // Generate a new key
-         if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
-         {
-             if (pwalletMain->GetKeyPoolSize() < 1)
-             {
-                 if (bKeyUsed || bForceNew)
-                     throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first");
-             }
-             else
-             {
-                 account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool();
-                 pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
-                 walletdb.WriteAccount(strAccount, account);
-             }
-         }
+     // Generate a new key
+     if (account.vchPubKey.empty() || bForceNew || bKeyUsed)
+     {
+         if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
+             throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
+         pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
+         walletdb.WriteAccount(strAccount, account);
      }
  
      return CBitcoinAddress(account.vchPubKey);
@@@ -413,12 -401,7 +401,7 @@@ Value getaccountaddress(const Array& pa
  
      Value ret;
  
-     CRITICAL_BLOCK(cs_main)
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
-     {
-         ret = GetAccountAddress(strAccount).ToString();
-     }
+     ret = GetAccountAddress(strAccount).ToString();
  
      return ret;
  }
@@@ -442,20 -425,15 +425,15 @@@ Value setaccount(const Array& params, b
          strAccount = AccountFromValue(params[1]);
  
      // Detect when changing the account of an address that is the 'unused current key' of another account:
-     CRITICAL_BLOCK(cs_main)
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+     if (pwalletMain->mapAddressBook.count(address))
      {
-         if (pwalletMain->mapAddressBook.count(address))
-         {
-             string strOldAccount = pwalletMain->mapAddressBook[address];
-             if (address == GetAccountAddress(strOldAccount))
-                 GetAccountAddress(strOldAccount, true);
-         }
-         pwalletMain->SetAddressBookName(address, strAccount);
+         string strOldAccount = pwalletMain->mapAddressBook[address];
+         if (address == GetAccountAddress(strOldAccount))
+             GetAccountAddress(strOldAccount, true);
      }
  
+     pwalletMain->SetAddressBookName(address, strAccount);
      return Value::null;
  }
  
@@@ -472,12 -450,9 +450,9 @@@ Value getaccount(const Array& params, b
          throw JSONRPCError(-5, "Invalid bitcoin address");
  
      string strAccount;
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
-     {
-         map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
-         if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
-             strAccount = (*mi).second;
-     }
+     map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
+     if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
+         strAccount = (*mi).second;
      return strAccount;
  }
  
@@@ -493,15 -468,12 +468,12 @@@ Value getaddressesbyaccount(const Array
  
      // Find all addresses that have the given account
      Array ret;
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
      {
-         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
-         {
-             const CBitcoinAddress& address = item.first;
-             const string& strName = item.second;
-             if (strName == strAccount)
-                 ret.push_back(address.ToString());
-         }
+         const CBitcoinAddress& address = item.first;
+         const string& strName = item.second;
+         if (strName == strAccount)
+             ret.push_back(address.ToString());
      }
      return ret;
  }
@@@ -548,16 -520,12 +520,12 @@@ Value sendtoaddress(const Array& params
      if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty())
          wtx.mapValue["to"]      = params[3].get_str();
  
-     CRITICAL_BLOCK(cs_main)
-     CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
-     {
-         if(pwalletMain->IsLocked())
-             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
+     if (pwalletMain->IsLocked())
+         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
  
-         string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
-         if (strError != "")
-             throw JSONRPCError(-4, strError);
-     }
+     string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
+     if (strError != "")
+         throw JSONRPCError(-4, strError);
  
      return wtx.GetHash().GetHex();
  }
@@@ -586,19 -554,16 +554,16 @@@ Value getreceivedbyaddress(const Array
  
      // Tally
      int64 nAmount = 0;
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
      {
-         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
-         {
-             const CWalletTx& wtx = (*it).second;
-             if (wtx.IsCoinBase() || !wtx.IsFinal())
-                 continue;
+         const CWalletTx& wtx = (*it).second;
+         if (wtx.IsCoinBase() || !wtx.IsFinal())
+             continue;
  
-             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
-                 if (txout.scriptPubKey == scriptPubKey)
-                     if (wtx.GetDepthInMainChain() >= nMinDepth)
-                         nAmount += txout.nValue;
-         }
+         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+             if (txout.scriptPubKey == scriptPubKey)
+                 if (wtx.GetDepthInMainChain() >= nMinDepth)
+                     nAmount += txout.nValue;
      }
  
      return  ValueFromAmount(nAmount);
  
  void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress)
  {
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
      {
-         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
-         {
-             const CBitcoinAddress& address = item.first;
-             const string& strName = item.second;
-             if (strName == strAccount)
-                 setAddress.insert(address);
-         }
+         const CBitcoinAddress& address = item.first;
+         const string& strName = item.second;
+         if (strName == strAccount)
+             setAddress.insert(address);
      }
  }
  
@@@ -639,21 -601,18 +601,18 @@@ Value getreceivedbyaccount(const Array
  
      // Tally
      int64 nAmount = 0;
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
      {
-         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
-         {
-             const CWalletTx& wtx = (*it).second;
-             if (wtx.IsCoinBase() || !wtx.IsFinal())
-                 continue;
+         const CWalletTx& wtx = (*it).second;
+         if (wtx.IsCoinBase() || !wtx.IsFinal())
+             continue;
  
-             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
-             {
-                 CBitcoinAddress address;
-                 if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address))
-                     if (wtx.GetDepthInMainChain() >= nMinDepth)
-                         nAmount += txout.nValue;
-             }
+         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+         {
+             CBitcoinAddress address;
+             if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address))
+                 if (wtx.GetDepthInMainChain() >= nMinDepth)
+                     nAmount += txout.nValue;
          }
      }
  
  int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
  {
      int64 nBalance = 0;
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     {
-         // Tally wallet transactions
-         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
-         {
-             const CWalletTx& wtx = (*it).second;
-             if (!wtx.IsFinal())
-                 continue;
  
-             int64 nGenerated, nReceived, nSent, nFee;
-             wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
+     // Tally wallet transactions
+     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+     {
+         const CWalletTx& wtx = (*it).second;
+         if (!wtx.IsFinal())
+             continue;
  
-             if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
-                 nBalance += nReceived;
-             nBalance += nGenerated - nSent - nFee;
-         }
+         int64 nGenerated, nReceived, nSent, nFee;
+         wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee);
  
-         // Tally internal accounting entries
-         nBalance += walletdb.GetAccountCreditDebit(strAccount);
+         if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth)
+             nBalance += nReceived;
+         nBalance += nGenerated - nSent - nFee;
      }
  
+     // Tally internal accounting entries
+     nBalance += walletdb.GetAccountCreditDebit(strAccount);
      return nBalance;
  }
  
@@@ -763,33 -720,31 +720,31 @@@ Value movecmd(const Array& params, boo
      if (params.size() > 4)
          strComment = params[4].get_str();
  
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     {
-         CWalletDB walletdb(pwalletMain->strWalletFile);
-         walletdb.TxnBegin();
-         int64 nNow = GetAdjustedTime();
-         // Debit
-         CAccountingEntry debit;
-         debit.strAccount = strFrom;
-         debit.nCreditDebit = -nAmount;
-         debit.nTime = nNow;
-         debit.strOtherAccount = strTo;
-         debit.strComment = strComment;
-         walletdb.WriteAccountingEntry(debit);
-         // Credit
-         CAccountingEntry credit;
-         credit.strAccount = strTo;
-         credit.nCreditDebit = nAmount;
-         credit.nTime = nNow;
-         credit.strOtherAccount = strFrom;
-         credit.strComment = strComment;
-         walletdb.WriteAccountingEntry(credit);
-         walletdb.TxnCommit();
-     }
+     CWalletDB walletdb(pwalletMain->strWalletFile);
+     walletdb.TxnBegin();
+     int64 nNow = GetAdjustedTime();
+     // Debit
+     CAccountingEntry debit;
+     debit.strAccount = strFrom;
+     debit.nCreditDebit = -nAmount;
+     debit.nTime = nNow;
+     debit.strOtherAccount = strTo;
+     debit.strComment = strComment;
+     walletdb.WriteAccountingEntry(debit);
+     // Credit
+     CAccountingEntry credit;
+     credit.strAccount = strTo;
+     credit.nCreditDebit = nAmount;
+     credit.nTime = nNow;
+     credit.strOtherAccount = strFrom;
+     credit.strComment = strComment;
+     walletdb.WriteAccountingEntry(credit);
+     walletdb.TxnCommit();
      return true;
  }
  
@@@ -822,23 -777,18 +777,18 @@@ Value sendfrom(const Array& params, boo
      if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
          wtx.mapValue["to"]      = params[5].get_str();
  
-     CRITICAL_BLOCK(cs_main)
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
-     {
-         if(pwalletMain->IsLocked())
-             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
+     if (pwalletMain->IsLocked())
+         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
  
-         // Check funds
-         int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
-         if (nAmount > nBalance)
-             throw JSONRPCError(-6, "Account has insufficient funds");
+     // Check funds
+     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+     if (nAmount > nBalance)
+         throw JSONRPCError(-6, "Account has insufficient funds");
  
-         // Send
-         string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
-         if (strError != "")
-             throw JSONRPCError(-4, strError);
-     }
+     // Send
+     string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx);
+     if (strError != "")
+         throw JSONRPCError(-4, strError);
  
      return wtx.GetHash().GetHex();
  }
@@@ -889,31 -839,26 +839,26 @@@ Value sendmany(const Array& params, boo
          vecSend.push_back(make_pair(scriptPubKey, nAmount));
      }
  
-     CRITICAL_BLOCK(cs_main)
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
-     {
-         if(pwalletMain->IsLocked())
-             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
-         // Check funds
-         int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
-         if (totalAmount > nBalance)
-             throw JSONRPCError(-6, "Account has insufficient funds");
+     if (pwalletMain->IsLocked())
+         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
  
-         // Send
-         CReserveKey keyChange(pwalletMain);
-         int64 nFeeRequired = 0;
-         bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
-         if (!fCreated)
-         {
-             if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
-                 throw JSONRPCError(-6, "Insufficient funds");
-             throw JSONRPCError(-4, "Transaction creation failed");
-         }
-         if (!pwalletMain->CommitTransaction(wtx, keyChange))
-             throw JSONRPCError(-4, "Transaction commit failed");
+     // Check funds
+     int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
+     if (totalAmount > nBalance)
+         throw JSONRPCError(-6, "Account has insufficient funds");
+     // Send
+     CReserveKey keyChange(pwalletMain);
+     int64 nFeeRequired = 0;
+     bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
+     if (!fCreated)
+     {
+         if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
+             throw JSONRPCError(-6, "Insufficient funds");
+         throw JSONRPCError(-4, "Transaction creation failed");
      }
+     if (!pwalletMain->CommitTransaction(wtx, keyChange))
+         throw JSONRPCError(-4, "Transaction commit failed");
  
      return wtx.GetHash().GetHex();
  }
@@@ -944,68 -889,62 +889,62 @@@ Value ListReceived(const Array& params
  
      // Tally
      map<CBitcoinAddress, tallyitem> mapTally;
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
      {
-         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
-         {
-             const CWalletTx& wtx = (*it).second;
-             if (wtx.IsCoinBase() || !wtx.IsFinal())
-                 continue;
+         const CWalletTx& wtx = (*it).second;
+         if (wtx.IsCoinBase() || !wtx.IsFinal())
+             continue;
  
-             int nDepth = wtx.GetDepthInMainChain();
-             if (nDepth < nMinDepth)
-                 continue;
+         int nDepth = wtx.GetDepthInMainChain();
+         if (nDepth < nMinDepth)
+             continue;
  
-             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
-             {
-                 CBitcoinAddress address;
-                 if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid())
-                     continue;
+         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+         {
+             CBitcoinAddress address;
+             if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid())
+                 continue;
  
-                 tallyitem& item = mapTally[address];
-                 item.nAmount += txout.nValue;
-                 item.nConf = min(item.nConf, nDepth);
-             }
+             tallyitem& item = mapTally[address];
+             item.nAmount += txout.nValue;
+             item.nConf = min(item.nConf, nDepth);
          }
      }
  
      // Reply
      Array ret;
      map<string, tallyitem> mapAccountTally;
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
      {
-         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook)
-         {
-             const CBitcoinAddress& address = item.first;
-             const string& strAccount = item.second;
-             map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
-             if (it == mapTally.end() && !fIncludeEmpty)
-                 continue;
+         const CBitcoinAddress& address = item.first;
+         const string& strAccount = item.second;
+         map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address);
+         if (it == mapTally.end() && !fIncludeEmpty)
+             continue;
  
-             int64 nAmount = 0;
-             int nConf = INT_MAX;
-             if (it != mapTally.end())
-             {
-                 nAmount = (*it).second.nAmount;
-                 nConf = (*it).second.nConf;
-             }
+         int64 nAmount = 0;
+         int nConf = INT_MAX;
+         if (it != mapTally.end())
+         {
+             nAmount = (*it).second.nAmount;
+             nConf = (*it).second.nConf;
+         }
  
-             if (fByAccounts)
-             {
-                 tallyitem& item = mapAccountTally[strAccount];
-                 item.nAmount += nAmount;
-                 item.nConf = min(item.nConf, nConf);
-             }
-             else
-             {
-                 Object obj;
-                 obj.push_back(Pair("address",       address.ToString()));
-                 obj.push_back(Pair("account",       strAccount));
-                 obj.push_back(Pair("label",         strAccount)); // deprecated
-                 obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
-                 obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
-                 ret.push_back(obj);
-             }
+         if (fByAccounts)
+         {
+             tallyitem& item = mapAccountTally[strAccount];
+             item.nAmount += nAmount;
+             item.nConf = min(item.nConf, nConf);
+         }
+         else
+         {
+             Object obj;
+             obj.push_back(Pair("address",       address.ToString()));
+             obj.push_back(Pair("account",       strAccount));
+             obj.push_back(Pair("label",         strAccount)); // deprecated
+             obj.push_back(Pair("amount",        ValueFromAmount(nAmount)));
+             obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf)));
+             ret.push_back(obj);
          }
      }
  
@@@ -1107,27 -1046,23 +1046,23 @@@ void ListTransactions(const CWalletTx& 
  
      // Received
      if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
-         CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
          {
-             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
+             string account;
+             if (pwalletMain->mapAddressBook.count(r.first))
+                 account = pwalletMain->mapAddressBook[r.first];
+             if (fAllAccounts || (account == strAccount))
              {
-                 string account;
-                 if (pwalletMain->mapAddressBook.count(r.first))
-                     account = pwalletMain->mapAddressBook[r.first];
-                 if (fAllAccounts || (account == strAccount))
-                 {
-                     Object entry;
-                     entry.push_back(Pair("account", account));
-                     entry.push_back(Pair("address", r.first.ToString()));
-                     entry.push_back(Pair("category", "receive"));
-                     entry.push_back(Pair("amount", ValueFromAmount(r.second)));
-                     if (fLong)
-                         WalletTxToJSON(wtx, entry);
-                     ret.push_back(entry);
-                 }
+                 Object entry;
+                 entry.push_back(Pair("account", account));
+                 entry.push_back(Pair("address", r.first.ToString()));
+                 entry.push_back(Pair("category", "receive"));
+                 entry.push_back(Pair("amount", ValueFromAmount(r.second)));
+                 if (fLong)
+                     WalletTxToJSON(wtx, entry);
+                 ret.push_back(entry);
              }
          }
  }
  
  void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret)
@@@ -1167,41 -1102,38 +1102,38 @@@ Value listtransactions(const Array& par
      Array ret;
      CWalletDB walletdb(pwalletMain->strWalletFile);
  
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     {
-         // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
-         typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
-         typedef multimap<int64, TxPair > TxItems;
-         TxItems txByTime;
+     // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
+     typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
+     typedef multimap<int64, TxPair > TxItems;
+     TxItems txByTime;
  
-         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
-         {
-             CWalletTx* wtx = &((*it).second);
-             txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
-         }
-         list<CAccountingEntry> acentries;
-         walletdb.ListAccountCreditDebit(strAccount, acentries);
-         BOOST_FOREACH(CAccountingEntry& entry, acentries)
-         {
-             txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
-         }
+     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+     {
+         CWalletTx* wtx = &((*it).second);
+         txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
+     }
+     list<CAccountingEntry> acentries;
+     walletdb.ListAccountCreditDebit(strAccount, acentries);
+     BOOST_FOREACH(CAccountingEntry& entry, acentries)
+     {
+         txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry)));
+     }
  
-         // Now: iterate backwards until we have nCount items to return:
-         TxItems::reverse_iterator it = txByTime.rbegin();
-         if (txByTime.size() > nFrom) std::advance(it, nFrom);
-         for (; it != txByTime.rend(); ++it)
-         {
-             CWalletTx *const pwtx = (*it).second.first;
-             if (pwtx != 0)
-                 ListTransactions(*pwtx, strAccount, 0, true, ret);
-             CAccountingEntry *const pacentry = (*it).second.second;
-             if (pacentry != 0)
-                 AcentryToJSON(*pacentry, strAccount, ret);
-             if (ret.size() >= nCount) break;
-         }
-         // ret is now newest to oldest
+     // Now: iterate backwards until we have nCount items to return:
+     TxItems::reverse_iterator it = txByTime.rbegin();
+     if (txByTime.size() > nFrom) std::advance(it, nFrom);
+     for (; it != txByTime.rend(); ++it)
+     {
+         CWalletTx *const pwtx = (*it).second.first;
+         if (pwtx != 0)
+             ListTransactions(*pwtx, strAccount, 0, true, ret);
+         CAccountingEntry *const pacentry = (*it).second.second;
+         if (pacentry != 0)
+             AcentryToJSON(*pacentry, strAccount, ret);
+         if (ret.size() >= nCount) break;
      }
+     // ret is now newest to oldest
      
      // Make sure we return only last nCount items (sends-to-self might give us an extra):
      if (ret.size() > nCount)
@@@ -1227,34 -1159,30 +1159,30 @@@ Value listaccounts(const Array& params
          nMinDepth = params[0].get_int();
  
      map<string, int64> mapAccountBalances;
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
-     {
-         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
-             if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
-                 mapAccountBalances[entry.second] = 0;
-         }
+     BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) {
+         if (pwalletMain->HaveKey(entry.first)) // This address belongs to me
+             mapAccountBalances[entry.second] = 0;
+     }
  
-         for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+     for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
+     {
+         const CWalletTx& wtx = (*it).second;
+         int64 nGeneratedImmature, nGeneratedMature, nFee;
+         string strSentAccount;
+         list<pair<CBitcoinAddress, int64> > listReceived;
+         list<pair<CBitcoinAddress, int64> > listSent;
+         wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
+         mapAccountBalances[strSentAccount] -= nFee;
+         BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
+             mapAccountBalances[strSentAccount] -= s.second;
+         if (wtx.GetDepthInMainChain() >= nMinDepth)
          {
-             const CWalletTx& wtx = (*it).second;
-             int64 nGeneratedImmature, nGeneratedMature, nFee;
-             string strSentAccount;
-             list<pair<CBitcoinAddress, int64> > listReceived;
-             list<pair<CBitcoinAddress, int64> > listSent;
-             wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount);
-             mapAccountBalances[strSentAccount] -= nFee;
-             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent)
-                 mapAccountBalances[strSentAccount] -= s.second;
-             if (wtx.GetDepthInMainChain() >= nMinDepth)
-             {
-                 mapAccountBalances[""] += nGeneratedMature;
-                 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
-                     if (pwalletMain->mapAddressBook.count(r.first))
-                         mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
-                     else
-                         mapAccountBalances[""] += r.second;
-             }
+             mapAccountBalances[""] += nGeneratedMature;
+             BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived)
+                 if (pwalletMain->mapAddressBook.count(r.first))
+                     mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
+                 else
+                     mapAccountBalances[""] += r.second;
          }
      }
  
@@@ -1281,27 -1209,25 +1209,25 @@@ Value gettransaction(const Array& param
      hash.SetHex(params[0].get_str());
  
      Object entry;
-     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
-     {
-         if (!pwalletMain->mapWallet.count(hash))
-             throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
-         const CWalletTx& wtx = pwalletMain->mapWallet[hash];
  
-         int64 nCredit = wtx.GetCredit();
-         int64 nDebit = wtx.GetDebit();
-         int64 nNet = nCredit - nDebit;
-         int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
+     if (!pwalletMain->mapWallet.count(hash))
+         throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
+     const CWalletTx& wtx = pwalletMain->mapWallet[hash];
  
-         entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
-         if (wtx.IsFromMe())
-             entry.push_back(Pair("fee", ValueFromAmount(nFee)));
+     int64 nCredit = wtx.GetCredit();
+     int64 nDebit = wtx.GetDebit();
+     int64 nNet = nCredit - nDebit;
+     int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
  
-         WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
+     entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
+     if (wtx.IsFromMe())
+         entry.push_back(Pair("fee", ValueFromAmount(nFee)));
  
-         Array details;
-         ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
-         entry.push_back(Pair("details", details));
-     }
+     WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
+     Array details;
+     ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
+     entry.push_back(Pair("details", details));
  
      return entry;
  }
@@@ -1332,13 -1258,10 +1258,10 @@@ Value keypoolrefill(const Array& params
              "keypoolrefill\n"
              "Fills the keypool.");
  
-     CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
-     {
-         if (pwalletMain->IsLocked())
-             throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+     if (pwalletMain->IsLocked())
+         throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
  
-         pwalletMain->TopUpKeyPool();
-     }
+     pwalletMain->TopUpKeyPool();
  
      if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
          throw JSONRPCError(-4, "Error refreshing keypool.");
@@@ -1407,24 -1330,21 +1330,21 @@@ Value walletpassphrase(const Array& par
      mlock(&strWalletPass[0], strWalletPass.capacity());
      strWalletPass = params[0].get_str();
  
-     CRITICAL_BLOCK(pwalletMain->cs_vMasterKey)
+     if (strWalletPass.length() > 0)
      {
-         if (strWalletPass.length() > 0)
+         if (!pwalletMain->Unlock(strWalletPass))
          {
-             if (!pwalletMain->Unlock(strWalletPass))
-             {
-                 fill(strWalletPass.begin(), strWalletPass.end(), '\0');
-                 munlock(&strWalletPass[0], strWalletPass.capacity());
-                 throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
-             }
              fill(strWalletPass.begin(), strWalletPass.end(), '\0');
              munlock(&strWalletPass[0], strWalletPass.capacity());
+             throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
          }
-         else
-             throw runtime_error(
-                 "walletpassphrase <passphrase> <timeout>\n"
-                 "Stores the wallet decryption key in memory for <timeout> seconds.");
+         fill(strWalletPass.begin(), strWalletPass.end(), '\0');
+         munlock(&strWalletPass[0], strWalletPass.capacity());
      }
+     else
+         throw runtime_error(
+             "walletpassphrase <passphrase> <timeout>\n"
+             "Stores the wallet decryption key in memory for <timeout> seconds.");
  
      CreateThread(ThreadTopUpKeyPool, NULL);
      int* pnSleepTime = new int(params[1].get_int());
@@@ -1553,11 -1473,8 +1473,8 @@@ Value validateaddress(const Array& para
          string currentAddress = address.ToString();
          ret.push_back(Pair("address", currentAddress));
          ret.push_back(Pair("ismine", (pwalletMain->HaveKey(address) > 0)));
-         CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
-         {
-             if (pwalletMain->mapAddressBook.count(address))
-                 ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
-         }
+         if (pwalletMain->mapAddressBook.count(address))
+             ret.push_back(Pair("account", pwalletMain->mapAddressBook[address]));
      }
      return ret;
  }
@@@ -2233,7 -2150,10 +2150,10 @@@ void ThreadRPCServer2(void* parg
              try
              {
                  // Execute
-                 Value result = (*(*mi).second)(params, false);
+                 Value result;
+                 CRITICAL_BLOCK(cs_main)
+                 CRITICAL_BLOCK(pwalletMain->cs_wallet)
+                     result = (*(*mi).second)(params, false);
  
                  // Send reply
                  string strReply = JSONRPCReply(result, Value::null, id);
diff --combined src/main.cpp
@@@ -22,15 -22,15 +22,15 @@@ set<CWallet*> setpwalletRegistered
  
  CCriticalSection cs_main;
  
- map<uint256, CTransaction> mapTransactions;
+ static map<uint256, CTransaction> mapTransactions;
  CCriticalSection cs_mapTransactions;
  unsigned int nTransactionsUpdated = 0;
  map<COutPoint, CInPoint> mapNextTx;
  
  map<uint256, CBlockIndex*> mapBlockIndex;
  uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
- CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
- int nTotalBlocksEstimate = 134444; // Conservative estimate of total nr of blocks on main chain
+ static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
+ const int nTotalBlocksEstimate = 140700; // Conservative estimate of total nr of blocks on main chain
  const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download"
  CBlockIndex* pindexGenesisBlock = NULL;
  int nBestHeight = -1;
@@@ -295,9 -295,10 +295,10 @@@ int CMerkleTx::SetMerkleBranch(const CB
  bool CTransaction::CheckTransaction() const
  {
      // Basic checks that don't depend on any context
-     if (vin.empty() || vout.empty())
-         return error("CTransaction::CheckTransaction() : vin or vout empty");
+     if (vin.empty())
+         return error("CTransaction::CheckTransaction() : vin empty");
+     if (vout.empty())
+         return error("CTransaction::CheckTransaction() : vout empty");
      // Size limits
      if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
          return error("CTransaction::CheckTransaction() : size limits failed");
@@@ -1301,7 -1302,8 +1302,8 @@@ bool CBlock::AcceptBlock(
              (nHeight ==  74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) ||
              (nHeight == 105000 && hash != uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) ||
              (nHeight == 118000 && hash != uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553")) ||
-             (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")))
+             (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) ||
+             (nHeight == 140700 && hash != uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd")))
              return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight);
  
      // Write block to history file
      if (hashBestChain == hash)
          CRITICAL_BLOCK(cs_vNodes)
              BOOST_FOREACH(CNode* pnode, vNodes)
-                 if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 134444))
+                 if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700))
                      pnode->PushInventory(CInv(MSG_BLOCK, hash));
  
      return true;
@@@ -1835,10 -1837,6 +1837,10 @@@ bool static ProcessMessage(CNode* pfrom
          pfrom->fSuccessfullyConnected = true;
  
          printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
 +        if(pfrom->nStartingHeight > nTotalBlocksEstimate)
 +        {
 +            nTotalBlocksEstimate = pfrom->nStartingHeight;
 +        }
      }
  
  
  
          // Keep giving the same key to the same ip until they use it
          if (!mapReuseKey.count(pfrom->addr.ip))
-             mapReuseKey[pfrom->addr.ip] = pwalletMain->GetOrReuseKeyFromPool();
+             pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true);
  
          // Send back approval of order and pubkey to use
          CScript scriptPubKey;
@@@ -2627,7 -2625,7 +2629,7 @@@ unsigned int static ScanHash_CryptoPP(c
      }
  }
  
+ // Some explaining would be appreciated
  class COrphan
  {
  public:
@@@ -2883,7 -2881,7 +2885,7 @@@ bool CheckWork(CBlock* pblock, CWallet
          reservekey.KeepKey();
  
          // Track how many getdata requests this block gets
-         CRITICAL_BLOCK(wallet.cs_mapRequestCount)
+         CRITICAL_BLOCK(wallet.cs_wallet)
              wallet.mapRequestCount[pblock->GetHash()] = 0;
  
          // Process this block the same as if we had received it from another node
diff --combined src/script.cpp
@@@ -1033,48 -1033,45 +1033,45 @@@ bool Solver(const CKeyStore& keystore, 
          return false;
  
      // Compile solution
-     CRITICAL_BLOCK(keystore.cs_KeyStore)
+     BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
      {
-         BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+         if (item.first == OP_PUBKEY)
          {
-             if (item.first == OP_PUBKEY)
+             // Sign
+             const valtype& vchPubKey = item.second;
+             CKey key;
+             if (!keystore.GetKey(Hash160(vchPubKey), key))
+                 return false;
+             if (key.GetPubKey() != vchPubKey)
+                 return false;
+             if (hash != 0)
              {
-                 // Sign
-                 const valtype& vchPubKey = item.second;
-                 CKey key;
-                 if (!keystore.GetKey(Hash160(vchPubKey), key))
-                     return false;
-                 if (key.GetPubKey() != vchPubKey)
+                 vector<unsigned char> vchSig;
+                 if (!key.Sign(hash, vchSig))
                      return false;
-                 if (hash != 0)
-                 {
-                     vector<unsigned char> vchSig;
-                     if (!key.Sign(hash, vchSig))
-                         return false;
-                     vchSig.push_back((unsigned char)nHashType);
-                     scriptSigRet << vchSig;
-                 }
+                 vchSig.push_back((unsigned char)nHashType);
+                 scriptSigRet << vchSig;
              }
-             else if (item.first == OP_PUBKEYHASH)
+         }
+         else if (item.first == OP_PUBKEYHASH)
+         {
+             // Sign and give pubkey
+             CKey key;
+             if (!keystore.GetKey(uint160(item.second), key))
+                 return false;
+             if (hash != 0)
              {
-                 // Sign and give pubkey
-                 CKey key;
-                 if (!keystore.GetKey(uint160(item.second), key))
+                 vector<unsigned char> vchSig;
+                 if (!key.Sign(hash, vchSig))
                      return false;
-                 if (hash != 0)
-                 {
-                     vector<unsigned char> vchSig;
-                     if (!key.Sign(hash, vchSig))
-                         return false;
-                     vchSig.push_back((unsigned char)nHashType);
-                     scriptSigRet << vchSig << key.GetPubKey();
-                 }
-             }
-             else
-             {
-                 return false;
+                 vchSig.push_back((unsigned char)nHashType);
+                 scriptSigRet << vchSig << key.GetPubKey();
              }
          }
+         else
+         {
+             return false;
+         }
      }
  
      return true;
@@@ -1095,35 -1092,31 +1092,31 @@@ bool IsMine(const CKeyStore &keystore, 
          return false;
  
      // Compile solution
-     CRITICAL_BLOCK(keystore.cs_KeyStore)
+     BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
      {
-         BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+         if (item.first == OP_PUBKEY)
          {
-             if (item.first == OP_PUBKEY)
-             {
-                 const valtype& vchPubKey = item.second;
-                 vector<unsigned char> vchPubKeyFound;
-                 if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
-                     return false;
-                 if (vchPubKeyFound != vchPubKey)
-                     return false;
-             }
-             else if (item.first == OP_PUBKEYHASH)
-             {
-                 if (!keystore.HaveKey(uint160(item.second)))
-                     return false;
-             }
-             else
-             {
+             const valtype& vchPubKey = item.second;
+             vector<unsigned char> vchPubKeyFound;
+             if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
                  return false;
-             }
+             if (vchPubKeyFound != vchPubKey)
+                 return false;
+         }
+         else if (item.first == OP_PUBKEYHASH)
+         {
+             if (!keystore.HaveKey(uint160(item.second)))
+                 return false;
+         }
+         else
+         {
+             return false;
          }
      }
  
      return true;
  }
  
- // requires either keystore==0, or a lock on keystore->cs_KeyStore
  bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
  {
      vector<pair<opcodetype, valtype> > vSolution;
          if (keystore == NULL || keystore->HaveKey(addressRet))
              return true;
      }
 +
      return false;
  }
  
  bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
  {
      if (keystore)
-         CRITICAL_BLOCK(keystore->cs_KeyStore)
-             return ExtractAddressInner(scriptPubKey, keystore, addressRet);
+         return ExtractAddressInner(scriptPubKey, keystore, addressRet);
      else
          return ExtractAddressInner(scriptPubKey, NULL, addressRet);
      return false;
diff --combined src/serialize.h
@@@ -31,7 -31,6 +31,7 @@@ typedef unsigned long long  uint64
  #endif
  
  #ifdef __WXMSW__
 +#include <windows.h>
  // This is used to attempt to keep keying material out of swap
  // Note that VirtualLock does not provide this as a guarantee on Windows,
  // but, in practice, memory that has been VirtualLock'd almost never gets written to
@@@ -64,10 -63,13 +64,13 @@@ static const int VERSION = 32500
  static const char* pszSubVer = "";
  static const bool VERSION_IS_BETA = true;
  
+ // Used to bypass the rule against non-const reference to temporary
+ // where it makes sense with wrappers such as CFlatData or CTxDB
+ template<typename T>
+ inline T& REF(const T& val)
+ {
+     return const_cast<T&>(val);
+ }
  
  /////////////////////////////////////////////////////////////////
  //
diff --combined src/util.cpp
@@@ -264,7 -264,8 +264,7 @@@ int my_snprintf(char* buffer, size_t li
      return ret;
  }
  
 -
 -string strprintf(const char* format, ...)
 +string strprintf(const std::string &format, ...)
  {
      char buffer[50000];
      char* p = buffer;
      {
          va_list arg_ptr;
          va_start(arg_ptr, format);
 -        ret = _vsnprintf(p, limit, format, arg_ptr);
 +        ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
          va_end(arg_ptr);
          if (ret >= 0 && ret < limit)
              break;
      return str;
  }
  
 -
 -bool error(const char* format, ...)
 +bool error(const std::string &format, ...)
  {
      char buffer[50000];
      int limit = sizeof(buffer);
      va_list arg_ptr;
      va_start(arg_ptr, format);
 -    int ret = _vsnprintf(buffer, limit, format, arg_ptr);
 +    int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr);
      va_end(arg_ptr);
      if (ret < 0 || ret >= limit)
      {
@@@ -940,17 -942,21 +940,21 @@@ static std::map<std::pair<CCriticalSect
  static boost::thread_specific_ptr<LockStack> lockstack;
  
  
- static void potential_deadlock_detected(const LockStack& s1, const LockStack& s2)
+ static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2)
  {
      printf("POTENTIAL DEADLOCK DETECTED\n");
      printf("Previous lock order was:\n");
      BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2)
      {
+         if (i.first == mismatch.first) printf(" (1)");
+         if (i.first == mismatch.second) printf(" (2)");
          printf(" %s  %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine);
      }
      printf("Current lock order is:\n");
      BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1)
      {
+         if (i.first == mismatch.first) printf(" (1)");
+         if (i.first == mismatch.second) printf(" (2)");
          printf(" %s  %s:%d\n", i.second.mutexName.c_str(), i.second.sourceFile.c_str(), i.second.sourceLine);
      }
  }
@@@ -977,7 -983,7 +981,7 @@@ static void push_lock(CCriticalSection
          std::pair<CCriticalSection*, CCriticalSection*> p2 = std::make_pair(c, i.first);
          if (lockorders.count(p2))
          {
-             potential_deadlock_detected(lockorders[p2], lockorders[p1]);
+             potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
              break;
          }
      }
diff --combined src/util.h
@@@ -65,16 -65,8 +65,8 @@@ typedef unsigned long long  uint64
  #endif
  
  // This is needed because the foreach macro can't get over the comma in pair<t1, t2>
 -#define PAIRTYPE(t1, t2)    pair<t1, t2>
 +#define PAIRTYPE(t1, t2)    std::pair<t1, t2>
  
- // Used to bypass the rule against non-const reference to temporary
- // where it makes sense with wrappers such as CFlatData or CTxDB
- template<typename T>
- inline T& REF(const T& val)
- {
-     return (T&)val;
- }
  // Align by increasing pointer, must have extra space at end of buffer
  template <size_t nBytes, typename T>
  T* alignup(T* p)
@@@ -140,7 -132,8 +132,7 @@@ inline int myclosesocket(SOCKET& hSocke
      return ret;
  }
  #define closesocket(s)      myclosesocket(s)
 -
 -#ifndef GUI
 +#if !defined(QT_GUI) && !defined(GUI)
  inline const char* _(const char* psz)
  {
      return psz;
  
  
  
 -
  extern std::map<std::string, std::string> mapArgs;
  extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
  extern bool fDebug;
@@@ -175,8 -169,8 +167,8 @@@ void RandAddSeed()
  void RandAddSeedPerfmon();
  int OutputDebugStringF(const char* pszFormat, ...);
  int my_snprintf(char* buffer, size_t limit, const char* format, ...);
 -std::string strprintf(const char* format, ...);
 -bool error(const char* format, ...);
 +std::string strprintf(const std::string &format, ...);
 +bool error(const std::string &format, ...);
  void LogException(std::exception* pex, const char* pszThread);
  void PrintException(std::exception* pex, const char* pszThread);
  void PrintExceptionContinue(std::exception* pex, const char* pszThread);
diff --combined src/wallet.cpp
@@@ -33,7 -33,7 +33,7 @@@ bool CWallet::AddCryptedKey(const vecto
          return false;
      if (!fFileBacked)
          return true;
-     CRITICAL_BLOCK(cs_pwalletdbEncryption)
+     CRITICAL_BLOCK(cs_wallet)
      {
          if (pwalletdbEncryption)
              return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
  
  bool CWallet::Unlock(const string& strWalletPassphrase)
  {
-     CRITICAL_BLOCK(cs_vMasterKey)
-     {
-         if (!IsLocked())
-             return false;
+     if (!IsLocked())
+         return false;
  
-         CCrypter crypter;
-         CKeyingMaterial vMasterKey;
+     CCrypter crypter;
+     CKeyingMaterial vMasterKey;
  
+     CRITICAL_BLOCK(cs_wallet)
          BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
          {
              if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
              if (CCryptoKeyStore::Unlock(vMasterKey))
                  return true;
          }
-     }
      return false;
  }
  
  bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase)
  {
-     CRITICAL_BLOCK(cs_vMasterKey)
-     {
-         bool fWasLocked = IsLocked();
+     bool fWasLocked = IsLocked();
  
+     CRITICAL_BLOCK(cs_wallet)
+     {
          Lock();
  
          CCrypter crypter;
@@@ -79,7 -77,7 +77,7 @@@
          {
              if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
                  return false;
-             if(!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
+             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
                  return false;
              if (CCryptoKeyStore::Unlock(vMasterKey))
              {
              }
          }
      }
      return false;
  }
  
@@@ -125,44 -124,42 +124,42 @@@ public
  
  bool CWallet::EncryptWallet(const string& strWalletPassphrase)
  {
-     CRITICAL_BLOCK(cs_KeyStore)
-     CRITICAL_BLOCK(cs_vMasterKey)
-     CRITICAL_BLOCK(cs_pwalletdbEncryption)
-     {
-         if (IsCrypted())
-             return false;
+     if (IsCrypted())
+         return false;
  
-         CKeyingMaterial vMasterKey;
-         RandAddSeedPerfmon();
+     CKeyingMaterial vMasterKey;
+     RandAddSeedPerfmon();
  
-         vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
-         RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
+     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
+     RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
  
-         CMasterKey kMasterKey;
+     CMasterKey kMasterKey;
  
-         RandAddSeedPerfmon();
-         kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
-         RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
+     RandAddSeedPerfmon();
+     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
+     RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
  
-         CCrypter crypter;
-         int64 nStartTime = GetTimeMillis();
-         crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
-         kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
+     CCrypter crypter;
+     int64 nStartTime = GetTimeMillis();
+     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
+     kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
  
-         nStartTime = GetTimeMillis();
-         crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
-         kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
+     nStartTime = GetTimeMillis();
+     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
+     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
  
-         if (kMasterKey.nDeriveIterations < 25000)
-             kMasterKey.nDeriveIterations = 25000;
+     if (kMasterKey.nDeriveIterations < 25000)
+         kMasterKey.nDeriveIterations = 25000;
  
-         printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
+     printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
  
-         if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
-             return false;
-         if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
-             return false;
+     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
+         return false;
+     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
+         return false;
  
+     CRITICAL_BLOCK(cs_wallet)
+     {
          mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
          if (fFileBacked)
          {
  
          Lock();
      }
      return true;
  }
  
@@@ -199,7 -197,7 +197,7 @@@ void CWallet::WalletUpdateSpent(const C
      // Anytime a signature is successfully verified, it's proof the outpoint is spent.
      // Update the wallet spent flag if it doesn't know due to wallet.dat being
      // restored from backup or the user making copies of wallet.dat.
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          BOOST_FOREACH(const CTxIn& txin, tx.vin)
          {
  bool CWallet::AddToWallet(const CWalletTx& wtxIn)
  {
      uint256 hash = wtxIn.GetHash();
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          // Inserts only if not already there, returns tx inserted or tx found
          pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
          if (fInsertedNew || fUpdated)
              if (!wtx.WriteToDisk())
                  return false;
 -
 +#ifndef QT_GUI
          // If default receiving address gets used, replace it with a new one
          CScript scriptDefaultKey;
          scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
          {
              if (txout.scriptPubKey == scriptDefaultKey)
              {
-                 SetDefaultKey(GetOrReuseKeyFromPool());
-                 SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
+                 std::vector<unsigned char> newDefaultKey;
+                 if (GetKeyFromPool(newDefaultKey, false))
+                 {
+                     SetDefaultKey(newDefaultKey);
+                     SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
+                 }
              }
          }
 -
 +#endif
          // Notify UI
          vWalletUpdated.push_back(hash);
  
  bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
  {
      uint256 hash = tx.GetHash();
-     bool fExisted = mapWallet.count(hash);
-     if (fExisted && !fUpdate) return false;
-     if (fExisted || IsMine(tx) || IsFromMe(tx))
+     CRITICAL_BLOCK(cs_wallet)
      {
-         CWalletTx wtx(this,tx);
-         // Get merkle branch if transaction was found in a block
-         if (pblock)
-             wtx.SetMerkleBranch(pblock);
-         return AddToWallet(wtx);
+         bool fExisted = mapWallet.count(hash);
+         if (fExisted && !fUpdate) return false;
+         if (fExisted || IsMine(tx) || IsFromMe(tx))
+         {
+             CWalletTx wtx(this,tx);
+             // Get merkle branch if transaction was found in a block
+             if (pblock)
+                 wtx.SetMerkleBranch(pblock);
+             return AddToWallet(wtx);
+         }
+         else
+             WalletUpdateSpent(tx);
      }
-     else
-         WalletUpdateSpent(tx);
      return false;
  }
  
@@@ -309,7 -314,7 +314,7 @@@ bool CWallet::EraseFromWallet(uint256 h
  {
      if (!fFileBacked)
          return false;
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          if (mapWallet.erase(hash))
              CWalletDB(strWalletFile).EraseTx(hash);
  
  bool CWallet::IsMine(const CTxIn &txin) const
  {
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
          if (mi != mapWallet.end())
  
  int64 CWallet::GetDebit(const CTxIn &txin) const
  {
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
          if (mi != mapWallet.end())
  
  int64 CWalletTx::GetTxTime() const
  {
-     if (!fTimeReceivedIsTxTime && hashBlock != 0)
-     {
-         // If we did not receive the transaction directly, we rely on the block's
-         // time to figure out when it happened.  We use the median over a range
-         // of blocks to try to filter out inaccurate block times.
-         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
-         if (mi != mapBlockIndex.end())
-         {
-             CBlockIndex* pindex = (*mi).second;
-             if (pindex)
-                 return pindex->GetMedianTime();
-         }
-     }
      return nTimeReceived;
  }
  
@@@ -372,7 -364,7 +364,7 @@@ int CWalletTx::GetRequestCount() cons
  {
      // Returns -1 if it wasn't being tracked
      int nRequests = -1;
-     CRITICAL_BLOCK(pwallet->cs_mapRequestCount)
+     CRITICAL_BLOCK(pwallet->cs_wallet)
      {
          if (IsCoinBase())
          {
@@@ -478,7 -470,7 +470,7 @@@ void CWalletTx::GetAccountAmounts(cons
              nSent += s.second;
          nFee = allFee;
      }
-     CRITICAL_BLOCK(pwallet->cs_mapAddressBook)
+     CRITICAL_BLOCK(pwallet->cs_wallet)
      {
          BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
          {
@@@ -508,7 -500,7 +500,7 @@@ void CWalletTx::AddSupportingTransactio
              vWorkQueue.push_back(txin.prevout.hash);
  
          // This critsect is OK because txdb is already open
-         CRITICAL_BLOCK(pwallet->cs_mapWallet)
+         CRITICAL_BLOCK(pwallet->cs_wallet)
          {
              map<uint256, const CMerkleTx*> mapWalletPrev;
              set<uint256> setAlreadyDone;
@@@ -564,7 -556,7 +556,7 @@@ int CWallet::ScanForWalletTransactions(
      int ret = 0;
  
      CBlockIndex* pindex = pindexStart;
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          while (pindex)
          {
@@@ -585,7 -577,7 +577,7 @@@ void CWallet::ReacceptWalletTransaction
  {
      CTxDB txdb("r");
      bool fRepeat = true;
-     while (fRepeat) CRITICAL_BLOCK(cs_mapWallet)
+     while (fRepeat) CRITICAL_BLOCK(cs_wallet)
      {
          fRepeat = false;
          vector<CDiskTxPos> vMissingTx;
@@@ -688,7 -680,7 +680,7 @@@ void CWallet::ResendWalletTransactions(
      // Rebroadcast any of our txes that aren't in a block yet
      printf("ResendWalletTransactions()\n");
      CTxDB txdb("r");
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          // Sort them in chronological order
          multimap<unsigned int, CWalletTx*> mapSorted;
  int64 CWallet::GetBalance() const
  {
      int64 nTotal = 0;
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
          {
      return nTotal;
  }
  
 +int64 CWallet::GetUnconfirmedBalance() const
 +{
 +    int64 nTotal = 0;
 +    CRITICAL_BLOCK(cs_mapWallet)
 +    {
 +        for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
 +        {
 +            const CWalletTx* pcoin = &(*it).second;
 +            if (pcoin->IsFinal() && pcoin->IsConfirmed())
 +                continue;
 +            nTotal += pcoin->GetAvailableCredit();
 +        }
 +    }
 +    return nTotal;
 +}
  
  bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
  {
      vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
      int64 nTotalLower = 0;
  
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
         vector<const CWalletTx*> vCoins;
         vCoins.reserve(mapWallet.size());
@@@ -922,10 -899,10 +914,10 @@@ bool CWallet::CreateTransaction(const v
      wtxNew.pwallet = this;
  
      CRITICAL_BLOCK(cs_main)
+     CRITICAL_BLOCK(cs_wallet)
      {
          // txdb must be opened before the mapWallet lock
          CTxDB txdb("r");
-         CRITICAL_BLOCK(cs_mapWallet)
          {
              nFeeRet = nTransactionFee;
              loop
@@@ -1036,9 -1013,9 +1028,9 @@@ bool CWallet::CreateTransaction(CScrip
  bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
  {
      CRITICAL_BLOCK(cs_main)
+     CRITICAL_BLOCK(cs_wallet)
      {
          printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
-         CRITICAL_BLOCK(cs_mapWallet)
          {
              // This is only to keep the database open to defeat the auto-flush for the
              // duration of this scope.  This is the only place where this optimization
          }
  
          // Track how many getdata requests our transaction gets
-         CRITICAL_BLOCK(cs_mapRequestCount)
-             mapRequestCount[wtxNew.GetHash()] = 0;
+         mapRequestCount[wtxNew.GetHash()] = 0;
  
          // Broadcast
          if (!wtxNew.AcceptToMemoryPool())
  
  
  
- // requires cs_main lock
  string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
  {
      CReserveKey reservekey(this);
      int64 nFeeRequired;
-     CRITICAL_BLOCK(cs_vMasterKey)
+     if (IsLocked())
      {
-         if (IsLocked())
-         {
-             string strError = _("Error: Wallet locked, unable to create transaction  ");
-             printf("SendMoney() : %s", strError.c_str());
-             return strError;
-         }
-         if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
-         {
-             string strError;
-             if (nValue + nFeeRequired > GetBalance())
-                 strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds  "), FormatMoney(nFeeRequired).c_str());
-             else
-                 strError = _("Error: Transaction creation failed  ");
-             printf("SendMoney() : %s", strError.c_str());
-             return strError;
-         }
+         string strError = _("Error: Wallet locked, unable to create transaction  ");
+         printf("SendMoney() : %s", strError.c_str());
+         return strError;
+     }
+     if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
+     {
+         string strError;
+         if (nValue + nFeeRequired > GetBalance())
+             strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds  "), FormatMoney(nFeeRequired).c_str());
+         else
+             strError = _("Error: Transaction creation failed  ");
+         printf("SendMoney() : %s", strError.c_str());
+         return strError;
      }
  
      if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
  
  
  
- // requires cs_main lock
  string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
  {
      // Check amount
@@@ -1158,7 -1130,10 +1145,10 @@@ int CWallet::LoadWallet(bool& fFirstRun
          // Create new keyUser and set as default key
          RandAddSeedPerfmon();
  
-         SetDefaultKey(GetOrReuseKeyFromPool());
+         std::vector<unsigned char> newDefaultKey;
+         if (!GetKeyFromPool(newDefaultKey, false))
+             return DB_LOAD_FAIL;
+         SetDefaultKey(newDefaultKey);
          if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""))
              return DB_LOAD_FAIL;
      }
@@@ -1187,7 -1162,7 +1177,7 @@@ bool CWallet::DelAddressBookName(const 
  
  void CWallet::PrintWallet(const CBlock& block)
  {
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          if (mapWallet.count(block.vtx[0].GetHash()))
          {
  
  bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
  {
-     CRITICAL_BLOCK(cs_mapWallet)
+     CRITICAL_BLOCK(cs_wallet)
      {
          map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
          if (mi != mapWallet.end())
@@@ -1233,10 -1208,7 +1223,7 @@@ bool GetWalletFile(CWallet* pwallet, st
  
  bool CWallet::TopUpKeyPool()
  {
-     CRITICAL_BLOCK(cs_main)
-     CRITICAL_BLOCK(cs_mapWallet)
-     CRITICAL_BLOCK(cs_setKeyPool)
-     CRITICAL_BLOCK(cs_vMasterKey)
+     CRITICAL_BLOCK(cs_wallet)
      {
          if (IsLocked())
              return false;
@@@ -1263,9 -1235,7 +1250,7 @@@ void CWallet::ReserveKeyFromKeyPool(int
  {
      nIndex = -1;
      keypool.vchPubKey.clear();
-     CRITICAL_BLOCK(cs_main)
-     CRITICAL_BLOCK(cs_mapWallet)
-     CRITICAL_BLOCK(cs_setKeyPool)
+     CRITICAL_BLOCK(cs_wallet)
      {
          if (!IsLocked())
              TopUpKeyPool();
@@@ -1293,10 -1263,7 +1278,7 @@@ void CWallet::KeepKey(int64 nIndex
      if (fFileBacked)
      {
          CWalletDB walletdb(strWalletFile);
-         CRITICAL_BLOCK(cs_main)
-         {
-             walletdb.ErasePool(nIndex);
-         }
+         walletdb.ErasePool(nIndex);
      }
      printf("keypool keep %"PRI64d"\n", nIndex);
  }
  void CWallet::ReturnKey(int64 nIndex)
  {
      // Return to key pool
-     CRITICAL_BLOCK(cs_setKeyPool)
+     CRITICAL_BLOCK(cs_wallet)
          setKeyPool.insert(nIndex);
      printf("keypool return %"PRI64d"\n", nIndex);
  }
  
- vector<unsigned char> CWallet::GetOrReuseKeyFromPool()
+ bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
  {
      int64 nIndex = 0;
      CKeyPool keypool;
-     ReserveKeyFromKeyPool(nIndex, keypool);
-     if(nIndex == -1)
-         return vchDefaultKey;
-     KeepKey(nIndex);
-     return keypool.vchPubKey;
+     CRITICAL_BLOCK(cs_wallet)
+     {
+         ReserveKeyFromKeyPool(nIndex, keypool);
+         if (nIndex == -1)
+         {
+             if (fAllowReuse && !vchDefaultKey.empty())
+             {
+                 result = vchDefaultKey;
+                 return true;
+             }
+             if (IsLocked()) return false;
+             result = GenerateNewKey();
+             return true;
+         }
+         KeepKey(nIndex);
+         result = keypool.vchPubKey;
+     }
+     return true;
  }
  
  int64 CWallet::GetOldestKeyPoolTime()
diff --combined src/wallet.h
@@@ -20,14 -20,14 +20,14 @@@ private
      bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
  
      CWalletDB *pwalletdbEncryption;
-     CCriticalSection cs_pwalletdbEncryption;
  
  public:
+     mutable CCriticalSection cs_wallet;
      bool fFileBacked;
      std::string strWalletFile;
  
      std::set<int64> setKeyPool;
-     CCriticalSection cs_setKeyPool;
  
      typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
      MasterKeyMap mapMasterKeys;
          pwalletdbEncryption = NULL;
      }
  
-     mutable CCriticalSection cs_mapWallet;
      std::map<uint256, CWalletTx> mapWallet;
      std::vector<uint256> vWalletUpdated;
  
      std::map<uint256, int> mapRequestCount;
-     mutable CCriticalSection cs_mapRequestCount;
  
      std::map<CBitcoinAddress, std::string> mapAddressBook;
-     mutable CCriticalSection cs_mapAddressBook;
  
      std::vector<unsigned char> vchDefaultKey;
  
@@@ -77,7 -74,6 +74,7 @@@
      void ReacceptWalletTransactions();
      void ResendWalletTransactions();
      int64 GetBalance() const;
 +    int64 GetUnconfirmedBalance() const;
      bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
      bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
      bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
@@@ -89,7 -85,7 +86,7 @@@
      void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
      void KeepKey(int64 nIndex);
      void ReturnKey(int64 nIndex);
-     std::vector<unsigned char> GetOrReuseKeyFromPool();
+     bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
      int64 GetOldestKeyPoolTime();
  
      bool IsMine(const CTxIn& txin) const;
      {
          CBitcoinAddress address;
          if (ExtractAddress(txout.scriptPubKey, this, address))
-             CRITICAL_BLOCK(cs_mapAddressBook)
+             CRITICAL_BLOCK(cs_wallet)
                  if (!mapAddressBook.count(address))
                      return true;
          return false;
      int LoadWallet(bool& fFirstRunRet);
  //    bool BackupWallet(const std::string& strDest);
  
-     // requires cs_mapAddressBook lock
      bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName);
  
-     // requires cs_mapAddressBook lock
      bool DelAddressBookName(const CBitcoinAddress& address);
  
      void UpdatedTransaction(const uint256 &hashTx)
      {
-         CRITICAL_BLOCK(cs_mapWallet)
+         CRITICAL_BLOCK(cs_wallet)
              vWalletUpdated.push_back(hashTx);
      }
  
  
      void Inventory(const uint256 &hash)
      {
-         CRITICAL_BLOCK(cs_mapRequestCount)
+         CRITICAL_BLOCK(cs_wallet)
          {
              std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
              if (mi != mapRequestCount.end())