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.
12 //////////////////////////////////////////////////////////////////////////////
17 std::vector<unsigned char> CWallet::GenerateNewKey()
19 bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
23 key.MakeNewKey(fCompressed);
25 // Compressed public keys were introduced in version 0.6.0
27 SetMinVersion(FEATURE_COMPRPUBKEY);
30 throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
31 return key.GetPubKey();
34 bool CWallet::AddKey(const CKey& key)
36 if (!CCryptoKeyStore::AddKey(key))
41 return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey());
45 bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
47 if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
53 if (pwalletdbEncryption)
54 return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
56 return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
61 bool CWallet::AddCScript(const CScript& redeemScript)
63 if (!CCryptoKeyStore::AddCScript(redeemScript))
67 return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
70 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
76 CKeyingMaterial vMasterKey;
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))
93 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
95 bool fWasLocked = IsLocked();
102 CKeyingMaterial vMasterKey;
103 BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
105 if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
107 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
109 if (CCryptoKeyStore::Unlock(vMasterKey))
111 int64 nStartTime = GetTimeMillis();
112 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
113 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
115 nStartTime = GetTimeMillis();
116 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
117 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
119 if (pMasterKey.second.nDeriveIterations < 25000)
120 pMasterKey.second.nDeriveIterations = 25000;
122 printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
124 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
126 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
128 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
139 void CWallet::SetBestChain(const CBlockLocator& loc)
141 CWalletDB walletdb(strWalletFile);
142 walletdb.WriteBestBlock(loc);
145 // This class implements an addrIncoming entry that causes pre-0.4
146 // clients to crash on startup if reading a private-key-encrypted wallet.
147 class CCorruptAddress
152 if (nType & SER_DISK)
157 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
159 if (nWalletVersion >= nVersion)
162 // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
163 if (fExplicit && nVersion > nWalletMaxVersion)
164 nVersion = FEATURE_LATEST;
166 nWalletVersion = nVersion;
168 if (nVersion > nWalletMaxVersion)
169 nWalletMaxVersion = nVersion;
173 CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
174 if (nWalletVersion >= 40000)
176 // Versions prior to 0.4.0 did not support the "minversion" record.
177 // Use a CCorruptAddress to make them crash instead.
178 CCorruptAddress corruptAddress;
179 pwalletdb->WriteSetting("addrIncoming", corruptAddress);
181 if (nWalletVersion > 40000)
182 pwalletdb->WriteMinVersion(nWalletVersion);
190 bool CWallet::SetMaxVersion(int nVersion)
192 // cannot downgrade below current version
193 if (nWalletVersion > nVersion)
196 nWalletMaxVersion = nVersion;
201 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
206 CKeyingMaterial vMasterKey;
207 RandAddSeedPerfmon();
209 vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
210 RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
212 CMasterKey kMasterKey;
214 RandAddSeedPerfmon();
215 kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
216 RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
219 int64 nStartTime = GetTimeMillis();
220 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
221 kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
223 nStartTime = GetTimeMillis();
224 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
225 kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
227 if (kMasterKey.nDeriveIterations < 25000)
228 kMasterKey.nDeriveIterations = 25000;
230 printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
232 if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
234 if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
239 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
242 pwalletdbEncryption = new CWalletDB(strWalletFile);
243 pwalletdbEncryption->TxnBegin();
244 pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
247 if (!EncryptKeys(vMasterKey))
250 pwalletdbEncryption->TxnAbort();
251 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.
254 // Encryption was introduced in version 0.4.0
255 SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
259 if (!pwalletdbEncryption->TxnCommit())
260 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.
262 delete pwalletdbEncryption;
263 pwalletdbEncryption = NULL;
267 Unlock(strWalletPassphrase);
271 // Need to completely rewrite the wallet file; if we don't, bdb might keep
272 // bits of the unencrypted private key in slack space in the database file.
273 CDB::Rewrite(strWalletFile);
279 void CWallet::WalletUpdateSpent(const CTransaction &tx)
281 // Anytime a signature is successfully verified, it's proof the outpoint is spent.
282 // Update the wallet spent flag if it doesn't know due to wallet.dat being
283 // restored from backup or the user making copies of wallet.dat.
286 BOOST_FOREACH(const CTxIn& txin, tx.vin)
288 map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
289 if (mi != mapWallet.end())
291 CWalletTx& wtx = (*mi).second;
292 if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
294 printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
295 wtx.MarkSpent(txin.prevout.n);
297 vWalletUpdated.push_back(txin.prevout.hash);
304 void CWallet::MarkDirty()
308 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
309 item.second.MarkDirty();
313 bool CWallet::AddToWallet(const CWalletTx& wtxIn)
315 uint256 hash = wtxIn.GetHash();
318 // Inserts only if not already there, returns tx inserted or tx found
319 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
320 CWalletTx& wtx = (*ret.first).second;
321 wtx.BindWallet(this);
322 bool fInsertedNew = ret.second;
324 wtx.nTimeReceived = GetAdjustedTime();
326 bool fUpdated = false;
330 if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
332 wtx.hashBlock = wtxIn.hashBlock;
335 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
337 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
338 wtx.nIndex = wtxIn.nIndex;
341 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
343 wtx.fFromMe = wtxIn.fFromMe;
346 fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
350 printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
353 if (fInsertedNew || fUpdated)
354 if (!wtx.WriteToDisk())
357 // If default receiving address gets used, replace it with a new one
358 CScript scriptDefaultKey;
359 scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
360 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
362 if (txout.scriptPubKey == scriptDefaultKey)
364 std::vector<unsigned char> newDefaultKey;
365 if (GetKeyFromPool(newDefaultKey, false))
367 SetDefaultKey(newDefaultKey);
368 SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
374 vWalletUpdated.push_back(hash);
376 // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
377 WalletUpdateSpent(wtx);
385 // Add a transaction to the wallet, or update it.
386 // pblock is optional, but should be provided if the transaction is known to be in a block.
387 // If fUpdate is true, existing transactions will be updated.
388 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
390 uint256 hash = tx.GetHash();
393 bool fExisted = mapWallet.count(hash);
394 if (fExisted && !fUpdate) return false;
395 if (fExisted || IsMine(tx) || IsFromMe(tx))
397 CWalletTx wtx(this,tx);
398 // Get merkle branch if transaction was found in a block
400 wtx.SetMerkleBranch(pblock);
401 return AddToWallet(wtx);
404 WalletUpdateSpent(tx);
409 bool CWallet::EraseFromWallet(uint256 hash)
415 if (mapWallet.erase(hash))
416 CWalletDB(strWalletFile).EraseTx(hash);
422 bool CWallet::IsMine(const CTxIn &txin) const
426 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
427 if (mi != mapWallet.end())
429 const CWalletTx& prev = (*mi).second;
430 if (txin.prevout.n < prev.vout.size())
431 if (IsMine(prev.vout[txin.prevout.n]))
438 int64 CWallet::GetDebit(const CTxIn &txin) const
442 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
443 if (mi != mapWallet.end())
445 const CWalletTx& prev = (*mi).second;
446 if (txin.prevout.n < prev.vout.size())
447 if (IsMine(prev.vout[txin.prevout.n]))
448 return prev.vout[txin.prevout.n].nValue;
454 bool CWallet::IsChange(const CTxOut& txout) const
456 CBitcoinAddress address;
458 // TODO: fix handling of 'change' outputs. The assumption is that any
459 // payment to a TX_PUBKEYHASH that is mine but isn't in the address book
460 // is change. That assumption is likely to break when we implement multisignature
461 // wallets that return change back into a multi-signature-protected address;
462 // a better way of identifying which outputs are 'the send' and which are
463 // 'the change' will need to be implemented (maybe extend CWalletTx to remember
464 // which output, if any, was change).
465 if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
468 if (!mapAddressBook.count(address))
474 int64 CWalletTx::GetTxTime() const
476 return nTimeReceived;
479 int CWalletTx::GetRequestCount() const
481 // Returns -1 if it wasn't being tracked
484 LOCK(pwallet->cs_wallet);
490 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
491 if (mi != pwallet->mapRequestCount.end())
492 nRequests = (*mi).second;
497 // Did anyone request this transaction?
498 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
499 if (mi != pwallet->mapRequestCount.end())
501 nRequests = (*mi).second;
503 // How about the block it's in?
504 if (nRequests == 0 && hashBlock != 0)
506 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
507 if (mi != pwallet->mapRequestCount.end())
508 nRequests = (*mi).second;
510 nRequests = 1; // If it's in someone else's block it must have got out
518 void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived,
519 list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const
521 nGeneratedImmature = nGeneratedMature = nFee = 0;
522 listReceived.clear();
524 strSentAccount = strFromAccount;
528 if (GetBlocksToMaturity() > 0)
529 nGeneratedImmature = pwallet->GetCredit(*this);
531 nGeneratedMature = GetCredit();
536 int64 nDebit = GetDebit();
537 if (nDebit > 0) // debit>0 means we signed/sent this transaction
539 int64 nValueOut = GetValueOut();
540 nFee = nDebit - nValueOut;
544 BOOST_FOREACH(const CTxOut& txout, vout)
546 CBitcoinAddress address;
547 vector<unsigned char> vchPubKey;
548 if (!ExtractAddress(txout.scriptPubKey, address))
550 printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
551 this->GetHash().ToString().c_str());
552 address = " unknown ";
555 // Don't report 'change' txouts
556 if (nDebit > 0 && pwallet->IsChange(txout))
560 listSent.push_back(make_pair(address, txout.nValue));
562 if (pwallet->IsMine(txout))
563 listReceived.push_back(make_pair(address, txout.nValue));
568 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
569 int64& nSent, int64& nFee) const
571 nGenerated = nReceived = nSent = nFee = 0;
573 int64 allGeneratedImmature, allGeneratedMature, allFee;
574 allGeneratedImmature = allGeneratedMature = allFee = 0;
575 string strSentAccount;
576 list<pair<CBitcoinAddress, int64> > listReceived;
577 list<pair<CBitcoinAddress, int64> > listSent;
578 GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
580 if (strAccount == "")
581 nGenerated = allGeneratedMature;
582 if (strAccount == strSentAccount)
584 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent)
589 LOCK(pwallet->cs_wallet);
590 BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
592 if (pwallet->mapAddressBook.count(r.first))
594 map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
595 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
596 nReceived += r.second;
598 else if (strAccount.empty())
600 nReceived += r.second;
606 void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
610 const int COPY_DEPTH = 3;
611 if (SetMerkleBranch() < COPY_DEPTH)
613 vector<uint256> vWorkQueue;
614 BOOST_FOREACH(const CTxIn& txin, vin)
615 vWorkQueue.push_back(txin.prevout.hash);
617 // This critsect is OK because txdb is already open
619 LOCK(pwallet->cs_wallet);
620 map<uint256, const CMerkleTx*> mapWalletPrev;
621 set<uint256> setAlreadyDone;
622 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
624 uint256 hash = vWorkQueue[i];
625 if (setAlreadyDone.count(hash))
627 setAlreadyDone.insert(hash);
630 map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
631 if (mi != pwallet->mapWallet.end())
634 BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
635 mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
637 else if (mapWalletPrev.count(hash))
639 tx = *mapWalletPrev[hash];
641 else if (!fClient && txdb.ReadDiskTx(hash, tx))
647 printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
651 int nDepth = tx.SetMerkleBranch();
652 vtxPrev.push_back(tx);
654 if (nDepth < COPY_DEPTH)
656 BOOST_FOREACH(const CTxIn& txin, tx.vin)
657 vWorkQueue.push_back(txin.prevout.hash);
663 reverse(vtxPrev.begin(), vtxPrev.end());
666 bool CWalletTx::WriteToDisk()
668 return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
671 // Scan the block chain (starting in pindexStart) for transactions
672 // from or to us. If fUpdate is true, found transactions that already
673 // exist in the wallet will be updated.
674 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
678 CBlockIndex* pindex = pindexStart;
684 block.ReadFromDisk(pindex, true);
685 BOOST_FOREACH(CTransaction& tx, block.vtx)
687 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
690 pindex = pindex->pnext;
696 int CWallet::ScanForWalletTransaction(const uint256& hashTx)
699 tx.ReadFromDisk(COutPoint(hashTx, 0));
700 if (AddToWalletIfInvolvingMe(tx, NULL, true, true))
705 void CWallet::ReacceptWalletTransactions()
713 vector<CDiskTxPos> vMissingTx;
714 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
716 CWalletTx& wtx = item.second;
717 if (wtx.IsCoinBase() && wtx.IsSpent(0))
721 bool fUpdated = false;
722 if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
724 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
725 if (txindex.vSpent.size() != wtx.vout.size())
727 printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
730 for (unsigned int i = 0; i < txindex.vSpent.size(); i++)
734 if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i]))
738 vMissingTx.push_back(txindex.vSpent[i]);
743 printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
750 // Reaccept any txes of ours that aren't already in a block
751 if (!wtx.IsCoinBase())
752 wtx.AcceptWalletTransaction(txdb, false);
755 if (!vMissingTx.empty())
757 // TODO: optimize this to scan just part of the block chain?
758 if (ScanForWalletTransactions(pindexGenesisBlock))
759 fRepeat = true; // Found missing transactions: re-do Reaccept.
764 void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
766 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
768 if (!tx.IsCoinBase())
770 uint256 hash = tx.GetHash();
771 if (!txdb.ContainsTx(hash))
772 RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
777 uint256 hash = GetHash();
778 if (!txdb.ContainsTx(hash))
780 printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
781 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
786 void CWalletTx::RelayWalletTransaction()
789 RelayWalletTransaction(txdb);
792 void CWallet::ResendWalletTransactions()
794 // Do this infrequently and randomly to avoid giving away
795 // that these are our transactions.
796 static int64 nNextTime;
797 if (GetTime() < nNextTime)
799 bool fFirst = (nNextTime == 0);
800 nNextTime = GetTime() + GetRand(30 * 60);
804 // Only do it if there's been a new block since last time
805 static int64 nLastTime;
806 if (nTimeBestReceived < nLastTime)
808 nLastTime = GetTime();
810 // Rebroadcast any of our txes that aren't in a block yet
811 printf("ResendWalletTransactions()\n");
815 // Sort them in chronological order
816 multimap<unsigned int, CWalletTx*> mapSorted;
817 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
819 CWalletTx& wtx = item.second;
820 // Don't rebroadcast until it's had plenty of time that
821 // it should have gotten in already by now.
822 if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
823 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
825 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
827 CWalletTx& wtx = *item.second;
828 wtx.RelayWalletTransaction(txdb);
838 //////////////////////////////////////////////////////////////////////////////
844 int64 CWallet::GetBalance() const
849 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
851 const CWalletTx* pcoin = &(*it).second;
852 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
854 nTotal += pcoin->GetAvailableCredit();
861 int64 CWallet::GetUnconfirmedBalance() const
866 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
868 const CWalletTx* pcoin = &(*it).second;
869 if (pcoin->IsFinal() && pcoin->IsConfirmed())
871 nTotal += pcoin->GetAvailableCredit();
877 bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
882 // List of values less than target
883 pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
884 coinLowestLarger.first = std::numeric_limits<int64>::max();
885 coinLowestLarger.second.first = NULL;
886 vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
887 int64 nTotalLower = 0;
891 vector<const CWalletTx*> vCoins;
892 vCoins.reserve(mapWallet.size());
893 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
894 vCoins.push_back(&(*it).second);
895 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
897 BOOST_FOREACH(const CWalletTx* pcoin, vCoins)
899 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
902 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
905 int nDepth = pcoin->GetDepthInMainChain();
906 if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
909 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
911 if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]))
914 int64 n = pcoin->vout[i].nValue;
919 pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin,i));
921 if (n == nTargetValue)
923 setCoinsRet.insert(coin.second);
924 nValueRet += coin.first;
927 else if (n < nTargetValue + CENT)
929 vValue.push_back(coin);
932 else if (n < coinLowestLarger.first)
934 coinLowestLarger = coin;
940 if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
942 for (unsigned int i = 0; i < vValue.size(); ++i)
944 setCoinsRet.insert(vValue[i].second);
945 nValueRet += vValue[i].first;
950 if (nTotalLower < nTargetValue + (coinLowestLarger.second.first ? CENT : 0))
952 if (coinLowestLarger.second.first == NULL)
954 setCoinsRet.insert(coinLowestLarger.second);
955 nValueRet += coinLowestLarger.first;
959 if (nTotalLower >= nTargetValue + CENT)
960 nTargetValue += CENT;
962 // Solve subset sum by stochastic approximation
963 sort(vValue.rbegin(), vValue.rend());
964 vector<char> vfIncluded;
965 vector<char> vfBest(vValue.size(), true);
966 int64 nBest = nTotalLower;
968 for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
970 vfIncluded.assign(vValue.size(), false);
972 bool fReachedTarget = false;
973 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
975 for (unsigned int i = 0; i < vValue.size(); i++)
977 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
979 nTotal += vValue[i].first;
980 vfIncluded[i] = true;
981 if (nTotal >= nTargetValue)
983 fReachedTarget = true;
989 nTotal -= vValue[i].first;
990 vfIncluded[i] = false;
997 // If the next larger is still closer, return it
998 if (coinLowestLarger.second.first && coinLowestLarger.first - nTargetValue <= nBest - nTargetValue)
1000 setCoinsRet.insert(coinLowestLarger.second);
1001 nValueRet += coinLowestLarger.first;
1004 for (unsigned int i = 0; i < vValue.size(); i++)
1007 setCoinsRet.insert(vValue[i].second);
1008 nValueRet += vValue[i].first;
1012 printf("SelectCoins() best subset: ");
1013 for (unsigned int i = 0; i < vValue.size(); i++)
1015 printf("%s ", FormatMoney(vValue[i].first).c_str());
1016 printf("total %s\n", FormatMoney(nBest).c_str());
1022 bool CWallet::SelectCoins(int64 nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
1024 return (SelectCoinsMinConf(nTargetValue, 1, 6, setCoinsRet, nValueRet) ||
1025 SelectCoinsMinConf(nTargetValue, 1, 1, setCoinsRet, nValueRet) ||
1026 SelectCoinsMinConf(nTargetValue, 0, 1, setCoinsRet, nValueRet));
1032 bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
1035 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1041 if (vecSend.empty() || nValue < 0)
1044 wtxNew.BindWallet(this);
1047 LOCK2(cs_main, cs_wallet);
1048 // txdb must be opened before the mapWallet lock
1051 nFeeRet = nTransactionFee;
1055 wtxNew.vout.clear();
1056 wtxNew.fFromMe = true;
1058 int64 nTotalValue = nValue + nFeeRet;
1059 double dPriority = 0;
1060 // vouts to the payees
1061 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1062 wtxNew.vout.push_back(CTxOut(s.second, s.first));
1064 // Choose coins to use
1065 set<pair<const CWalletTx*,unsigned int> > setCoins;
1067 if (!SelectCoins(nTotalValue, setCoins, nValueIn))
1069 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1071 int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
1072 dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
1075 int64 nChange = nValueIn - nValue - nFeeRet;
1076 // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
1077 // or until nChange becomes zero
1078 // NOTE: this depends on the exact behaviour of GetMinFee
1079 if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
1081 int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
1082 nChange -= nMoveToFee;
1083 nFeeRet += nMoveToFee;
1088 // Note: We use a new key here to keep it from being obvious which side is the change.
1089 // The drawback is that by not reusing a previous key, the change may be lost if a
1090 // backup is restored, if the backup doesn't have the new private key for the change.
1091 // If we reused the old key, it would be possible to add code to look for and
1092 // rediscover unknown transactions that were written with keys of ours to recover
1093 // post-backup change.
1095 // Reserve a new key pair from key pool
1096 vector<unsigned char> vchPubKey = reservekey.GetReservedKey();
1097 // assert(mapKeys.count(vchPubKey));
1099 // Fill a vout to ourself
1100 // TODO: pass in scriptChange instead of reservekey so
1101 // change transaction isn't always pay-to-bitcoin-address
1102 CScript scriptChange;
1103 scriptChange.SetBitcoinAddress(vchPubKey);
1105 // Insert change txn at random position:
1106 vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
1107 wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
1110 reservekey.ReturnKey();
1113 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1114 wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
1118 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1119 if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
1123 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
1124 if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
1126 dPriority /= nBytes;
1128 // Check that enough fee is included
1129 int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
1130 bool fAllowFree = CTransaction::AllowFree(dPriority);
1131 int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND);
1132 if (nFeeRet < max(nPayFee, nMinFee))
1134 nFeeRet = max(nPayFee, nMinFee);
1138 // Fill vtxPrev by copying from previous transactions vtxPrev
1139 wtxNew.AddSupportingTransactions(txdb);
1140 wtxNew.fTimeReceivedIsTxTime = true;
1149 bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
1151 vector< pair<CScript, int64> > vecSend;
1152 vecSend.push_back(make_pair(scriptPubKey, nValue));
1153 return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet);
1156 // Call after CreateTransaction unless you want to abort
1157 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
1160 LOCK2(cs_main, cs_wallet);
1161 printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
1163 // This is only to keep the database open to defeat the auto-flush for the
1164 // duration of this scope. This is the only place where this optimization
1165 // maybe makes sense; please don't do it anywhere else.
1166 CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
1168 // Take key pair from key pool so it won't be used again
1169 reservekey.KeepKey();
1171 // Add tx to wallet, because if it has change it's also ours,
1172 // otherwise just for transaction history.
1173 AddToWallet(wtxNew);
1175 // Mark old coins as spent
1176 set<CWalletTx*> setCoins;
1177 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
1179 CWalletTx &coin = mapWallet[txin.prevout.hash];
1180 coin.BindWallet(this);
1181 coin.MarkSpent(txin.prevout.n);
1183 vWalletUpdated.push_back(coin.GetHash());
1190 // Track how many getdata requests our transaction gets
1191 mapRequestCount[wtxNew.GetHash()] = 0;
1194 if (!wtxNew.AcceptToMemoryPool())
1196 // This must not fail. The transaction has already been signed and recorded.
1197 printf("CommitTransaction() : Error: Transaction not valid");
1200 wtxNew.RelayWalletTransaction();
1209 string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
1211 CReserveKey reservekey(this);
1216 string strError = _("Error: Wallet locked, unable to create transaction ");
1217 printf("SendMoney() : %s", strError.c_str());
1220 if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
1223 if (nValue + nFeeRequired > GetBalance())
1224 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());
1226 strError = _("Error: Transaction creation failed ");
1227 printf("SendMoney() : %s", strError.c_str());
1231 if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending...")))
1234 if (!CommitTransaction(wtxNew, reservekey))
1235 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.");
1243 string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
1247 return _("Invalid amount");
1248 if (nValue + nTransactionFee > GetBalance())
1249 return _("Insufficient funds");
1251 // Parse bitcoin address
1252 CScript scriptPubKey;
1253 scriptPubKey.SetBitcoinAddress(address);
1255 return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
1261 int CWallet::LoadWallet(bool& fFirstRunRet)
1265 fFirstRunRet = false;
1266 int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
1267 if (nLoadWalletRet == DB_NEED_REWRITE)
1269 if (CDB::Rewrite(strWalletFile, "\x04pool"))
1272 // Note: can't top-up keypool here, because wallet is locked.
1273 // User will be prompted to unlock wallet the next operation
1274 // the requires a new key.
1276 nLoadWalletRet = DB_NEED_REWRITE;
1279 if (nLoadWalletRet != DB_LOAD_OK)
1280 return nLoadWalletRet;
1281 fFirstRunRet = vchDefaultKey.empty();
1283 CreateThread(ThreadFlushWalletDB, &strWalletFile);
1288 bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
1290 mapAddressBook[address] = strName;
1291 AddressBookRepaint();
1294 return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
1297 bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
1299 mapAddressBook.erase(address);
1300 AddressBookRepaint();
1303 return CWalletDB(strWalletFile).EraseName(address.ToString());
1307 void CWallet::PrintWallet(const CBlock& block)
1311 if (mapWallet.count(block.vtx[0].GetHash()))
1313 CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
1314 printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
1320 bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
1324 map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
1325 if (mi != mapWallet.end())
1334 bool CWallet::SetDefaultKey(const std::vector<unsigned char> &vchPubKey)
1338 if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
1341 vchDefaultKey = vchPubKey;
1345 bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
1347 if (!pwallet->fFileBacked)
1349 strWalletFileOut = pwallet->strWalletFile;
1354 // Mark old keypool keys as used,
1355 // and generate all new keys
1357 bool CWallet::NewKeyPool()
1361 CWalletDB walletdb(strWalletFile);
1362 BOOST_FOREACH(int64 nIndex, setKeyPool)
1363 walletdb.ErasePool(nIndex);
1369 int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
1370 for (int i = 0; i < nKeys; i++)
1373 walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
1374 setKeyPool.insert(nIndex);
1376 printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
1381 bool CWallet::TopUpKeyPool()
1389 CWalletDB walletdb(strWalletFile);
1392 int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
1393 while (setKeyPool.size() < nTargetSize+1)
1396 if (!setKeyPool.empty())
1397 nEnd = *(--setKeyPool.end()) + 1;
1398 if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
1399 throw runtime_error("TopUpKeyPool() : writing generated key failed");
1400 setKeyPool.insert(nEnd);
1401 printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
1407 void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
1410 keypool.vchPubKey.clear();
1417 // Get the oldest key
1418 if(setKeyPool.empty())
1421 CWalletDB walletdb(strWalletFile);
1423 nIndex = *(setKeyPool.begin());
1424 setKeyPool.erase(setKeyPool.begin());
1425 if (!walletdb.ReadPool(nIndex, keypool))
1426 throw runtime_error("ReserveKeyFromKeyPool() : read failed");
1427 if (!HaveKey(Hash160(keypool.vchPubKey)))
1428 throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
1429 assert(!keypool.vchPubKey.empty());
1430 printf("keypool reserve %"PRI64d"\n", nIndex);
1434 int64 CWallet::AddReserveKey(const CKeyPool& keypool)
1437 LOCK2(cs_main, cs_wallet);
1438 CWalletDB walletdb(strWalletFile);
1440 int64 nIndex = 1 + *(--setKeyPool.end());
1441 if (!walletdb.WritePool(nIndex, keypool))
1442 throw runtime_error("AddReserveKey() : writing added key failed");
1443 setKeyPool.insert(nIndex);
1449 void CWallet::KeepKey(int64 nIndex)
1451 // Remove from key pool
1454 CWalletDB walletdb(strWalletFile);
1455 walletdb.ErasePool(nIndex);
1457 printf("keypool keep %"PRI64d"\n", nIndex);
1460 void CWallet::ReturnKey(int64 nIndex)
1462 // Return to key pool
1465 setKeyPool.insert(nIndex);
1467 printf("keypool return %"PRI64d"\n", nIndex);
1470 bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
1476 ReserveKeyFromKeyPool(nIndex, keypool);
1479 if (fAllowReuse && !vchDefaultKey.empty())
1481 result = vchDefaultKey;
1484 if (IsLocked()) return false;
1485 result = GenerateNewKey();
1489 result = keypool.vchPubKey;
1494 int64 CWallet::GetOldestKeyPoolTime()
1498 ReserveKeyFromKeyPool(nIndex, keypool);
1502 return keypool.nTime;
1505 vector<unsigned char> CReserveKey::GetReservedKey()
1510 pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
1512 vchPubKey = keypool.vchPubKey;
1515 printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool.");
1516 vchPubKey = pwallet->vchDefaultKey;
1519 assert(!vchPubKey.empty());
1523 void CReserveKey::KeepKey()
1526 pwallet->KeepKey(nIndex);
1531 void CReserveKey::ReturnKey()
1534 pwallet->ReturnKey(nIndex);
1539 void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
1543 CWalletDB walletdb(strWalletFile);
1545 LOCK2(cs_main, cs_wallet);
1546 BOOST_FOREACH(const int64& id, setKeyPool)
1549 if (!walletdb.ReadPool(id, keypool))
1550 throw runtime_error("GetAllReserveKeyHashes() : read failed");
1551 CBitcoinAddress address(keypool.vchPubKey);
1552 assert(!keypool.vchPubKey.empty());
1553 if (!HaveKey(address))
1554 throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
1555 setAddress.insert(address);