aboutsummaryrefslogtreecommitdiff
path: root/src/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet.cpp')
-rw-r--r--src/wallet.cpp101
1 files changed, 57 insertions, 44 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp
index fb2fc7efbc..c115a53340 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -3,9 +3,10 @@
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "headers.h"
-#include "db.h"
+#include "wallet.h"
+#include "walletdb.h"
#include "crypter.h"
+#include "ui_interface.h"
using namespace std;
@@ -49,8 +50,8 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
return false;
if (!fFileBacked)
return true;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
if (pwalletdbEncryption)
return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
else
@@ -76,7 +77,8 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase)
CCrypter crypter;
CKeyingMaterial vMasterKey;
- CRITICAL_BLOCK(cs_wallet)
+ {
+ LOCK(cs_wallet);
BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
{
if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
@@ -86,6 +88,7 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase)
if (CCryptoKeyStore::Unlock(vMasterKey))
return true;
}
+ }
return false;
}
@@ -93,8 +96,8 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
{
bool fWasLocked = IsLocked();
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
Lock();
CCrypter crypter;
@@ -135,6 +138,11 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
return false;
}
+void CWallet::SetBestChain(const CBlockLocator& loc)
+{
+ CWalletDB walletdb(strWalletFile);
+ walletdb.WriteBestBlock(loc);
+}
// This class implements an addrIncoming entry that causes pre-0.4
// clients to crash on startup if reading a private-key-encrypted wallet.
@@ -228,8 +236,8 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
return false;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
if (fFileBacked)
{
@@ -276,8 +284,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
// 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_wallet)
{
+ LOCK(cs_wallet);
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
@@ -298,8 +306,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
void CWallet::MarkDirty()
{
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
item.second.MarkDirty();
}
@@ -308,8 +316,8 @@ void CWallet::MarkDirty()
bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{
uint256 hash = wtxIn.GetHash();
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(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));
CWalletTx& wtx = (*ret.first).second;
@@ -383,8 +391,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
{
uint256 hash = tx.GetHash();
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
bool fExisted = mapWallet.count(hash);
if (fExisted && !fUpdate) return false;
if (fExisted || IsMine(tx) || IsFromMe(tx))
@@ -405,8 +413,8 @@ bool CWallet::EraseFromWallet(uint256 hash)
{
if (!fFileBacked)
return false;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
if (mapWallet.erase(hash))
CWalletDB(strWalletFile).EraseTx(hash);
}
@@ -416,8 +424,8 @@ bool CWallet::EraseFromWallet(uint256 hash)
bool CWallet::IsMine(const CTxIn &txin) const
{
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
if (mi != mapWallet.end())
{
@@ -432,8 +440,8 @@ bool CWallet::IsMine(const CTxIn &txin) const
int64 CWallet::GetDebit(const CTxIn &txin) const
{
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
if (mi != mapWallet.end())
{
@@ -458,9 +466,11 @@ bool CWallet::IsChange(const CTxOut& txout) const
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
// which output, if any, was change).
if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
- CRITICAL_BLOCK(cs_wallet)
- if (!mapAddressBook.count(address))
- return true;
+ {
+ LOCK(cs_wallet);
+ if (!mapAddressBook.count(address))
+ return true;
+ }
return false;
}
@@ -473,8 +483,8 @@ int CWalletTx::GetRequestCount() const
{
// Returns -1 if it wasn't being tracked
int nRequests = -1;
- CRITICAL_BLOCK(pwallet->cs_wallet)
{
+ LOCK(pwallet->cs_wallet);
if (IsCoinBase())
{
// Generated block
@@ -578,8 +588,8 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i
nSent += s.second;
nFee = allFee;
}
- CRITICAL_BLOCK(pwallet->cs_wallet)
{
+ LOCK(pwallet->cs_wallet);
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
{
if (pwallet->mapAddressBook.count(r.first))
@@ -608,8 +618,8 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
vWorkQueue.push_back(txin.prevout.hash);
// This critsect is OK because txdb is already open
- CRITICAL_BLOCK(pwallet->cs_wallet)
{
+ LOCK(pwallet->cs_wallet);
map<uint256, const CMerkleTx*> mapWalletPrev;
set<uint256> setAlreadyDone;
for (unsigned int i = 0; i < vWorkQueue.size(); i++)
@@ -669,8 +679,8 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
int ret = 0;
CBlockIndex* pindex = pindexStart;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
while (pindex)
{
CBlock block;
@@ -699,8 +709,9 @@ void CWallet::ReacceptWalletTransactions()
{
CTxDB txdb("r");
bool fRepeat = true;
- while (fRepeat) CRITICAL_BLOCK(cs_wallet)
+ while (fRepeat)
{
+ LOCK(cs_wallet);
fRepeat = false;
vector<CDiskTxPos> vMissingTx;
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
@@ -802,8 +813,8 @@ void CWallet::ResendWalletTransactions()
// Rebroadcast any of our txes that aren't in a block yet
printf("ResendWalletTransactions()\n");
CTxDB txdb("r");
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
// Sort them in chronological order
multimap<unsigned int, CWalletTx*> mapSorted;
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
@@ -836,8 +847,8 @@ void CWallet::ResendWalletTransactions()
int64 CWallet::GetBalance() const
{
int64 nTotal = 0;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx* pcoin = &(*it).second;
@@ -853,8 +864,8 @@ int64 CWallet::GetBalance() const
int64 CWallet::GetUnconfirmedBalance() const
{
int64 nTotal = 0;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx* pcoin = &(*it).second;
@@ -878,8 +889,8 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
int64 nTotalLower = 0;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
vector<const CWalletTx*> vCoins;
vCoins.reserve(mapWallet.size());
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
@@ -1035,9 +1046,8 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
wtxNew.BindWallet(this);
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK2(cs_main, cs_wallet);
// txdb must be opened before the mapWallet lock
CTxDB txdb("r");
{
@@ -1113,7 +1123,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
return false;
// Limit size
- unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
+ unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
return false;
dPriority /= nBytes;
@@ -1149,9 +1159,8 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w
// Call after CreateTransaction unless you want to abort
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
{
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK2(cs_main, cs_wallet);
printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
{
// This is only to keep the database open to defeat the auto-flush for the
@@ -1222,7 +1231,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
return strError;
}
- if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
+ if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending...")))
return "ABORTED";
if (!CommitTransaction(wtxNew, reservekey))
@@ -1282,6 +1291,7 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
{
mapAddressBook[address] = strName;
+ AddressBookRepaint();
if (!fFileBacked)
return false;
return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
@@ -1290,6 +1300,7 @@ bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& s
bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
{
mapAddressBook.erase(address);
+ AddressBookRepaint();
if (!fFileBacked)
return false;
return CWalletDB(strWalletFile).EraseName(address.ToString());
@@ -1298,8 +1309,8 @@ bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
void CWallet::PrintWallet(const CBlock& block)
{
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
if (mapWallet.count(block.vtx[0].GetHash()))
{
CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
@@ -1311,8 +1322,8 @@ void CWallet::PrintWallet(const CBlock& block)
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
{
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
if (mi != mapWallet.end())
{
@@ -1348,8 +1359,8 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
//
bool CWallet::NewKeyPool()
{
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
CWalletDB walletdb(strWalletFile);
BOOST_FOREACH(int64 nIndex, setKeyPool)
walletdb.ErasePool(nIndex);
@@ -1372,16 +1383,17 @@ bool CWallet::NewKeyPool()
bool CWallet::TopUpKeyPool()
{
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
+
if (IsLocked())
return false;
CWalletDB walletdb(strWalletFile);
// Top up key pool
- int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
- while (setKeyPool.size() < nTargetSize+1)
+ unsigned int nTargetSize = max(GetArg("-keypool", 100), 0LL);
+ while (setKeyPool.size() < (nTargetSize + 1))
{
int64 nEnd = 1;
if (!setKeyPool.empty())
@@ -1399,8 +1411,9 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
{
nIndex = -1;
keypool.vchPubKey.clear();
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
+
if (!IsLocked())
TopUpKeyPool();
@@ -1423,9 +1436,8 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
int64 CWallet::AddReserveKey(const CKeyPool& keypool)
{
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK2(cs_main, cs_wallet);
CWalletDB walletdb(strWalletFile);
int64 nIndex = 1 + *(--setKeyPool.end());
@@ -1451,8 +1463,10 @@ void CWallet::KeepKey(int64 nIndex)
void CWallet::ReturnKey(int64 nIndex)
{
// Return to key pool
- CRITICAL_BLOCK(cs_wallet)
+ {
+ LOCK(cs_wallet);
setKeyPool.insert(nIndex);
+ }
printf("keypool return %"PRI64d"\n", nIndex);
}
@@ -1460,8 +1474,8 @@ bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
{
int64 nIndex = 0;
CKeyPool keypool;
- CRITICAL_BLOCK(cs_wallet)
{
+ LOCK(cs_wallet);
ReserveKeyFromKeyPool(nIndex, keypool);
if (nIndex == -1)
{
@@ -1531,8 +1545,7 @@ void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
CWalletDB walletdb(strWalletFile);
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_wallet)
+ LOCK2(cs_main, cs_wallet);
BOOST_FOREACH(const int64& id, setKeyPool)
{
CKeyPool keypool;