Bugfixes walletclass
[novacoin.git] / src / wallet.cpp
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.
4
5 #include "headers.h"
6 #include "db.h"
7 #include "cryptopp/sha.h"
8
9 using namespace std;
10
11
12
13 //////////////////////////////////////////////////////////////////////////////
14 //
15 // mapWallet
16 //
17
18 bool CWallet::AddKey(const CKey& key)
19 {
20     this->CKeyStore::AddKey(key);
21     if (!fFileBacked)
22         return true;
23     return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey());
24 }
25
26 void CWallet::WalletUpdateSpent(const CTransaction &tx)
27 {
28     // Anytime a signature is successfully verified, it's proof the outpoint is spent.
29     // Update the wallet spent flag if it doesn't know due to wallet.dat being
30     // restored from backup or the user making copies of wallet.dat.
31     CRITICAL_BLOCK(cs_mapWallet)
32     {
33         BOOST_FOREACH(const CTxIn& txin, tx.vin)
34         {
35             map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
36             if (mi != mapWallet.end())
37             {
38                 CWalletTx& wtx = (*mi).second;
39                 if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
40                 {
41                     printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
42                     wtx.MarkSpent(txin.prevout.n);
43                     wtx.WriteToDisk();
44                     vWalletUpdated.push_back(txin.prevout.hash);
45                 }
46             }
47         }
48     }
49 }
50
51 bool CWallet::AddToWallet(const CWalletTx& wtxIn)
52 {
53     uint256 hash = wtxIn.GetHash();
54     CRITICAL_BLOCK(cs_mapWallet)
55     {
56         // Inserts only if not already there, returns tx inserted or tx found
57         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
58         CWalletTx& wtx = (*ret.first).second;
59         wtx.pwallet = this;
60         bool fInsertedNew = ret.second;
61         if (fInsertedNew)
62             wtx.nTimeReceived = GetAdjustedTime();
63
64         bool fUpdated = false;
65         if (!fInsertedNew)
66         {
67             // Merge
68             if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
69             {
70                 wtx.hashBlock = wtxIn.hashBlock;
71                 fUpdated = true;
72             }
73             if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
74             {
75                 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
76                 wtx.nIndex = wtxIn.nIndex;
77                 fUpdated = true;
78             }
79             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
80             {
81                 wtx.fFromMe = wtxIn.fFromMe;
82                 fUpdated = true;
83             }
84             fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
85         }
86
87         //// debug print
88         printf("AddToWallet %s  %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
89
90         // Write to disk
91         if (fInsertedNew || fUpdated)
92             if (!wtx.WriteToDisk())
93                 return false;
94
95         // If default receiving address gets used, replace it with a new one
96         CScript scriptDefaultKey;
97         scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
98         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
99         {
100             if (txout.scriptPubKey == scriptDefaultKey)
101             {
102                 if (!fFileBacked)
103                     continue;
104                 CWalletDB walletdb(strWalletFile);
105                 vchDefaultKey = GetKeyFromKeyPool();
106                 walletdb.WriteDefaultKey(vchDefaultKey);
107                 walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
108             }
109         }
110
111         // Notify UI
112         vWalletUpdated.push_back(hash);
113
114         // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
115         WalletUpdateSpent(wtx);
116     }
117
118     // Refresh UI
119     MainFrameRepaint();
120     return true;
121 }
122
123 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
124 {
125     uint256 hash = tx.GetHash();
126     bool fExisted = mapWallet.count(hash);
127     if (fExisted && !fUpdate) return false;
128     if (fExisted || IsMine(tx) || IsFromMe(tx))
129     {
130         CWalletTx wtx(this,tx);
131         // Get merkle branch if transaction was found in a block
132         if (pblock)
133             wtx.SetMerkleBranch(pblock);
134         return AddToWallet(wtx);
135     }
136     else
137         WalletUpdateSpent(tx);
138     return false;
139 }
140
141 bool CWallet::EraseFromWallet(uint256 hash)
142 {
143     if (!fFileBacked)
144         return false;
145     CRITICAL_BLOCK(cs_mapWallet)
146     {
147         if (mapWallet.erase(hash))
148             CWalletDB(strWalletFile).EraseTx(hash);
149     }
150     return true;
151 }
152
153
154 bool CWallet::IsMine(const CTxIn &txin) const
155 {
156     CRITICAL_BLOCK(cs_mapWallet)
157     {
158         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
159         if (mi != mapWallet.end())
160         {
161             const CWalletTx& prev = (*mi).second;
162             if (txin.prevout.n < prev.vout.size())
163                 if (IsMine(prev.vout[txin.prevout.n]))
164                     return true;
165         }
166     }
167     return false;
168 }
169
170 int64 CWallet::GetDebit(const CTxIn &txin) const
171 {
172     CRITICAL_BLOCK(cs_mapWallet)
173     {
174         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
175         if (mi != mapWallet.end())
176         {
177             const CWalletTx& prev = (*mi).second;
178             if (txin.prevout.n < prev.vout.size())
179                 if (IsMine(prev.vout[txin.prevout.n]))
180                     return prev.vout[txin.prevout.n].nValue;
181         }
182     }
183     return 0;
184 }
185
186 int64 CWalletTx::GetTxTime() const
187 {
188     if (!fTimeReceivedIsTxTime && hashBlock != 0)
189     {
190         // If we did not receive the transaction directly, we rely on the block's
191         // time to figure out when it happened.  We use the median over a range
192         // of blocks to try to filter out inaccurate block times.
193         map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
194         if (mi != mapBlockIndex.end())
195         {
196             CBlockIndex* pindex = (*mi).second;
197             if (pindex)
198                 return pindex->GetMedianTime();
199         }
200     }
201     return nTimeReceived;
202 }
203
204 int CWalletTx::GetRequestCount() const
205 {
206     // Returns -1 if it wasn't being tracked
207     int nRequests = -1;
208     CRITICAL_BLOCK(pwallet->cs_mapRequestCount)
209     {
210         if (IsCoinBase())
211         {
212             // Generated block
213             if (hashBlock != 0)
214             {
215                 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
216                 if (mi != pwallet->mapRequestCount.end())
217                     nRequests = (*mi).second;
218             }
219         }
220         else
221         {
222             // Did anyone request this transaction?
223             map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
224             if (mi != pwallet->mapRequestCount.end())
225             {
226                 nRequests = (*mi).second;
227
228                 // How about the block it's in?
229                 if (nRequests == 0 && hashBlock != 0)
230                 {
231                     map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
232                     if (mi != pwallet->mapRequestCount.end())
233                         nRequests = (*mi).second;
234                     else
235                         nRequests = 1; // If it's in someone else's block it must have got out
236                 }
237             }
238         }
239     }
240     return nRequests;
241 }
242
243 void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<string, int64> >& listReceived,
244                            list<pair<string, int64> >& listSent, int64& nFee, string& strSentAccount) const
245 {
246     nGeneratedImmature = nGeneratedMature = nFee = 0;
247     listReceived.clear();
248     listSent.clear();
249     strSentAccount = strFromAccount;
250
251     if (IsCoinBase())
252     {
253         if (GetBlocksToMaturity() > 0)
254             nGeneratedImmature = pwallet->GetCredit(*this);
255         else
256             nGeneratedMature = GetCredit();
257         return;
258     }
259
260     // Compute fee:
261     int64 nDebit = GetDebit();
262     if (nDebit > 0) // debit>0 means we signed/sent this transaction
263     {
264         int64 nValueOut = GetValueOut();
265         nFee = nDebit - nValueOut;
266     }
267
268     // Sent/received.  Standard client will never generate a send-to-multiple-recipients,
269     // but non-standard clients might (so return a list of address/amount pairs)
270     BOOST_FOREACH(const CTxOut& txout, vout)
271     {
272         string address;
273         uint160 hash160;
274         vector<unsigned char> vchPubKey;
275         if (ExtractHash160(txout.scriptPubKey, hash160))
276             address = Hash160ToAddress(hash160);
277         else if (ExtractPubKey(txout.scriptPubKey, NULL, vchPubKey))
278             address = PubKeyToAddress(vchPubKey);
279         else
280         {
281             printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
282                    this->GetHash().ToString().c_str());
283             address = " unknown ";
284         }
285
286         // Don't report 'change' txouts
287         if (nDebit > 0 && pwallet->IsChange(txout))
288             continue;
289
290         if (nDebit > 0)
291             listSent.push_back(make_pair(address, txout.nValue));
292
293         if (pwallet->IsMine(txout))
294             listReceived.push_back(make_pair(address, txout.nValue));
295     }
296
297 }
298
299 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, 
300                                   int64& nSent, int64& nFee) const
301 {
302     nGenerated = nReceived = nSent = nFee = 0;
303
304     int64 allGeneratedImmature, allGeneratedMature, allFee;
305     allGeneratedImmature = allGeneratedMature = allFee = 0;
306     string strSentAccount;
307     list<pair<string, int64> > listReceived;
308     list<pair<string, int64> > listSent;
309     GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
310
311     if (strAccount == "")
312         nGenerated = allGeneratedMature;
313     if (strAccount == strSentAccount)
314     {
315         BOOST_FOREACH(const PAIRTYPE(string,int64)& s, listSent)
316             nSent += s.second;
317         nFee = allFee;
318     }
319     CRITICAL_BLOCK(pwallet->cs_mapAddressBook)
320     {
321         BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listReceived)
322         {
323             if (pwallet->mapAddressBook.count(r.first))
324             {
325                 map<string, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
326                 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
327                     nReceived += r.second;
328             }
329             else if (strAccount.empty())
330             {
331                 nReceived += r.second;
332             }
333         }
334     }
335 }
336
337 void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
338 {
339     vtxPrev.clear();
340
341     const int COPY_DEPTH = 3;
342     if (SetMerkleBranch() < COPY_DEPTH)
343     {
344         vector<uint256> vWorkQueue;
345         BOOST_FOREACH(const CTxIn& txin, vin)
346             vWorkQueue.push_back(txin.prevout.hash);
347
348         // This critsect is OK because txdb is already open
349         CRITICAL_BLOCK(pwallet->cs_mapWallet)
350         {
351             map<uint256, const CMerkleTx*> mapWalletPrev;
352             set<uint256> setAlreadyDone;
353             for (int i = 0; i < vWorkQueue.size(); i++)
354             {
355                 uint256 hash = vWorkQueue[i];
356                 if (setAlreadyDone.count(hash))
357                     continue;
358                 setAlreadyDone.insert(hash);
359
360                 CMerkleTx tx;
361                 map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
362                 if (mi != pwallet->mapWallet.end())
363                 {
364                     tx = (*mi).second;
365                     BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
366                         mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
367                 }
368                 else if (mapWalletPrev.count(hash))
369                 {
370                     tx = *mapWalletPrev[hash];
371                 }
372                 else if (!fClient && txdb.ReadDiskTx(hash, tx))
373                 {
374                     ;
375                 }
376                 else
377                 {
378                     printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
379                     continue;
380                 }
381
382                 int nDepth = tx.SetMerkleBranch();
383                 vtxPrev.push_back(tx);
384
385                 if (nDepth < COPY_DEPTH)
386                     BOOST_FOREACH(const CTxIn& txin, tx.vin)
387                         vWorkQueue.push_back(txin.prevout.hash);
388             }
389         }
390     }
391
392     reverse(vtxPrev.begin(), vtxPrev.end());
393 }
394
395 bool CWalletTx::WriteToDisk()
396 {
397     return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
398 }
399
400 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
401 {
402     int ret = 0;
403
404     CBlockIndex* pindex = pindexStart;
405     CRITICAL_BLOCK(cs_mapWallet)
406     {
407         while (pindex)
408         {
409             CBlock block;
410             block.ReadFromDisk(pindex, true);
411             BOOST_FOREACH(CTransaction& tx, block.vtx)
412             {
413                 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
414                     ret++;
415             }
416             pindex = pindex->pnext;
417         }
418     }
419     return ret;
420 }
421
422 void CWallet::ReacceptWalletTransactions()
423 {
424     CTxDB txdb("r");
425     bool fRepeat = true;
426     while (fRepeat) CRITICAL_BLOCK(cs_mapWallet)
427     {
428         fRepeat = false;
429         vector<CDiskTxPos> vMissingTx;
430         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
431         {
432             CWalletTx& wtx = item.second;
433             if (wtx.IsCoinBase() && wtx.IsSpent(0))
434                 continue;
435
436             CTxIndex txindex;
437             bool fUpdated = false;
438             if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
439             {
440                 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
441                 if (txindex.vSpent.size() != wtx.vout.size())
442                 {
443                     printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
444                     continue;
445                 }
446                 for (int i = 0; i < txindex.vSpent.size(); i++)
447                 {
448                     if (wtx.IsSpent(i))
449                         continue;
450                     if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i]))
451                     {
452                         wtx.MarkSpent(i);
453                         fUpdated = true;
454                         vMissingTx.push_back(txindex.vSpent[i]);
455                     }
456                 }
457                 if (fUpdated)
458                 {
459                     printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
460                     wtx.MarkDirty();
461                     wtx.WriteToDisk();
462                 }
463             }
464             else
465             {
466                 // Reaccept any txes of ours that aren't already in a block
467                 if (!wtx.IsCoinBase())
468                     wtx.AcceptWalletTransaction(txdb, false);
469             }
470         }
471         if (!vMissingTx.empty())
472         {
473             // TODO: optimize this to scan just part of the block chain?
474             if (ScanForWalletTransactions(pindexGenesisBlock))
475                 fRepeat = true;  // Found missing transactions: re-do Reaccept.
476         }
477     }
478 }
479
480 void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
481 {
482     BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
483     {
484         if (!tx.IsCoinBase())
485         {
486             uint256 hash = tx.GetHash();
487             if (!txdb.ContainsTx(hash))
488                 RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
489         }
490     }
491     if (!IsCoinBase())
492     {
493         uint256 hash = GetHash();
494         if (!txdb.ContainsTx(hash))
495         {
496             printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
497             RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
498         }
499     }
500 }
501
502 void CWalletTx::RelayWalletTransaction()
503 {
504    CTxDB txdb("r");
505    RelayWalletTransaction(txdb);
506 }
507
508 void CWallet::ResendWalletTransactions()
509 {
510     // Do this infrequently and randomly to avoid giving away
511     // that these are our transactions.
512     static int64 nNextTime;
513     if (GetTime() < nNextTime)
514         return;
515     bool fFirst = (nNextTime == 0);
516     nNextTime = GetTime() + GetRand(30 * 60);
517     if (fFirst)
518         return;
519
520     // Only do it if there's been a new block since last time
521     static int64 nLastTime;
522     if (nTimeBestReceived < nLastTime)
523         return;
524     nLastTime = GetTime();
525
526     // Rebroadcast any of our txes that aren't in a block yet
527     printf("ResendWalletTransactions()\n");
528     CTxDB txdb("r");
529     CRITICAL_BLOCK(cs_mapWallet)
530     {
531         // Sort them in chronological order
532         multimap<unsigned int, CWalletTx*> mapSorted;
533         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
534         {
535             CWalletTx& wtx = item.second;
536             // Don't rebroadcast until it's had plenty of time that
537             // it should have gotten in already by now.
538             if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
539                 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
540         }
541         BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
542         {
543             CWalletTx& wtx = *item.second;
544             wtx.RelayWalletTransaction(txdb);
545         }
546     }
547 }
548
549
550
551
552
553
554 //////////////////////////////////////////////////////////////////////////////
555 //
556 // Actions
557 //
558
559
560 int64 CWallet::GetBalance() const
561 {
562     int64 nStart = GetTimeMillis();
563
564     int64 nTotal = 0;
565     CRITICAL_BLOCK(cs_mapWallet)
566     {
567         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
568         {
569             const CWalletTx* pcoin = &(*it).second;
570             if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
571                 continue;
572             nTotal += pcoin->GetAvailableCredit();
573         }
574     }
575
576     //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart);
577     return nTotal;
578 }
579
580
581 bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
582 {
583     setCoinsRet.clear();
584     nValueRet = 0;
585
586     // List of values less than target
587     pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
588     coinLowestLarger.first = INT64_MAX;
589     coinLowestLarger.second.first = NULL;
590     vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
591     int64 nTotalLower = 0;
592
593     CRITICAL_BLOCK(cs_mapWallet)
594     {
595        vector<const CWalletTx*> vCoins;
596        vCoins.reserve(mapWallet.size());
597        for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
598            vCoins.push_back(&(*it).second);
599        random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
600
601        BOOST_FOREACH(const CWalletTx* pcoin, vCoins)
602        {
603             if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
604                 continue;
605
606             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
607                 continue;
608
609             int nDepth = pcoin->GetDepthInMainChain();
610             if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
611                 continue;
612
613             for (int i = 0; i < pcoin->vout.size(); i++)
614             {
615                 if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]))
616                     continue;
617
618                 int64 n = pcoin->vout[i].nValue;
619
620                 if (n <= 0)
621                     continue;
622
623                 pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin,i));
624
625                 if (n == nTargetValue)
626                 {
627                     setCoinsRet.insert(coin.second);
628                     nValueRet += coin.first;
629                     return true;
630                 }
631                 else if (n < nTargetValue + CENT)
632                 {
633                     vValue.push_back(coin);
634                     nTotalLower += n;
635                 }
636                 else if (n < coinLowestLarger.first)
637                 {
638                     coinLowestLarger = coin;
639                 }
640             }
641         }
642     }
643
644     if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
645     {
646         for (int i = 0; i < vValue.size(); ++i)
647         {
648             setCoinsRet.insert(vValue[i].second);
649             nValueRet += vValue[i].first;
650         }
651         return true;
652     }
653
654     if (nTotalLower < nTargetValue + (coinLowestLarger.second.first ? CENT : 0))
655     {
656         if (coinLowestLarger.second.first == NULL)
657             return false;
658         setCoinsRet.insert(coinLowestLarger.second);
659         nValueRet += coinLowestLarger.first;
660         return true;
661     }
662
663     if (nTotalLower >= nTargetValue + CENT)
664         nTargetValue += CENT;
665
666     // Solve subset sum by stochastic approximation
667     sort(vValue.rbegin(), vValue.rend());
668     vector<char> vfIncluded;
669     vector<char> vfBest(vValue.size(), true);
670     int64 nBest = nTotalLower;
671
672     for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
673     {
674         vfIncluded.assign(vValue.size(), false);
675         int64 nTotal = 0;
676         bool fReachedTarget = false;
677         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
678         {
679             for (int i = 0; i < vValue.size(); i++)
680             {
681                 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
682                 {
683                     nTotal += vValue[i].first;
684                     vfIncluded[i] = true;
685                     if (nTotal >= nTargetValue)
686                     {
687                         fReachedTarget = true;
688                         if (nTotal < nBest)
689                         {
690                             nBest = nTotal;
691                             vfBest = vfIncluded;
692                         }
693                         nTotal -= vValue[i].first;
694                         vfIncluded[i] = false;
695                     }
696                 }
697             }
698         }
699     }
700
701     // If the next larger is still closer, return it
702     if (coinLowestLarger.second.first && coinLowestLarger.first - nTargetValue <= nBest - nTargetValue)
703     {
704         setCoinsRet.insert(coinLowestLarger.second);
705         nValueRet += coinLowestLarger.first;
706     }
707     else {
708         for (int i = 0; i < vValue.size(); i++)
709             if (vfBest[i])
710             {
711                 setCoinsRet.insert(vValue[i].second);
712                 nValueRet += vValue[i].first;
713             }
714
715         //// debug print
716         printf("SelectCoins() best subset: ");
717         for (int i = 0; i < vValue.size(); i++)
718             if (vfBest[i])
719                 printf("%s ", FormatMoney(vValue[i].first).c_str());
720         printf("total %s\n", FormatMoney(nBest).c_str());
721     }
722
723     return true;
724 }
725
726 bool CWallet::SelectCoins(int64 nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
727 {
728     return (SelectCoinsMinConf(nTargetValue, 1, 6, setCoinsRet, nValueRet) ||
729             SelectCoinsMinConf(nTargetValue, 1, 1, setCoinsRet, nValueRet) ||
730             SelectCoinsMinConf(nTargetValue, 0, 1, setCoinsRet, nValueRet));
731 }
732
733
734
735
736 bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
737 {
738     int64 nValue = 0;
739     BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
740     {
741         if (nValue < 0)
742             return false;
743         nValue += s.second;
744     }
745     if (vecSend.empty() || nValue < 0)
746         return false;
747
748     wtxNew.pwallet = this;
749
750     CRITICAL_BLOCK(cs_main)
751     {
752         // txdb must be opened before the mapWallet lock
753         CTxDB txdb("r");
754         CRITICAL_BLOCK(cs_mapWallet)
755         {
756             nFeeRet = nTransactionFee;
757             loop
758             {
759                 wtxNew.vin.clear();
760                 wtxNew.vout.clear();
761                 wtxNew.fFromMe = true;
762
763                 int64 nTotalValue = nValue + nFeeRet;
764                 double dPriority = 0;
765                 // vouts to the payees
766                 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
767                     wtxNew.vout.push_back(CTxOut(s.second, s.first));
768
769                 // Choose coins to use
770                 set<pair<const CWalletTx*,unsigned int> > setCoins;
771                 int64 nValueIn = 0;
772                 if (!SelectCoins(nTotalValue, setCoins, nValueIn))
773                     return false;
774                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
775                 {
776                     int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
777                     dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
778                 }
779
780                 // Fill a vout back to self with any change
781                 int64 nChange = nValueIn - nTotalValue;
782                 if (nChange >= CENT)
783                 {
784                     // Note: We use a new key here to keep it from being obvious which side is the change.
785                     //  The drawback is that by not reusing a previous key, the change may be lost if a
786                     //  backup is restored, if the backup doesn't have the new private key for the change.
787                     //  If we reused the old key, it would be possible to add code to look for and
788                     //  rediscover unknown transactions that were written with keys of ours to recover
789                     //  post-backup change.
790
791                     // Reserve a new key pair from key pool
792                     vector<unsigned char> vchPubKey = reservekey.GetReservedKey();
793                     assert(mapKeys.count(vchPubKey));
794
795                     // Fill a vout to ourself, using same address type as the payment
796                     CScript scriptChange;
797                     if (vecSend[0].first.GetBitcoinAddressHash160() != 0)
798                         scriptChange.SetBitcoinAddress(vchPubKey);
799                     else
800                         scriptChange << vchPubKey << OP_CHECKSIG;
801
802                     // Insert change txn at random position:
803                     vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
804                     wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
805                 }
806                 else
807                     reservekey.ReturnKey();
808
809                 // Fill vin
810                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
811                     wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
812
813                 // Sign
814                 int nIn = 0;
815                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
816                     if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
817                         return false;
818
819                 // Limit size
820                 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
821                 if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
822                     return false;
823                 dPriority /= nBytes;
824
825                 // Check that enough fee is included
826                 int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
827                 bool fAllowFree = CTransaction::AllowFree(dPriority);
828                 int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree);
829                 if (nFeeRet < max(nPayFee, nMinFee))
830                 {
831                     nFeeRet = max(nPayFee, nMinFee);
832                     continue;
833                 }
834
835                 // Fill vtxPrev by copying from previous transactions vtxPrev
836                 wtxNew.AddSupportingTransactions(txdb);
837                 wtxNew.fTimeReceivedIsTxTime = true;
838
839                 break;
840             }
841         }
842     }
843     return true;
844 }
845
846 bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
847 {
848     vector< pair<CScript, int64> > vecSend;
849     vecSend.push_back(make_pair(scriptPubKey, nValue));
850     return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet);
851 }
852
853 // Call after CreateTransaction unless you want to abort
854 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
855 {
856     CRITICAL_BLOCK(cs_main)
857     {
858         printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
859         CRITICAL_BLOCK(cs_mapWallet)
860         {
861             // This is only to keep the database open to defeat the auto-flush for the
862             // duration of this scope.  This is the only place where this optimization
863             // maybe makes sense; please don't do it anywhere else.
864             CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
865
866             // Take key pair from key pool so it won't be used again
867             reservekey.KeepKey();
868
869             // Add tx to wallet, because if it has change it's also ours,
870             // otherwise just for transaction history.
871             AddToWallet(wtxNew);
872
873             // Mark old coins as spent
874             set<CWalletTx*> setCoins;
875             BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
876             {
877                 CWalletTx &coin = mapWallet[txin.prevout.hash];
878                 coin.pwallet = this;
879                 coin.MarkSpent(txin.prevout.n);
880                 coin.WriteToDisk();
881                 vWalletUpdated.push_back(coin.GetHash());
882             }
883
884             if (fFileBacked)
885                 delete pwalletdb;
886         }
887
888         // Track how many getdata requests our transaction gets
889         CRITICAL_BLOCK(cs_mapRequestCount)
890             mapRequestCount[wtxNew.GetHash()] = 0;
891
892         // Broadcast
893         if (!wtxNew.AcceptToMemoryPool())
894         {
895             // This must not fail. The transaction has already been signed and recorded.
896             printf("CommitTransaction() : Error: Transaction not valid");
897             return false;
898         }
899         wtxNew.RelayWalletTransaction();
900     }
901     MainFrameRepaint();
902     return true;
903 }
904
905
906
907
908 // requires cs_main lock
909 string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
910 {
911     CReserveKey reservekey(this);
912     int64 nFeeRequired;
913     if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
914     {
915         string strError;
916         if (nValue + nFeeRequired > GetBalance())
917             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());
918         else
919             strError = _("Error: Transaction creation failed  ");
920         printf("SendMoney() : %s", strError.c_str());
921         return strError;
922     }
923
924     if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
925         return "ABORTED";
926
927     if (!CommitTransaction(wtxNew, reservekey))
928         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.");
929
930     MainFrameRepaint();
931     return "";
932 }
933
934
935
936 // requires cs_main lock
937 string CWallet::SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
938 {
939     // Check amount
940     if (nValue <= 0)
941         return _("Invalid amount");
942     if (nValue + nTransactionFee > GetBalance())
943         return _("Insufficient funds");
944
945     // Parse bitcoin address
946     CScript scriptPubKey;
947     if (!scriptPubKey.SetBitcoinAddress(strAddress))
948         return _("Invalid bitcoin address");
949
950     return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
951 }
952
953
954
955
956 bool CWallet::LoadWallet(bool& fFirstRunRet)
957 {
958     if (!fFileBacked)
959         return false;
960     fFirstRunRet = false;
961     if (!CWalletDB(strWalletFile,"cr+").LoadWallet(this))
962         return false;
963     fFirstRunRet = vchDefaultKey.empty();
964
965     if (mapKeys.count(vchDefaultKey))
966     {
967         // Set keyUser
968         keyUser.SetPubKey(vchDefaultKey);
969         keyUser.SetPrivKey(mapKeys[vchDefaultKey]);
970     }
971     else
972     {
973         // Create new keyUser and set as default key
974         RandAddSeedPerfmon();
975
976         vchDefaultKey = GetKeyFromKeyPool();
977         if (!SetAddressBookName(PubKeyToAddress(vchDefaultKey), ""))
978             return false;
979         CWalletDB(strWalletFile).WriteDefaultKey(keyUser.GetPubKey());
980     }
981
982     CreateThread(ThreadFlushWalletDB, &strWalletFile);
983     return true;
984 }
985
986 void CWallet::PrintWallet(const CBlock& block)
987 {
988     CRITICAL_BLOCK(cs_mapWallet)
989     {
990         if (mapWallet.count(block.vtx[0].GetHash()))
991         {
992             CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
993             printf("    mine:  %d  %d  %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
994         }
995     }
996     printf("\n");
997 }
998
999 bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
1000 {
1001     CRITICAL_BLOCK(cs_mapWallet)
1002     {
1003         map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
1004         if (mi != mapWallet.end())
1005         {
1006             wtx = (*mi).second;
1007             return true;
1008         }
1009     }
1010     return false;
1011 }
1012
1013 bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
1014 {
1015     if (!pwallet->fFileBacked)
1016         return false;
1017     strWalletFileOut = pwallet->strWalletFile;
1018     return true;
1019 }
1020
1021 void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
1022 {
1023     nIndex = -1;
1024     keypool.vchPubKey.clear();
1025     CRITICAL_BLOCK(cs_main)
1026     CRITICAL_BLOCK(cs_mapWallet)
1027     CRITICAL_BLOCK(cs_setKeyPool)
1028     {
1029         CWalletDB walletdb(strWalletFile);
1030
1031         // Top up key pool
1032         int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
1033         while (setKeyPool.size() < nTargetSize+1)
1034         {
1035             int64 nEnd = 1;
1036             if (!setKeyPool.empty())
1037                 nEnd = *(--setKeyPool.end()) + 1;
1038             if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
1039                 throw runtime_error("ReserveKeyFromKeyPool() : writing generated key failed");
1040             setKeyPool.insert(nEnd);
1041             printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
1042         }
1043
1044         // Get the oldest key
1045         assert(!setKeyPool.empty());
1046         nIndex = *(setKeyPool.begin());
1047         setKeyPool.erase(setKeyPool.begin());
1048         if (!walletdb.ReadPool(nIndex, keypool))
1049             throw runtime_error("ReserveKeyFromKeyPool() : read failed");
1050         if (!mapKeys.count(keypool.vchPubKey))
1051             throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
1052         assert(!keypool.vchPubKey.empty());
1053         printf("keypool reserve %"PRI64d"\n", nIndex);
1054     }
1055 }
1056
1057 void CWallet::KeepKey(int64 nIndex)
1058 {
1059     // Remove from key pool
1060     if (fFileBacked)
1061     {
1062         CWalletDB walletdb(strWalletFile);
1063         CRITICAL_BLOCK(cs_main)
1064         {
1065             walletdb.ErasePool(nIndex);
1066         }
1067     }
1068     printf("keypool keep %"PRI64d"\n", nIndex);
1069 }
1070
1071 void CWallet::ReturnKey(int64 nIndex)
1072 {
1073     // Return to key pool
1074     CRITICAL_BLOCK(cs_setKeyPool)
1075         setKeyPool.insert(nIndex);
1076     printf("keypool return %"PRI64d"\n", nIndex);
1077 }
1078
1079 vector<unsigned char> CWallet::GetKeyFromKeyPool()
1080 {
1081     int64 nIndex = 0;
1082     CKeyPool keypool;
1083     ReserveKeyFromKeyPool(nIndex, keypool);
1084     KeepKey(nIndex);
1085     return keypool.vchPubKey;
1086 }
1087
1088 int64 CWallet::GetOldestKeyPoolTime()
1089 {
1090     int64 nIndex = 0;
1091     CKeyPool keypool;
1092     ReserveKeyFromKeyPool(nIndex, keypool);
1093     ReturnKey(nIndex);
1094     return keypool.nTime;
1095 }
1096
1097 vector<unsigned char> CReserveKey::GetReservedKey()
1098 {
1099     if (nIndex == -1)
1100     {
1101         CKeyPool keypool;
1102         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
1103         vchPubKey = keypool.vchPubKey;
1104     }
1105     assert(!vchPubKey.empty());
1106     return vchPubKey;
1107 }
1108
1109 void CReserveKey::KeepKey()
1110 {
1111     if (nIndex != -1)
1112         pwallet->KeepKey(nIndex);
1113     nIndex = -1;
1114     vchPubKey.clear();
1115 }
1116
1117 void CReserveKey::ReturnKey()
1118 {
1119     if (nIndex != -1)
1120         pwallet->ReturnKey(nIndex);
1121     nIndex = -1;
1122     vchPubKey.clear();
1123 }