1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
13 //////////////////////////////////////////////////////////////////////////////
18 std::vector<unsigned char> CWallet::GenerateNewKey()
20 bool fCompressed = true; // default to compressed public keys
24 key.MakeNewKey(fCompressed);
26 // Compressed public keys were introduced in version 0.6.0
31 throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
32 return key.GetPubKey();
35 bool CWallet::AddKey(const CKey& key)
37 if (!CCryptoKeyStore::AddKey(key))
42 return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey());
46 bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
48 if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
52 CRITICAL_BLOCK(cs_wallet)
54 if (pwalletdbEncryption)
55 return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
57 return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
62 bool CWallet::AddCScript(const CScript& redeemScript)
64 if (!CCryptoKeyStore::AddCScript(redeemScript))
68 return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
71 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
77 CKeyingMaterial vMasterKey;
79 CRITICAL_BLOCK(cs_wallet)
80 BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
82 if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
84 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
86 if (CCryptoKeyStore::Unlock(vMasterKey))
92 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
94 bool fWasLocked = IsLocked();
96 CRITICAL_BLOCK(cs_wallet)
101 CKeyingMaterial vMasterKey;
102 BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
104 if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
106 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
108 if (CCryptoKeyStore::Unlock(vMasterKey))
110 int64 nStartTime = GetTimeMillis();
111 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
112 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
114 nStartTime = GetTimeMillis();
115 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
116 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
118 if (pMasterKey.second.nDeriveIterations < 25000)
119 pMasterKey.second.nDeriveIterations = 25000;
121 printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
123 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
125 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
127 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
139 // This class implements an addrIncoming entry that causes pre-0.4
140 // clients to crash on startup if reading a private-key-encrypted wallet.
141 class CCorruptAddress
146 if (nType & SER_DISK)
151 bool CWallet::SetMinVersion(int nVersion, CWalletDB* pwalletdbIn)
153 if (nWalletVersion >= nVersion)
156 nWalletVersion = nVersion;
160 CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
161 if (nWalletVersion >= 40000)
163 // Versions prior to 0.4.0 did not support the "minversion" record.
164 // Use a CCorruptAddress to make them crash instead.
165 CCorruptAddress corruptAddress;
166 pwalletdb->WriteSetting("addrIncoming", corruptAddress);
168 if (nWalletVersion > 40000)
169 pwalletdb->WriteMinVersion(nWalletVersion);
177 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
182 CKeyingMaterial vMasterKey;
183 RandAddSeedPerfmon();
185 vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
186 RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
188 CMasterKey kMasterKey;
190 RandAddSeedPerfmon();
191 kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
192 RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
195 int64 nStartTime = GetTimeMillis();
196 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
197 kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
199 nStartTime = GetTimeMillis();
200 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
201 kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
203 if (kMasterKey.nDeriveIterations < 25000)
204 kMasterKey.nDeriveIterations = 25000;
206 printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
208 if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
210 if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
213 CRITICAL_BLOCK(cs_wallet)
215 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
218 pwalletdbEncryption = new CWalletDB(strWalletFile);
219 pwalletdbEncryption->TxnBegin();
220 pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
223 if (!EncryptKeys(vMasterKey))
226 pwalletdbEncryption->TxnAbort();
227 exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet.
230 // Encryption was introduced in version 0.4.0
231 SetMinVersion(40000, pwalletdbEncryption);
235 if (!pwalletdbEncryption->TxnCommit())
236 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.
238 delete pwalletdbEncryption;
239 pwalletdbEncryption = NULL;
243 Unlock(strWalletPassphrase);
247 // Need to completely rewrite the wallet file; if we don't, bdb might keep
248 // bits of the unencrypted private key in slack space in the database file.
249 CDB::Rewrite(strWalletFile);
255 void CWallet::WalletUpdateSpent(const CTransaction &tx)
257 // Anytime a signature is successfully verified, it's proof the outpoint is spent.
258 // Update the wallet spent flag if it doesn't know due to wallet.dat being
259 // restored from backup or the user making copies of wallet.dat.
260 CRITICAL_BLOCK(cs_wallet)
262 BOOST_FOREACH(const CTxIn& txin, tx.vin)
264 map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
265 if (mi != mapWallet.end())
267 CWalletTx& wtx = (*mi).second;
268 if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
270 printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
271 wtx.MarkSpent(txin.prevout.n);
273 vWalletUpdated.push_back(txin.prevout.hash);
280 void CWallet::MarkDirty()
282 CRITICAL_BLOCK(cs_wallet)
284 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
285 item.second.MarkDirty();
289 bool CWallet::AddToWallet(const CWalletTx& wtxIn)
291 uint256 hash = wtxIn.GetHash();
292 CRITICAL_BLOCK(cs_wallet)
294 // Inserts only if not already there, returns tx inserted or tx found
295 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
296 CWalletTx& wtx = (*ret.first).second;
297 wtx.BindWallet(this);
298 bool fInsertedNew = ret.second;
300 wtx.nTimeReceived = GetAdjustedTime();
302 bool fUpdated = false;
306 if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
308 wtx.hashBlock = wtxIn.hashBlock;
311 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
313 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
314 wtx.nIndex = wtxIn.nIndex;
317 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
319 wtx.fFromMe = wtxIn.fFromMe;
322 fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
326 printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
329 if (fInsertedNew || fUpdated)
330 if (!wtx.WriteToDisk())
333 // If default receiving address gets used, replace it with a new one
334 CScript scriptDefaultKey;
335 scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
336 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
338 if (txout.scriptPubKey == scriptDefaultKey)
340 std::vector<unsigned char> newDefaultKey;
341 if (GetKeyFromPool(newDefaultKey, false))
343 SetDefaultKey(newDefaultKey);
344 SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
350 vWalletUpdated.push_back(hash);
352 // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
353 WalletUpdateSpent(wtx);
361 // Add a transaction to the wallet, or update it.
362 // pblock is optional, but should be provided if the transaction is known to be in a block.
363 // If fUpdate is true, existing transactions will be updated.
364 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
366 uint256 hash = tx.GetHash();
367 CRITICAL_BLOCK(cs_wallet)
369 bool fExisted = mapWallet.count(hash);
370 if (fExisted && !fUpdate) return false;
371 if (fExisted || IsMine(tx) || IsFromMe(tx))
373 CWalletTx wtx(this,tx);
374 // Get merkle branch if transaction was found in a block
376 wtx.SetMerkleBranch(pblock);
377 return AddToWallet(wtx);
380 WalletUpdateSpent(tx);
385 bool CWallet::EraseFromWallet(uint256 hash)
389 CRITICAL_BLOCK(cs_wallet)
391 if (mapWallet.erase(hash))
392 CWalletDB(strWalletFile).EraseTx(hash);
398 bool CWallet::IsMine(const CTxIn &txin) const
400 CRITICAL_BLOCK(cs_wallet)
402 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
403 if (mi != mapWallet.end())
405 const CWalletTx& prev = (*mi).second;
406 if (txin.prevout.n < prev.vout.size())
407 if (IsMine(prev.vout[txin.prevout.n]))
414 int64 CWallet::GetDebit(const CTxIn &txin) const
416 CRITICAL_BLOCK(cs_wallet)
418 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
419 if (mi != mapWallet.end())
421 const CWalletTx& prev = (*mi).second;
422 if (txin.prevout.n < prev.vout.size())
423 if (IsMine(prev.vout[txin.prevout.n]))
424 return prev.vout[txin.prevout.n].nValue;
430 bool CWallet::IsChange(const CTxOut& txout) const
432 CBitcoinAddress address;
434 // TODO: fix handling of 'change' outputs. The assumption is that any
435 // payment to a TX_PUBKEYHASH that is mine but isn't in the address book
436 // is change. That assumption is likely to break when we implement multisignature
437 // wallets that return change back into a multi-signature-protected address;
438 // a better way of identifying which outputs are 'the send' and which are
439 // 'the change' will need to be implemented (maybe extend CWalletTx to remember
440 // which output, if any, was change).
441 if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
442 CRITICAL_BLOCK(cs_wallet)
443 if (!mapAddressBook.count(address))
448 int64 CWalletTx::GetTxTime() const
450 return nTimeReceived;
453 int CWalletTx::GetRequestCount() const
455 // Returns -1 if it wasn't being tracked
457 CRITICAL_BLOCK(pwallet->cs_wallet)
464 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
465 if (mi != pwallet->mapRequestCount.end())
466 nRequests = (*mi).second;
471 // Did anyone request this transaction?
472 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
473 if (mi != pwallet->mapRequestCount.end())
475 nRequests = (*mi).second;
477 // How about the block it's in?
478 if (nRequests == 0 && hashBlock != 0)
480 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
481 if (mi != pwallet->mapRequestCount.end())
482 nRequests = (*mi).second;
484 nRequests = 1; // If it's in someone else's block it must have got out
492 void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived,
493 list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const
495 nGeneratedImmature = nGeneratedMature = nFee = 0;
496 listReceived.clear();
498 strSentAccount = strFromAccount;
502 if (GetBlocksToMaturity() > 0)
503 nGeneratedImmature = pwallet->GetCredit(*this);
505 nGeneratedMature = GetCredit();
510 int64 nDebit = GetDebit();
511 if (nDebit > 0) // debit>0 means we signed/sent this transaction
513 int64 nValueOut = GetValueOut();
514 nFee = nDebit - nValueOut;
518 BOOST_FOREACH(const CTxOut& txout, vout)
520 CBitcoinAddress address;
521 vector<unsigned char> vchPubKey;
522 if (!ExtractAddress(txout.scriptPubKey, address))
524 printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
525 this->GetHash().ToString().c_str());
526 address = " unknown ";
529 // Don't report 'change' txouts
530 if (nDebit > 0 && pwallet->IsChange(txout))
534 listSent.push_back(make_pair(address, txout.nValue));
536 if (pwallet->IsMine(txout))
537 listReceived.push_back(make_pair(address, txout.nValue));
542 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
543 int64& nSent, int64& nFee) const
545 nGenerated = nReceived = nSent = nFee = 0;
547 int64 allGeneratedImmature, allGeneratedMature, allFee;
548 allGeneratedImmature = allGeneratedMature = allFee = 0;
549 string strSentAccount;
550 list<pair<CBitcoinAddress, int64> > listReceived;
551 list<pair<CBitcoinAddress, int64> > listSent;
552 GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
554 if (strAccount == "")
555 nGenerated = allGeneratedMature;
556 if (strAccount == strSentAccount)
558 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent)
562 CRITICAL_BLOCK(pwallet->cs_wallet)
564 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
566 if (pwallet->mapAddressBook.count(r.first))
568 map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
569 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
570 nReceived += r.second;
572 else if (strAccount.empty())
574 nReceived += r.second;
580 void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
584 const int COPY_DEPTH = 3;
585 if (SetMerkleBranch() < COPY_DEPTH)
587 vector<uint256> vWorkQueue;
588 BOOST_FOREACH(const CTxIn& txin, vin)
589 vWorkQueue.push_back(txin.prevout.hash);
591 // This critsect is OK because txdb is already open
592 CRITICAL_BLOCK(pwallet->cs_wallet)
594 map<uint256, const CMerkleTx*> mapWalletPrev;
595 set<uint256> setAlreadyDone;
596 for (int i = 0; i < vWorkQueue.size(); i++)
598 uint256 hash = vWorkQueue[i];
599 if (setAlreadyDone.count(hash))
601 setAlreadyDone.insert(hash);
604 map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
605 if (mi != pwallet->mapWallet.end())
608 BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
609 mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
611 else if (mapWalletPrev.count(hash))
613 tx = *mapWalletPrev[hash];
615 else if (!fClient && txdb.ReadDiskTx(hash, tx))
621 printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
625 int nDepth = tx.SetMerkleBranch();
626 vtxPrev.push_back(tx);
628 if (nDepth < COPY_DEPTH)
629 BOOST_FOREACH(const CTxIn& txin, tx.vin)
630 vWorkQueue.push_back(txin.prevout.hash);
635 reverse(vtxPrev.begin(), vtxPrev.end());
638 bool CWalletTx::WriteToDisk()
640 return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
643 // Scan the block chain (starting in pindexStart) for transactions
644 // from or to us. If fUpdate is true, found transactions that already
645 // exist in the wallet will be updated.
646 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
650 CBlockIndex* pindex = pindexStart;
651 CRITICAL_BLOCK(cs_wallet)
656 block.ReadFromDisk(pindex, true);
657 BOOST_FOREACH(CTransaction& tx, block.vtx)
659 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
662 pindex = pindex->pnext;
668 int CWallet::ScanForWalletTransaction(const uint256& hashTx)
671 tx.ReadFromDisk(COutPoint(hashTx, 0));
672 if (AddToWalletIfInvolvingMe(tx, NULL, true, true))
677 void CWallet::ReacceptWalletTransactions()
681 while (fRepeat) CRITICAL_BLOCK(cs_wallet)
684 vector<CDiskTxPos> vMissingTx;
685 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
687 CWalletTx& wtx = item.second;
688 if (wtx.IsCoinBase() && wtx.IsSpent(0))
692 bool fUpdated = false;
693 if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
695 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
696 if (txindex.vSpent.size() != wtx.vout.size())
698 printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
701 for (int i = 0; i < txindex.vSpent.size(); i++)
705 if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i]))
709 vMissingTx.push_back(txindex.vSpent[i]);
714 printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
721 // Reaccept any txes of ours that aren't already in a block
722 if (!wtx.IsCoinBase())
723 wtx.AcceptWalletTransaction(txdb, false);
726 if (!vMissingTx.empty())
728 // TODO: optimize this to scan just part of the block chain?
729 if (ScanForWalletTransactions(pindexGenesisBlock))
730 fRepeat = true; // Found missing transactions: re-do Reaccept.
735 void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
737 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
739 if (!tx.IsCoinBase())
741 uint256 hash = tx.GetHash();
742 if (!txdb.ContainsTx(hash))
743 RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
748 uint256 hash = GetHash();
749 if (!txdb.ContainsTx(hash))
751 printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
752 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
757 void CWalletTx::RelayWalletTransaction()
760 RelayWalletTransaction(txdb);
763 void CWallet::ResendWalletTransactions()
765 // Do this infrequently and randomly to avoid giving away
766 // that these are our transactions.
767 static int64 nNextTime;
768 if (GetTime() < nNextTime)
770 bool fFirst = (nNextTime == 0);
771 nNextTime = GetTime() + GetRand(30 * 60);
775 // Only do it if there's been a new block since last time
776 static int64 nLastTime;
777 if (nTimeBestReceived < nLastTime)
779 nLastTime = GetTime();
781 // Rebroadcast any of our txes that aren't in a block yet
782 printf("ResendWalletTransactions()\n");
784 CRITICAL_BLOCK(cs_wallet)
786 // Sort them in chronological order
787 multimap<unsigned int, CWalletTx*> mapSorted;
788 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
790 CWalletTx& wtx = item.second;
791 // Don't rebroadcast until it's had plenty of time that
792 // it should have gotten in already by now.
793 if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
794 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
796 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
798 CWalletTx& wtx = *item.second;
799 wtx.RelayWalletTransaction(txdb);
809 //////////////////////////////////////////////////////////////////////////////
815 int64 CWallet::GetBalance() const
818 CRITICAL_BLOCK(cs_wallet)
820 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
822 const CWalletTx* pcoin = &(*it).second;
823 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
825 nTotal += pcoin->GetAvailableCredit();
832 int64 CWallet::GetUnconfirmedBalance() const
835 CRITICAL_BLOCK(cs_wallet)
837 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
839 const CWalletTx* pcoin = &(*it).second;
840 if (pcoin->IsFinal() && pcoin->IsConfirmed())
842 nTotal += pcoin->GetAvailableCredit();
848 bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
853 // List of values less than target
854 pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
855 coinLowestLarger.first = std::numeric_limits<int64>::max();
856 coinLowestLarger.second.first = NULL;
857 vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
858 int64 nTotalLower = 0;
860 CRITICAL_BLOCK(cs_wallet)
862 vector<const CWalletTx*> vCoins;
863 vCoins.reserve(mapWallet.size());
864 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
865 vCoins.push_back(&(*it).second);
866 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
868 BOOST_FOREACH(const CWalletTx* pcoin, vCoins)
870 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
873 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
876 int nDepth = pcoin->GetDepthInMainChain();
877 if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
880 for (int i = 0; i < pcoin->vout.size(); i++)
882 if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]))
885 int64 n = pcoin->vout[i].nValue;
890 pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin,i));
892 if (n == nTargetValue)
894 setCoinsRet.insert(coin.second);
895 nValueRet += coin.first;
898 else if (n < nTargetValue + CENT)
900 vValue.push_back(coin);
903 else if (n < coinLowestLarger.first)
905 coinLowestLarger = coin;
911 if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
913 for (int i = 0; i < vValue.size(); ++i)
915 setCoinsRet.insert(vValue[i].second);
916 nValueRet += vValue[i].first;
921 if (nTotalLower < nTargetValue + (coinLowestLarger.second.first ? CENT : 0))
923 if (coinLowestLarger.second.first == NULL)
925 setCoinsRet.insert(coinLowestLarger.second);
926 nValueRet += coinLowestLarger.first;
930 if (nTotalLower >= nTargetValue + CENT)
931 nTargetValue += CENT;
933 // Solve subset sum by stochastic approximation
934 sort(vValue.rbegin(), vValue.rend());
935 vector<char> vfIncluded;
936 vector<char> vfBest(vValue.size(), true);
937 int64 nBest = nTotalLower;
939 for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
941 vfIncluded.assign(vValue.size(), false);
943 bool fReachedTarget = false;
944 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
946 for (int i = 0; i < vValue.size(); i++)
948 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
950 nTotal += vValue[i].first;
951 vfIncluded[i] = true;
952 if (nTotal >= nTargetValue)
954 fReachedTarget = true;
960 nTotal -= vValue[i].first;
961 vfIncluded[i] = false;
968 // If the next larger is still closer, return it
969 if (coinLowestLarger.second.first && coinLowestLarger.first - nTargetValue <= nBest - nTargetValue)
971 setCoinsRet.insert(coinLowestLarger.second);
972 nValueRet += coinLowestLarger.first;
975 for (int i = 0; i < vValue.size(); i++)
978 setCoinsRet.insert(vValue[i].second);
979 nValueRet += vValue[i].first;
983 printf("SelectCoins() best subset: ");
984 for (int i = 0; i < vValue.size(); i++)
986 printf("%s ", FormatMoney(vValue[i].first).c_str());
987 printf("total %s\n", FormatMoney(nBest).c_str());
993 bool CWallet::SelectCoins(int64 nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
995 return (SelectCoinsMinConf(nTargetValue, 1, 6, setCoinsRet, nValueRet) ||
996 SelectCoinsMinConf(nTargetValue, 1, 1, setCoinsRet, nValueRet) ||
997 SelectCoinsMinConf(nTargetValue, 0, 1, setCoinsRet, nValueRet));
1003 bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
1006 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1012 if (vecSend.empty() || nValue < 0)
1015 wtxNew.BindWallet(this);
1017 CRITICAL_BLOCK(cs_main)
1018 CRITICAL_BLOCK(cs_wallet)
1020 // txdb must be opened before the mapWallet lock
1023 nFeeRet = nTransactionFee;
1027 wtxNew.vout.clear();
1028 wtxNew.fFromMe = true;
1030 int64 nTotalValue = nValue + nFeeRet;
1031 double dPriority = 0;
1032 // vouts to the payees
1033 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1034 wtxNew.vout.push_back(CTxOut(s.second, s.first));
1036 // Choose coins to use
1037 set<pair<const CWalletTx*,unsigned int> > setCoins;
1039 if (!SelectCoins(nTotalValue, setCoins, nValueIn))
1041 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1043 int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
1044 dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
1047 int64 nChange = nValueIn - nValue - nFeeRet;
1048 // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
1049 // or until nChange becomes zero
1050 // NOTE: this depends on the exact behaviour of GetMinFee
1051 if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
1053 int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
1054 nChange -= nMoveToFee;
1055 nFeeRet += nMoveToFee;
1060 // Note: We use a new key here to keep it from being obvious which side is the change.
1061 // The drawback is that by not reusing a previous key, the change may be lost if a
1062 // backup is restored, if the backup doesn't have the new private key for the change.
1063 // If we reused the old key, it would be possible to add code to look for and
1064 // rediscover unknown transactions that were written with keys of ours to recover
1065 // post-backup change.
1067 // Reserve a new key pair from key pool
1068 vector<unsigned char> vchPubKey = reservekey.GetReservedKey();
1069 // assert(mapKeys.count(vchPubKey));
1071 // Fill a vout to ourself
1072 // TODO: pass in scriptChange instead of reservekey so
1073 // change transaction isn't always pay-to-bitcoin-address
1074 CScript scriptChange;
1075 scriptChange.SetBitcoinAddress(vchPubKey);
1077 // Insert change txn at random position:
1078 vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
1079 wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
1082 reservekey.ReturnKey();
1085 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1086 wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
1090 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1091 if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
1095 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
1096 if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
1098 dPriority /= nBytes;
1100 // Check that enough fee is included
1101 int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
1102 bool fAllowFree = CTransaction::AllowFree(dPriority);
1103 int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND);
1104 if (nFeeRet < max(nPayFee, nMinFee))
1106 nFeeRet = max(nPayFee, nMinFee);
1110 // Fill vtxPrev by copying from previous transactions vtxPrev
1111 wtxNew.AddSupportingTransactions(txdb);
1112 wtxNew.fTimeReceivedIsTxTime = true;
1121 bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
1123 vector< pair<CScript, int64> > vecSend;
1124 vecSend.push_back(make_pair(scriptPubKey, nValue));
1125 return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet);
1128 // Call after CreateTransaction unless you want to abort
1129 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
1131 CRITICAL_BLOCK(cs_main)
1132 CRITICAL_BLOCK(cs_wallet)
1134 printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
1136 // This is only to keep the database open to defeat the auto-flush for the
1137 // duration of this scope. This is the only place where this optimization
1138 // maybe makes sense; please don't do it anywhere else.
1139 CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
1141 // Take key pair from key pool so it won't be used again
1142 reservekey.KeepKey();
1144 // Add tx to wallet, because if it has change it's also ours,
1145 // otherwise just for transaction history.
1146 AddToWallet(wtxNew);
1148 // Mark old coins as spent
1149 set<CWalletTx*> setCoins;
1150 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
1152 CWalletTx &coin = mapWallet[txin.prevout.hash];
1153 coin.BindWallet(this);
1154 coin.MarkSpent(txin.prevout.n);
1156 vWalletUpdated.push_back(coin.GetHash());
1163 // Track how many getdata requests our transaction gets
1164 mapRequestCount[wtxNew.GetHash()] = 0;
1167 if (!wtxNew.AcceptToMemoryPool())
1169 // This must not fail. The transaction has already been signed and recorded.
1170 printf("CommitTransaction() : Error: Transaction not valid");
1173 wtxNew.RelayWalletTransaction();
1182 string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
1184 CReserveKey reservekey(this);
1189 string strError = _("Error: Wallet locked, unable to create transaction ");
1190 printf("SendMoney() : %s", strError.c_str());
1193 if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
1196 if (nValue + nFeeRequired > GetBalance())
1197 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());
1199 strError = _("Error: Transaction creation failed ");
1200 printf("SendMoney() : %s", strError.c_str());
1204 if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
1207 if (!CommitTransaction(wtxNew, reservekey))
1208 return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
1216 string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
1220 return _("Invalid amount");
1221 if (nValue + nTransactionFee > GetBalance())
1222 return _("Insufficient funds");
1224 // Parse bitcoin address
1225 CScript scriptPubKey;
1226 scriptPubKey.SetBitcoinAddress(address);
1228 return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
1234 int CWallet::LoadWallet(bool& fFirstRunRet)
1238 fFirstRunRet = false;
1239 int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
1240 if (nLoadWalletRet == DB_NEED_REWRITE)
1242 if (CDB::Rewrite(strWalletFile, "\x04pool"))
1245 // Note: can't top-up keypool here, because wallet is locked.
1246 // User will be prompted to unlock wallet the next operation
1247 // the requires a new key.
1249 nLoadWalletRet = DB_NEED_REWRITE;
1252 if (nLoadWalletRet != DB_LOAD_OK)
1253 return nLoadWalletRet;
1254 fFirstRunRet = vchDefaultKey.empty();
1256 if (!HaveKey(Hash160(vchDefaultKey)))
1258 // Create new keyUser and set as default key
1259 RandAddSeedPerfmon();
1261 std::vector<unsigned char> newDefaultKey;
1262 if (!GetKeyFromPool(newDefaultKey, false))
1263 return DB_LOAD_FAIL;
1264 SetDefaultKey(newDefaultKey);
1265 if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""))
1266 return DB_LOAD_FAIL;
1269 CreateThread(ThreadFlushWalletDB, &strWalletFile);
1274 bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
1276 mapAddressBook[address] = strName;
1279 return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
1282 bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
1284 mapAddressBook.erase(address);
1287 return CWalletDB(strWalletFile).EraseName(address.ToString());
1291 void CWallet::PrintWallet(const CBlock& block)
1293 CRITICAL_BLOCK(cs_wallet)
1295 if (mapWallet.count(block.vtx[0].GetHash()))
1297 CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
1298 printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
1304 bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
1306 CRITICAL_BLOCK(cs_wallet)
1308 map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
1309 if (mi != mapWallet.end())
1318 bool CWallet::SetDefaultKey(const std::vector<unsigned char> &vchPubKey)
1322 if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
1325 vchDefaultKey = vchPubKey;
1329 bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
1331 if (!pwallet->fFileBacked)
1333 strWalletFileOut = pwallet->strWalletFile;
1338 // Mark old keypool keys as used,
1339 // and generate all new keys
1341 bool CWallet::NewKeyPool()
1343 CRITICAL_BLOCK(cs_wallet)
1345 CWalletDB walletdb(strWalletFile);
1346 BOOST_FOREACH(int64 nIndex, setKeyPool)
1347 walletdb.ErasePool(nIndex);
1353 int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
1354 for (int i = 0; i < nKeys; i++)
1357 walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
1358 setKeyPool.insert(nIndex);
1360 printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
1365 bool CWallet::TopUpKeyPool()
1367 CRITICAL_BLOCK(cs_wallet)
1372 CWalletDB walletdb(strWalletFile);
1375 int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
1376 while (setKeyPool.size() < nTargetSize+1)
1379 if (!setKeyPool.empty())
1380 nEnd = *(--setKeyPool.end()) + 1;
1381 if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
1382 throw runtime_error("TopUpKeyPool() : writing generated key failed");
1383 setKeyPool.insert(nEnd);
1384 printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
1390 void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
1393 keypool.vchPubKey.clear();
1394 CRITICAL_BLOCK(cs_wallet)
1399 // Get the oldest key
1400 if(setKeyPool.empty())
1403 CWalletDB walletdb(strWalletFile);
1405 nIndex = *(setKeyPool.begin());
1406 setKeyPool.erase(setKeyPool.begin());
1407 if (!walletdb.ReadPool(nIndex, keypool))
1408 throw runtime_error("ReserveKeyFromKeyPool() : read failed");
1409 if (!HaveKey(Hash160(keypool.vchPubKey)))
1410 throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
1411 assert(!keypool.vchPubKey.empty());
1412 printf("keypool reserve %"PRI64d"\n", nIndex);
1416 int64 CWallet::AddReserveKey(const CKeyPool& keypool)
1418 CRITICAL_BLOCK(cs_main)
1419 CRITICAL_BLOCK(cs_wallet)
1421 CWalletDB walletdb(strWalletFile);
1423 int64 nIndex = 1 + *(--setKeyPool.end());
1424 if (!walletdb.WritePool(nIndex, keypool))
1425 throw runtime_error("AddReserveKey() : writing added key failed");
1426 setKeyPool.insert(nIndex);
1432 void CWallet::KeepKey(int64 nIndex)
1434 // Remove from key pool
1437 CWalletDB walletdb(strWalletFile);
1438 walletdb.ErasePool(nIndex);
1440 printf("keypool keep %"PRI64d"\n", nIndex);
1443 void CWallet::ReturnKey(int64 nIndex)
1445 // Return to key pool
1446 CRITICAL_BLOCK(cs_wallet)
1447 setKeyPool.insert(nIndex);
1448 printf("keypool return %"PRI64d"\n", nIndex);
1451 bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
1455 CRITICAL_BLOCK(cs_wallet)
1457 ReserveKeyFromKeyPool(nIndex, keypool);
1460 if (fAllowReuse && !vchDefaultKey.empty())
1462 result = vchDefaultKey;
1465 if (IsLocked()) return false;
1466 result = GenerateNewKey();
1470 result = keypool.vchPubKey;
1475 int64 CWallet::GetOldestKeyPoolTime()
1479 ReserveKeyFromKeyPool(nIndex, keypool);
1483 return keypool.nTime;
1486 vector<unsigned char> CReserveKey::GetReservedKey()
1491 pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
1493 vchPubKey = keypool.vchPubKey;
1496 printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool.");
1497 vchPubKey = pwallet->vchDefaultKey;
1500 assert(!vchPubKey.empty());
1504 void CReserveKey::KeepKey()
1507 pwallet->KeepKey(nIndex);
1512 void CReserveKey::ReturnKey()
1515 pwallet->ReturnKey(nIndex);
1520 void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
1524 CWalletDB walletdb(strWalletFile);
1526 CRITICAL_BLOCK(cs_main)
1527 CRITICAL_BLOCK(cs_wallet)
1528 BOOST_FOREACH(const int64& id, setKeyPool)
1531 if (!walletdb.ReadPool(id, keypool))
1532 throw runtime_error("GetAllReserveKeyHashes() : read failed");
1533 CBitcoinAddress address(keypool.vchPubKey);
1534 assert(!keypool.vchPubKey.empty());
1535 if (!HaveKey(address))
1536 throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
1537 setAddress.insert(address);