X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=3ffad27e82db00c10e33b017cc22dee786fe78d9;hb=3b36da6d277c6f5ad671343e724e0336ce55c893;hp=298a2c64288c171c5b2e8bfd860886b0bdeda514;hpb=ef4280e08b217bf2512bb1878e1dd2a926e557c9;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 298a2c6..3ffad27 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1,11 +1,10 @@ // 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; @@ -43,7 +42,7 @@ bool CWallet::AddCryptedKey(const vector &vchPubKey, const vector return false; } -bool CWallet::Unlock(const string& strWalletPassphrase) +bool CWallet::Unlock(const SecureString& strWalletPassphrase) { if (!IsLocked()) return false; @@ -64,7 +63,7 @@ bool CWallet::Unlock(const string& strWalletPassphrase) return false; } -bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase) +bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase) { bool fWasLocked = IsLocked(); @@ -123,7 +122,7 @@ public: ) }; -bool CWallet::EncryptWallet(const string& strWalletPassphrase) +bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) { if (IsCrypted()) return false; @@ -165,7 +164,8 @@ bool CWallet::EncryptWallet(const string& strWalletPassphrase) if (fFileBacked) { pwalletdbEncryption = new CWalletDB(strWalletFile); - pwalletdbEncryption->TxnBegin(); + if (!pwalletdbEncryption->TxnBegin()) + return false; pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); } @@ -183,11 +183,18 @@ bool CWallet::EncryptWallet(const string& strWalletPassphrase) 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; @@ -261,7 +268,7 @@ bool CWallet::AddToWallet(const CWalletTx& 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); @@ -277,7 +284,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) } } } - +#endif // Notify UI vWalletUpdated.push_back(hash); @@ -290,6 +297,9 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) 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(); @@ -505,7 +515,7 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) { map mapWalletPrev; set 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)) @@ -538,8 +548,10 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) vtxPrev.push_back(tx); if (nDepth < COPY_DEPTH) + { BOOST_FOREACH(const CTxIn& txin, tx.vin) vWorkQueue.push_back(txin.prevout.hash); + } } } } @@ -552,6 +564,9 @@ bool CWalletTx::WriteToDisk() 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; @@ -598,7 +613,7 @@ void CWallet::ReacceptWalletTransactions() 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; @@ -729,6 +744,21 @@ int64 CWallet::GetBalance() const return nTotal; } +int64 CWallet::GetUnconfirmedBalance() const +{ + int64 nTotal = 0; + CRITICAL_BLOCK(cs_wallet) + { + for (map::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 >& setCoinsRet, int64& nValueRet) const { @@ -762,7 +792,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe 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; @@ -795,7 +825,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe 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; @@ -828,7 +858,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe 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]) { @@ -857,7 +887,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe 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); @@ -866,7 +896,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe //// 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()); @@ -1122,6 +1152,18 @@ int CWallet::LoadWallet(bool& fFirstRunRet) 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(); @@ -1207,6 +1249,34 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) 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)