// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
#include "db.h"
-#include "cryptopp/sha.h"
#include "crypter.h"
using namespace std;
else
return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
}
+ return false;
}
-bool CWallet::Unlock(const string& strWalletPassphrase)
+bool CWallet::Unlock(const SecureString& strWalletPassphrase)
{
if (!IsLocked())
return false;
return false;
}
-bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase)
+bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
{
bool fWasLocked = IsLocked();
)
};
-bool CWallet::EncryptWallet(const string& strWalletPassphrase)
+bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
{
if (IsCrypted())
return false;
if (fFileBacked)
{
pwalletdbEncryption = new CWalletDB(strWalletFile);
- pwalletdbEncryption->TxnBegin();
+ if (!pwalletdbEncryption->TxnBegin())
+ return false;
pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
}
if (!pwalletdbEncryption->TxnCommit())
exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
- pwalletdbEncryption->Close();
+ delete pwalletdbEncryption;
pwalletdbEncryption = NULL;
}
Lock();
+ Unlock(strWalletPassphrase);
+ NewKeyPool();
+ Lock();
+
+ // Need to completely rewrite the wallet file; if we don't, bdb might keep
+ // bits of the unencrypted private key in slack space in the database file.
+ CDB::Rewrite(strWalletFile);
}
return true;
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);
}
}
}
-
+#endif
// Notify UI
vWalletUpdated.push_back(hash);
return true;
}
+// Add a transaction to the wallet, or update it.
+// pblock is optional, but should be provided if the transaction is known to be in a block.
+// If fUpdate is true, existing transactions will be updated.
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
{
uint256 hash = tx.GetHash();
{
map<uint256, const CMerkleTx*> mapWalletPrev;
set<uint256> setAlreadyDone;
- for (int i = 0; i < vWorkQueue.size(); i++)
+ for (unsigned int i = 0; i < vWorkQueue.size(); i++)
{
uint256 hash = vWorkQueue[i];
if (setAlreadyDone.count(hash))
vtxPrev.push_back(tx);
if (nDepth < COPY_DEPTH)
+ {
BOOST_FOREACH(const CTxIn& txin, tx.vin)
vWorkQueue.push_back(txin.prevout.hash);
+ }
}
}
}
return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
}
+// Scan the block chain (starting in pindexStart) for transactions
+// from or to us. If fUpdate is true, found transactions that already
+// exist in the wallet will be updated.
int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
{
int ret = 0;
printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
continue;
}
- for (int i = 0; i < txindex.vSpent.size(); i++)
+ for (unsigned int i = 0; i < txindex.vSpent.size(); i++)
{
if (wtx.IsSpent(i))
continue;
return nTotal;
}
+int64 CWallet::GetUnconfirmedBalance() const
+{
+ int64 nTotal = 0;
+ CRITICAL_BLOCK(cs_wallet)
+ {
+ 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
{
if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
continue;
- for (int i = 0; i < pcoin->vout.size(); i++)
+ for (unsigned int i = 0; i < pcoin->vout.size(); i++)
{
if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]))
continue;
if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
{
- for (int i = 0; i < vValue.size(); ++i)
+ for (unsigned int i = 0; i < vValue.size(); ++i)
{
setCoinsRet.insert(vValue[i].second);
nValueRet += vValue[i].first;
bool fReachedTarget = false;
for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
{
- for (int i = 0; i < vValue.size(); i++)
+ for (unsigned int i = 0; i < vValue.size(); i++)
{
if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
{
nValueRet += coinLowestLarger.first;
}
else {
- for (int i = 0; i < vValue.size(); i++)
+ for (unsigned int i = 0; i < vValue.size(); i++)
if (vfBest[i])
{
setCoinsRet.insert(vValue[i].second);
//// debug print
printf("SelectCoins() best subset: ");
- for (int i = 0; i < vValue.size(); i++)
+ for (unsigned int i = 0; i < vValue.size(); i++)
if (vfBest[i])
printf("%s ", FormatMoney(vValue[i].first).c_str());
printf("total %s\n", FormatMoney(nBest).c_str());
return false;
fFirstRunRet = false;
int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
+ if (nLoadWalletRet == DB_NEED_REWRITE)
+ {
+ if (CDB::Rewrite(strWalletFile, "\x04pool"))
+ {
+ setKeyPool.clear();
+ // Note: can't top-up keypool here, because wallet is locked.
+ // User will be prompted to unlock wallet the next operation
+ // the requires a new key.
+ }
+ nLoadWalletRet = DB_NEED_REWRITE;
+ }
+
if (nLoadWalletRet != DB_LOAD_OK)
return nLoadWalletRet;
fFirstRunRet = vchDefaultKey.empty();
return true;
}
+//
+// Mark old keypool keys as used,
+// and generate all new keys
+//
+bool CWallet::NewKeyPool()
+{
+ CRITICAL_BLOCK(cs_wallet)
+ {
+ CWalletDB walletdb(strWalletFile);
+ BOOST_FOREACH(int64 nIndex, setKeyPool)
+ walletdb.ErasePool(nIndex);
+ setKeyPool.clear();
+
+ if (IsLocked())
+ return false;
+
+ int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
+ for (int i = 0; i < nKeys; i++)
+ {
+ int64 nIndex = i+1;
+ walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
+ setKeyPool.insert(nIndex);
+ }
+ printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
+ }
+ return true;
+}
+
bool CWallet::TopUpKeyPool()
{
CRITICAL_BLOCK(cs_wallet)