1 // Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
7 #include "cryptopp/sha.h"
13 //////////////////////////////////////////////////////////////////////////////
18 void WalletUpdateSpent(const COutPoint& prevout)
20 // Anytime a signature is successfully verified, it's proof the outpoint is spent.
21 // Update the wallet spent flag if it doesn't know due to wallet.dat being
22 // restored from backup or the user making copies of wallet.dat.
23 CRITICAL_BLOCK(cs_mapWallet)
25 map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
26 if (mi != mapWallet.end())
28 CWalletTx& wtx = (*mi).second;
29 if (!wtx.IsSpent(prevout.n) && wtx.vout[prevout.n].IsMine())
31 printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
32 wtx.MarkSpent(prevout.n);
34 vWalletUpdated.push_back(prevout.hash);
40 bool AddToWallet(const CWalletTx& wtxIn)
42 uint256 hash = wtxIn.GetHash();
43 CRITICAL_BLOCK(cs_mapWallet)
45 // Inserts only if not already there, returns tx inserted or tx found
46 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
47 CWalletTx& wtx = (*ret.first).second;
48 bool fInsertedNew = ret.second;
50 wtx.nTimeReceived = GetAdjustedTime();
52 bool fUpdated = false;
56 if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
58 wtx.hashBlock = wtxIn.hashBlock;
61 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
63 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
64 wtx.nIndex = wtxIn.nIndex;
67 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
69 wtx.fFromMe = wtxIn.fFromMe;
72 fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
76 printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
79 if (fInsertedNew || fUpdated)
80 if (!wtx.WriteToDisk())
83 // If default receiving address gets used, replace it with a new one
84 CScript scriptDefaultKey;
85 scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
86 BOOST_FOREACH(const CTxOut& txout, wtx.vout)
88 if (txout.scriptPubKey == scriptDefaultKey)
91 vchDefaultKey = GetKeyFromKeyPool();
92 walletdb.WriteDefaultKey(vchDefaultKey);
93 walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
98 vWalletUpdated.push_back(hash);
106 bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
108 uint256 hash = tx.GetHash();
109 bool fExisted = mapWallet.count(hash);
110 if (fExisted && !fUpdate) return false;
111 if (fExisted || tx.IsMine() || tx.IsFromMe())
114 // Get merkle branch if transaction was found in a block
116 wtx.SetMerkleBranch(pblock);
117 return AddToWallet(wtx);
122 bool EraseFromWallet(uint256 hash)
124 CRITICAL_BLOCK(cs_mapWallet)
126 if (mapWallet.erase(hash))
127 CWalletDB().EraseTx(hash);
133 bool CTxIn::IsMine() const
135 CRITICAL_BLOCK(cs_mapWallet)
137 map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
138 if (mi != mapWallet.end())
140 const CWalletTx& prev = (*mi).second;
141 if (prevout.n < prev.vout.size())
142 if (prev.vout[prevout.n].IsMine())
149 int64 CTxIn::GetDebit() const
151 CRITICAL_BLOCK(cs_mapWallet)
153 map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
154 if (mi != mapWallet.end())
156 const CWalletTx& prev = (*mi).second;
157 if (prevout.n < prev.vout.size())
158 if (prev.vout[prevout.n].IsMine())
159 return prev.vout[prevout.n].nValue;
165 int64 CWalletTx::GetTxTime() const
167 if (!fTimeReceivedIsTxTime && hashBlock != 0)
169 // If we did not receive the transaction directly, we rely on the block's
170 // time to figure out when it happened. We use the median over a range
171 // of blocks to try to filter out inaccurate block times.
172 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
173 if (mi != mapBlockIndex.end())
175 CBlockIndex* pindex = (*mi).second;
177 return pindex->GetMedianTime();
180 return nTimeReceived;
183 int CWalletTx::GetRequestCount() const
185 // Returns -1 if it wasn't being tracked
187 CRITICAL_BLOCK(cs_mapRequestCount)
194 map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock);
195 if (mi != mapRequestCount.end())
196 nRequests = (*mi).second;
201 // Did anyone request this transaction?
202 map<uint256, int>::iterator mi = mapRequestCount.find(GetHash());
203 if (mi != mapRequestCount.end())
205 nRequests = (*mi).second;
207 // How about the block it's in?
208 if (nRequests == 0 && hashBlock != 0)
210 map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock);
211 if (mi != mapRequestCount.end())
212 nRequests = (*mi).second;
214 nRequests = 1; // If it's in someone else's block it must have got out
222 void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<string, int64> >& listReceived,
223 list<pair<string, int64> >& listSent, int64& nFee, string& strSentAccount) const
225 nGeneratedImmature = nGeneratedMature = nFee = 0;
226 listReceived.clear();
228 strSentAccount = strFromAccount;
232 if (GetBlocksToMaturity() > 0)
233 nGeneratedImmature = CTransaction::GetCredit();
235 nGeneratedMature = GetCredit();
240 int64 nDebit = GetDebit();
241 if (nDebit > 0) // debit>0 means we signed/sent this transaction
243 int64 nValueOut = GetValueOut();
244 nFee = nDebit - nValueOut;
247 // Sent/received. Standard client will never generate a send-to-multiple-recipients,
248 // but non-standard clients might (so return a list of address/amount pairs)
249 BOOST_FOREACH(const CTxOut& txout, vout)
253 vector<unsigned char> vchPubKey;
254 if (ExtractHash160(txout.scriptPubKey, hash160))
255 address = Hash160ToAddress(hash160);
256 else if (ExtractPubKey(txout.scriptPubKey, false, vchPubKey))
257 address = PubKeyToAddress(vchPubKey);
260 printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
261 this->GetHash().ToString().c_str());
262 address = " unknown ";
265 // Don't report 'change' txouts
266 if (nDebit > 0 && txout.IsChange())
270 listSent.push_back(make_pair(address, txout.nValue));
273 listReceived.push_back(make_pair(address, txout.nValue));
278 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
279 int64& nSent, int64& nFee) const
281 nGenerated = nReceived = nSent = nFee = 0;
283 int64 allGeneratedImmature, allGeneratedMature, allFee;
284 allGeneratedImmature = allGeneratedMature = allFee = 0;
285 string strSentAccount;
286 list<pair<string, int64> > listReceived;
287 list<pair<string, int64> > listSent;
288 GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
290 if (strAccount == "")
291 nGenerated = allGeneratedMature;
292 if (strAccount == strSentAccount)
294 BOOST_FOREACH(const PAIRTYPE(string,int64)& s, listSent)
298 CRITICAL_BLOCK(cs_mapAddressBook)
300 BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listReceived)
302 if (mapAddressBook.count(r.first))
304 if (mapAddressBook[r.first] == strAccount)
306 nReceived += r.second;
309 else if (strAccount.empty())
311 nReceived += r.second;
317 void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
321 const int COPY_DEPTH = 3;
322 if (SetMerkleBranch() < COPY_DEPTH)
324 vector<uint256> vWorkQueue;
325 BOOST_FOREACH(const CTxIn& txin, vin)
326 vWorkQueue.push_back(txin.prevout.hash);
328 // This critsect is OK because txdb is already open
329 CRITICAL_BLOCK(cs_mapWallet)
331 map<uint256, const CMerkleTx*> mapWalletPrev;
332 set<uint256> setAlreadyDone;
333 for (int i = 0; i < vWorkQueue.size(); i++)
335 uint256 hash = vWorkQueue[i];
336 if (setAlreadyDone.count(hash))
338 setAlreadyDone.insert(hash);
341 if (mapWallet.count(hash))
343 tx = mapWallet[hash];
344 BOOST_FOREACH(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev)
345 mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
347 else if (mapWalletPrev.count(hash))
349 tx = *mapWalletPrev[hash];
351 else if (!fClient && txdb.ReadDiskTx(hash, tx))
357 printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
361 int nDepth = tx.SetMerkleBranch();
362 vtxPrev.push_back(tx);
364 if (nDepth < COPY_DEPTH)
365 BOOST_FOREACH(const CTxIn& txin, tx.vin)
366 vWorkQueue.push_back(txin.prevout.hash);
371 reverse(vtxPrev.begin(), vtxPrev.end());
374 bool CWalletTx::WriteToDisk()
376 return CWalletDB().WriteTx(GetHash(), *this);
379 int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
383 CBlockIndex* pindex = pindexStart;
384 CRITICAL_BLOCK(cs_mapWallet)
389 block.ReadFromDisk(pindex, true);
390 BOOST_FOREACH(CTransaction& tx, block.vtx)
392 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
395 pindex = pindex->pnext;
401 void ReacceptWalletTransactions()
405 while (fRepeat) CRITICAL_BLOCK(cs_mapWallet)
408 vector<CDiskTxPos> vMissingTx;
409 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
411 CWalletTx& wtx = item.second;
412 if (wtx.IsCoinBase() && wtx.IsSpent(0))
416 bool fUpdated = false;
417 if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
419 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
420 if (txindex.vSpent.size() != wtx.vout.size())
422 printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
425 for (int i = 0; i < txindex.vSpent.size(); i++)
429 if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine())
433 vMissingTx.push_back(txindex.vSpent[i]);
438 printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
445 // Reaccept any txes of ours that aren't already in a block
446 if (!wtx.IsCoinBase())
447 wtx.AcceptWalletTransaction(txdb, false);
450 if (!vMissingTx.empty())
452 // TODO: optimize this to scan just part of the block chain?
453 if (ScanForWalletTransactions(pindexGenesisBlock))
454 fRepeat = true; // Found missing transactions: re-do Reaccept.
459 void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
461 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
463 if (!tx.IsCoinBase())
465 uint256 hash = tx.GetHash();
466 if (!txdb.ContainsTx(hash))
467 RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
472 uint256 hash = GetHash();
473 if (!txdb.ContainsTx(hash))
475 printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
476 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
481 void CWalletTx::RelayWalletTransaction()
484 RelayWalletTransaction(txdb);
487 void ResendWalletTransactions()
489 // Do this infrequently and randomly to avoid giving away
490 // that these are our transactions.
491 static int64 nNextTime;
492 if (GetTime() < nNextTime)
494 bool fFirst = (nNextTime == 0);
495 nNextTime = GetTime() + GetRand(30 * 60);
499 // Only do it if there's been a new block since last time
500 static int64 nLastTime;
501 if (nTimeBestReceived < nLastTime)
503 nLastTime = GetTime();
505 // Rebroadcast any of our txes that aren't in a block yet
506 printf("ResendWalletTransactions()\n");
508 CRITICAL_BLOCK(cs_mapWallet)
510 // Sort them in chronological order
511 multimap<unsigned int, CWalletTx*> mapSorted;
512 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
514 CWalletTx& wtx = item.second;
515 // Don't rebroadcast until it's had plenty of time that
516 // it should have gotten in already by now.
517 if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
518 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
520 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
522 CWalletTx& wtx = *item.second;
523 wtx.RelayWalletTransaction(txdb);
533 //////////////////////////////////////////////////////////////////////////////
541 int64 nStart = GetTimeMillis();
544 CRITICAL_BLOCK(cs_mapWallet)
546 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
548 CWalletTx* pcoin = &(*it).second;
549 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
551 nTotal += pcoin->GetAvailableCredit();
555 //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart);
560 bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet)
565 // List of values less than target
566 pair<int64, pair<CWalletTx*,unsigned int> > coinLowestLarger;
567 coinLowestLarger.first = INT64_MAX;
568 coinLowestLarger.second.first = NULL;
569 vector<pair<int64, pair<CWalletTx*,unsigned int> > > vValue;
570 int64 nTotalLower = 0;
572 CRITICAL_BLOCK(cs_mapWallet)
574 vector<CWalletTx*> vCoins;
575 vCoins.reserve(mapWallet.size());
576 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
577 vCoins.push_back(&(*it).second);
578 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
580 BOOST_FOREACH(CWalletTx* pcoin, vCoins)
582 if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
585 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
588 int nDepth = pcoin->GetDepthInMainChain();
589 if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
592 for (int i = 0; i < pcoin->vout.size(); i++)
594 if (pcoin->IsSpent(i) || !pcoin->vout[i].IsMine())
597 int64 n = pcoin->vout[i].nValue;
602 pair<int64,pair<CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin,i));
604 if (n == nTargetValue)
606 setCoinsRet.insert(coin.second);
607 nValueRet += coin.first;
610 else if (n < nTargetValue + CENT)
612 vValue.push_back(coin);
615 else if (n < coinLowestLarger.first)
617 coinLowestLarger = coin;
623 if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
625 for (int i = 0; i < vValue.size(); ++i)
627 setCoinsRet.insert(vValue[i].second);
628 nValueRet += vValue[i].first;
633 if (nTotalLower < nTargetValue + (coinLowestLarger.second.first ? CENT : 0))
635 if (coinLowestLarger.second.first == NULL)
637 setCoinsRet.insert(coinLowestLarger.second);
638 nValueRet += coinLowestLarger.first;
642 if (nTotalLower >= nTargetValue + CENT)
643 nTargetValue += CENT;
645 // Solve subset sum by stochastic approximation
646 sort(vValue.rbegin(), vValue.rend());
647 vector<char> vfIncluded;
648 vector<char> vfBest(vValue.size(), true);
649 int64 nBest = nTotalLower;
651 for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
653 vfIncluded.assign(vValue.size(), false);
655 bool fReachedTarget = false;
656 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
658 for (int i = 0; i < vValue.size(); i++)
660 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
662 nTotal += vValue[i].first;
663 vfIncluded[i] = true;
664 if (nTotal >= nTargetValue)
666 fReachedTarget = true;
672 nTotal -= vValue[i].first;
673 vfIncluded[i] = false;
680 // If the next larger is still closer, return it
681 if (coinLowestLarger.second.first && coinLowestLarger.first - nTargetValue <= nBest - nTargetValue)
683 setCoinsRet.insert(coinLowestLarger.second);
684 nValueRet += coinLowestLarger.first;
687 for (int i = 0; i < vValue.size(); i++)
690 setCoinsRet.insert(vValue[i].second);
691 nValueRet += vValue[i].first;
695 printf("SelectCoins() best subset: ");
696 for (int i = 0; i < vValue.size(); i++)
698 printf("%s ", FormatMoney(vValue[i].first).c_str());
699 printf("total %s\n", FormatMoney(nBest).c_str());
705 bool SelectCoins(int64 nTargetValue, set<pair<CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet)
707 return (SelectCoinsMinConf(nTargetValue, 1, 6, setCoinsRet, nValueRet) ||
708 SelectCoinsMinConf(nTargetValue, 1, 1, setCoinsRet, nValueRet) ||
709 SelectCoinsMinConf(nTargetValue, 0, 1, setCoinsRet, nValueRet));
715 bool CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
718 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
724 if (vecSend.empty() || nValue < 0)
727 CRITICAL_BLOCK(cs_main)
729 // txdb must be opened before the mapWallet lock
731 CRITICAL_BLOCK(cs_mapWallet)
733 nFeeRet = nTransactionFee;
738 wtxNew.fFromMe = true;
740 int64 nTotalValue = nValue + nFeeRet;
741 double dPriority = 0;
742 // vouts to the payees
743 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
744 wtxNew.vout.push_back(CTxOut(s.second, s.first));
746 // Choose coins to use
747 set<pair<CWalletTx*,unsigned int> > setCoins;
749 if (!SelectCoins(nTotalValue, setCoins, nValueIn))
751 BOOST_FOREACH(PAIRTYPE(CWalletTx*, unsigned int) pcoin, setCoins)
753 int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
754 dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
757 // Fill a vout back to self with any change
758 int64 nChange = nValueIn - nTotalValue;
761 // Note: We use a new key here to keep it from being obvious which side is the change.
762 // The drawback is that by not reusing a previous key, the change may be lost if a
763 // backup is restored, if the backup doesn't have the new private key for the change.
764 // If we reused the old key, it would be possible to add code to look for and
765 // rediscover unknown transactions that were written with keys of ours to recover
766 // post-backup change.
768 // Reserve a new key pair from key pool
769 vector<unsigned char> vchPubKey = reservekey.GetReservedKey();
770 assert(mapKeys.count(vchPubKey));
772 // Fill a vout to ourself, using same address type as the payment
773 CScript scriptChange;
774 if (vecSend[0].first.GetBitcoinAddressHash160() != 0)
775 scriptChange.SetBitcoinAddress(vchPubKey);
777 scriptChange << vchPubKey << OP_CHECKSIG;
779 // Insert change txn at random position:
780 vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
781 wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
784 reservekey.ReturnKey();
787 BOOST_FOREACH(const PAIRTYPE(CWalletTx*,unsigned int)& coin, setCoins)
788 wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
792 BOOST_FOREACH(const PAIRTYPE(CWalletTx*,unsigned int)& coin, setCoins)
793 if (!SignSignature(*coin.first, wtxNew, nIn++))
797 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
798 if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
802 // Check that enough fee is included
803 int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
804 bool fAllowFree = CTransaction::AllowFree(dPriority);
805 int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree);
806 if (nFeeRet < max(nPayFee, nMinFee))
808 nFeeRet = max(nPayFee, nMinFee);
812 // Fill vtxPrev by copying from previous transactions vtxPrev
813 wtxNew.AddSupportingTransactions(txdb);
814 wtxNew.fTimeReceivedIsTxTime = true;
823 bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
825 vector< pair<CScript, int64> > vecSend;
826 vecSend.push_back(make_pair(scriptPubKey, nValue));
827 return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet);
830 // Call after CreateTransaction unless you want to abort
831 bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
833 CRITICAL_BLOCK(cs_main)
835 printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
836 CRITICAL_BLOCK(cs_mapWallet)
838 // This is only to keep the database open to defeat the auto-flush for the
839 // duration of this scope. This is the only place where this optimization
840 // maybe makes sense; please don't do it anywhere else.
841 CWalletDB walletdb("r");
843 // Take key pair from key pool so it won't be used again
844 reservekey.KeepKey();
846 // Add tx to wallet, because if it has change it's also ours,
847 // otherwise just for transaction history.
850 // Mark old coins as spent
851 set<CWalletTx*> setCoins;
852 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
854 CWalletTx &pcoin = mapWallet[txin.prevout.hash];
855 pcoin.MarkSpent(txin.prevout.n);
857 vWalletUpdated.push_back(pcoin.GetHash());
861 // Track how many getdata requests our transaction gets
862 CRITICAL_BLOCK(cs_mapRequestCount)
863 mapRequestCount[wtxNew.GetHash()] = 0;
866 if (!wtxNew.AcceptToMemoryPool())
868 // This must not fail. The transaction has already been signed and recorded.
869 printf("CommitTransaction() : Error: Transaction not valid");
872 wtxNew.RelayWalletTransaction();
881 // requires cs_main lock
882 string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
884 CReserveKey reservekey;
886 if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
889 if (nValue + nFeeRequired > GetBalance())
890 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());
892 strError = _("Error: Transaction creation failed ");
893 printf("SendMoney() : %s", strError.c_str());
897 if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
900 if (!CommitTransaction(wtxNew, reservekey))
901 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.");
909 // requires cs_main lock
910 string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
914 return _("Invalid amount");
915 if (nValue + nTransactionFee > GetBalance())
916 return _("Insufficient funds");
918 // Parse bitcoin address
919 CScript scriptPubKey;
920 if (!scriptPubKey.SetBitcoinAddress(strAddress))
921 return _("Invalid bitcoin address");
923 return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
929 bool LoadWallet(bool& fFirstRunRet)
931 fFirstRunRet = false;
932 if (!CWalletDB("cr+").LoadWallet())
934 fFirstRunRet = vchDefaultKey.empty();
936 if (mapKeys.count(vchDefaultKey))
939 keyUser.SetPubKey(vchDefaultKey);
940 keyUser.SetPrivKey(mapKeys[vchDefaultKey]);
944 // Create new keyUser and set as default key
945 RandAddSeedPerfmon();
948 vchDefaultKey = GetKeyFromKeyPool();
949 walletdb.WriteDefaultKey(vchDefaultKey);
950 walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
953 CreateThread(ThreadFlushWalletDB, NULL);
957 void CWalletDB::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
960 keypool.vchPubKey.clear();
961 CRITICAL_BLOCK(cs_main)
962 CRITICAL_BLOCK(cs_mapWallet)
963 CRITICAL_BLOCK(cs_setKeyPool)
966 int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
967 while (setKeyPool.size() < nTargetSize+1)
970 if (!setKeyPool.empty())
971 nEnd = *(--setKeyPool.end()) + 1;
972 if (!Write(make_pair(string("pool"), nEnd), CKeyPool(GenerateNewKey())))
973 throw runtime_error("ReserveKeyFromKeyPool() : writing generated key failed");
974 setKeyPool.insert(nEnd);
975 printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
978 // Get the oldest key
979 assert(!setKeyPool.empty());
980 nIndex = *(setKeyPool.begin());
981 setKeyPool.erase(setKeyPool.begin());
982 if (!Read(make_pair(string("pool"), nIndex), keypool))
983 throw runtime_error("ReserveKeyFromKeyPool() : read failed");
984 if (!mapKeys.count(keypool.vchPubKey))
985 throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
986 assert(!keypool.vchPubKey.empty());
987 printf("keypool reserve %"PRI64d"\n", nIndex);
991 void CWalletDB::KeepKey(int64 nIndex)
993 // Remove from key pool
994 CRITICAL_BLOCK(cs_main)
995 CRITICAL_BLOCK(cs_mapWallet)
997 Erase(make_pair(string("pool"), nIndex));
999 printf("keypool keep %"PRI64d"\n", nIndex);
1002 void CWalletDB::ReturnKey(int64 nIndex)
1004 // Return to key pool
1005 CRITICAL_BLOCK(cs_setKeyPool)
1006 setKeyPool.insert(nIndex);
1007 printf("keypool return %"PRI64d"\n", nIndex);
1010 vector<unsigned char> GetKeyFromKeyPool()
1015 walletdb.ReserveKeyFromKeyPool(nIndex, keypool);
1016 walletdb.KeepKey(nIndex);
1017 return keypool.vchPubKey;
1020 int64 GetOldestKeyPoolTime()
1025 walletdb.ReserveKeyFromKeyPool(nIndex, keypool);
1026 walletdb.ReturnKey(nIndex);
1027 return keypool.nTime;
1030 std::vector<unsigned char> CReserveKey::GetReservedKey()
1035 CWalletDB().ReserveKeyFromKeyPool(nIndex, keypool);
1036 vchPubKey = keypool.vchPubKey;
1038 assert(!vchPubKey.empty());
1042 void CReserveKey::KeepKey()
1045 CWalletDB().KeepKey(nIndex);
1050 void CReserveKey::ReturnKey()
1053 CWalletDB::ReturnKey(nIndex);