OSDN Git Service

Add option to avoid spending unconfirmed change
[monacoin/monacoin.git] / src / wallet.cpp
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 COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "wallet.h"
7 #include "walletdb.h"
8 #include "crypter.h"
9 #include "ui_interface.h"
10 #include "base58.h"
11 #include "coincontrol.h"
12 #include <boost/algorithm/string/replace.hpp>
13
14 using namespace std;
15
16
17 bool bSpendZeroConfChange = true;
18
19 //////////////////////////////////////////////////////////////////////////////
20 //
21 // mapWallet
22 //
23
24 struct CompareValueOnly
25 {
26     bool operator()(const pair<int64, pair<const CWalletTx*, unsigned int> >& t1,
27                     const pair<int64, pair<const CWalletTx*, unsigned int> >& t2) const
28     {
29         return t1.first < t2.first;
30     }
31 };
32
33 CPubKey CWallet::GenerateNewKey()
34 {
35     bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
36
37     RandAddSeedPerfmon();
38     CKey secret;
39     secret.MakeNewKey(fCompressed);
40
41     // Compressed public keys were introduced in version 0.6.0
42     if (fCompressed)
43         SetMinVersion(FEATURE_COMPRPUBKEY);
44
45     CPubKey pubkey = secret.GetPubKey();
46     if (!AddKeyPubKey(secret, pubkey))
47         throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
48     return pubkey;
49 }
50
51 bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
52 {
53     if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
54         return false;
55     if (!fFileBacked)
56         return true;
57     if (!IsCrypted()) {
58         return CWalletDB(strWalletFile).WriteKey(pubkey, secret.GetPrivKey());
59     }
60     return true;
61 }
62
63 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
64 {
65     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
66         return false;
67     if (!fFileBacked)
68         return true;
69     {
70         LOCK(cs_wallet);
71         if (pwalletdbEncryption)
72             return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
73         else
74             return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
75     }
76     return false;
77 }
78
79 bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
80 {
81     return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
82 }
83
84 bool CWallet::AddCScript(const CScript& redeemScript)
85 {
86     if (!CCryptoKeyStore::AddCScript(redeemScript))
87         return false;
88     if (!fFileBacked)
89         return true;
90     return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
91 }
92
93 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
94 {
95     if (!IsLocked())
96         return false;
97
98     CCrypter crypter;
99     CKeyingMaterial vMasterKey;
100
101     {
102         LOCK(cs_wallet);
103         BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
104         {
105             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
106                 return false;
107             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
108                 return false;
109             if (CCryptoKeyStore::Unlock(vMasterKey))
110                 return true;
111         }
112     }
113     return false;
114 }
115
116 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
117 {
118     bool fWasLocked = IsLocked();
119
120     {
121         LOCK(cs_wallet);
122         Lock();
123
124         CCrypter crypter;
125         CKeyingMaterial vMasterKey;
126         BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
127         {
128             if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
129                 return false;
130             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
131                 return false;
132             if (CCryptoKeyStore::Unlock(vMasterKey))
133             {
134                 int64 nStartTime = GetTimeMillis();
135                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
136                 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
137
138                 nStartTime = GetTimeMillis();
139                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
140                 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
141
142                 if (pMasterKey.second.nDeriveIterations < 25000)
143                     pMasterKey.second.nDeriveIterations = 25000;
144
145                 printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
146
147                 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
148                     return false;
149                 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
150                     return false;
151                 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
152                 if (fWasLocked)
153                     Lock();
154                 return true;
155             }
156         }
157     }
158
159     return false;
160 }
161
162 void CWallet::SetBestChain(const CBlockLocator& loc)
163 {
164     CWalletDB walletdb(strWalletFile);
165     walletdb.WriteBestBlock(loc);
166 }
167
168 // This class implements an addrIncoming entry that causes pre-0.4
169 // clients to crash on startup if reading a private-key-encrypted wallet.
170 class CCorruptAddress
171 {
172 public:
173     IMPLEMENT_SERIALIZE
174     (
175         if (nType & SER_DISK)
176             READWRITE(nVersion);
177     )
178 };
179
180 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
181 {
182     if (nWalletVersion >= nVersion)
183         return true;
184
185     // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
186     if (fExplicit && nVersion > nWalletMaxVersion)
187             nVersion = FEATURE_LATEST;
188
189     nWalletVersion = nVersion;
190
191     if (nVersion > nWalletMaxVersion)
192         nWalletMaxVersion = nVersion;
193
194     if (fFileBacked)
195     {
196         CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
197         if (nWalletVersion >= 40000)
198         {
199             // Versions prior to 0.4.0 did not support the "minversion" record.
200             // Use a CCorruptAddress to make them crash instead.
201             CCorruptAddress corruptAddress;
202             pwalletdb->WriteSetting("addrIncoming", corruptAddress);
203         }
204         if (nWalletVersion > 40000)
205             pwalletdb->WriteMinVersion(nWalletVersion);
206         if (!pwalletdbIn)
207             delete pwalletdb;
208     }
209
210     return true;
211 }
212
213 bool CWallet::SetMaxVersion(int nVersion)
214 {
215     // cannot downgrade below current version
216     if (nWalletVersion > nVersion)
217         return false;
218
219     nWalletMaxVersion = nVersion;
220
221     return true;
222 }
223
224 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
225 {
226     if (IsCrypted())
227         return false;
228
229     CKeyingMaterial vMasterKey;
230     RandAddSeedPerfmon();
231
232     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
233     RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
234
235     CMasterKey kMasterKey;
236
237     RandAddSeedPerfmon();
238     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
239     RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
240
241     CCrypter crypter;
242     int64 nStartTime = GetTimeMillis();
243     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
244     kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
245
246     nStartTime = GetTimeMillis();
247     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
248     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
249
250     if (kMasterKey.nDeriveIterations < 25000)
251         kMasterKey.nDeriveIterations = 25000;
252
253     printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
254
255     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
256         return false;
257     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
258         return false;
259
260     {
261         LOCK(cs_wallet);
262         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
263         if (fFileBacked)
264         {
265             pwalletdbEncryption = new CWalletDB(strWalletFile);
266             if (!pwalletdbEncryption->TxnBegin())
267                 return false;
268             pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
269         }
270
271         if (!EncryptKeys(vMasterKey))
272         {
273             if (fFileBacked)
274                 pwalletdbEncryption->TxnAbort();
275             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.
276         }
277
278         // Encryption was introduced in version 0.4.0
279         SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
280
281         if (fFileBacked)
282         {
283             if (!pwalletdbEncryption->TxnCommit())
284                 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.
285
286             delete pwalletdbEncryption;
287             pwalletdbEncryption = NULL;
288         }
289
290         Lock();
291         Unlock(strWalletPassphrase);
292         NewKeyPool();
293         Lock();
294
295         // Need to completely rewrite the wallet file; if we don't, bdb might keep
296         // bits of the unencrypted private key in slack space in the database file.
297         CDB::Rewrite(strWalletFile);
298
299     }
300     NotifyStatusChanged(this);
301
302     return true;
303 }
304
305 int64 CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
306 {
307     int64 nRet = nOrderPosNext++;
308     if (pwalletdb) {
309         pwalletdb->WriteOrderPosNext(nOrderPosNext);
310     } else {
311         CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
312     }
313     return nRet;
314 }
315
316 CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
317 {
318     CWalletDB walletdb(strWalletFile);
319
320     // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
321     TxItems txOrdered;
322
323     // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
324     // would make this much faster for applications that do this a lot.
325     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
326     {
327         CWalletTx* wtx = &((*it).second);
328         txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
329     }
330     acentries.clear();
331     walletdb.ListAccountCreditDebit(strAccount, acentries);
332     BOOST_FOREACH(CAccountingEntry& entry, acentries)
333     {
334         txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
335     }
336
337     return txOrdered;
338 }
339
340 void CWallet::WalletUpdateSpent(const CTransaction &tx)
341 {
342     // Anytime a signature is successfully verified, it's proof the outpoint is spent.
343     // Update the wallet spent flag if it doesn't know due to wallet.dat being
344     // restored from backup or the user making copies of wallet.dat.
345     {
346         LOCK(cs_wallet);
347         BOOST_FOREACH(const CTxIn& txin, tx.vin)
348         {
349             map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
350             if (mi != mapWallet.end())
351             {
352                 CWalletTx& wtx = (*mi).second;
353                 if (txin.prevout.n >= wtx.vout.size())
354                     printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
355                 else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
356                 {
357                     printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
358                     wtx.MarkSpent(txin.prevout.n);
359                     wtx.WriteToDisk();
360                     NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED);
361                 }
362             }
363         }
364     }
365 }
366
367 void CWallet::MarkDirty()
368 {
369     {
370         LOCK(cs_wallet);
371         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
372             item.second.MarkDirty();
373     }
374 }
375
376 bool CWallet::AddToWallet(const CWalletTx& wtxIn)
377 {
378     uint256 hash = wtxIn.GetHash();
379     {
380         LOCK(cs_wallet);
381         // Inserts only if not already there, returns tx inserted or tx found
382         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
383         CWalletTx& wtx = (*ret.first).second;
384         wtx.BindWallet(this);
385         bool fInsertedNew = ret.second;
386         if (fInsertedNew)
387         {
388             wtx.nTimeReceived = GetAdjustedTime();
389             wtx.nOrderPos = IncOrderPosNext();
390
391             wtx.nTimeSmart = wtx.nTimeReceived;
392             if (wtxIn.hashBlock != 0)
393             {
394                 if (mapBlockIndex.count(wtxIn.hashBlock))
395                 {
396                     unsigned int latestNow = wtx.nTimeReceived;
397                     unsigned int latestEntry = 0;
398                     {
399                         // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
400                         int64 latestTolerated = latestNow + 300;
401                         std::list<CAccountingEntry> acentries;
402                         TxItems txOrdered = OrderedTxItems(acentries);
403                         for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
404                         {
405                             CWalletTx *const pwtx = (*it).second.first;
406                             if (pwtx == &wtx)
407                                 continue;
408                             CAccountingEntry *const pacentry = (*it).second.second;
409                             int64 nSmartTime;
410                             if (pwtx)
411                             {
412                                 nSmartTime = pwtx->nTimeSmart;
413                                 if (!nSmartTime)
414                                     nSmartTime = pwtx->nTimeReceived;
415                             }
416                             else
417                                 nSmartTime = pacentry->nTime;
418                             if (nSmartTime <= latestTolerated)
419                             {
420                                 latestEntry = nSmartTime;
421                                 if (nSmartTime > latestNow)
422                                     latestNow = nSmartTime;
423                                 break;
424                             }
425                         }
426                     }
427
428                     unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime;
429                     wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
430                 }
431                 else
432                     printf("AddToWallet() : found %s in block %s not in index\n",
433                            wtxIn.GetHash().ToString().c_str(),
434                            wtxIn.hashBlock.ToString().c_str());
435             }
436         }
437
438         bool fUpdated = false;
439         if (!fInsertedNew)
440         {
441             // Merge
442             if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
443             {
444                 wtx.hashBlock = wtxIn.hashBlock;
445                 fUpdated = true;
446             }
447             if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
448             {
449                 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
450                 wtx.nIndex = wtxIn.nIndex;
451                 fUpdated = true;
452             }
453             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
454             {
455                 wtx.fFromMe = wtxIn.fFromMe;
456                 fUpdated = true;
457             }
458             fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
459         }
460
461         //// debug print
462         printf("AddToWallet %s  %s%s\n", wtxIn.GetHash().ToString().c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
463
464         // Write to disk
465         if (fInsertedNew || fUpdated)
466             if (!wtx.WriteToDisk())
467                 return false;
468 #ifndef QT_GUI
469         // If default receiving address gets used, replace it with a new one
470         if (vchDefaultKey.IsValid()) {
471             CScript scriptDefaultKey;
472             scriptDefaultKey.SetDestination(vchDefaultKey.GetID());
473             BOOST_FOREACH(const CTxOut& txout, wtx.vout)
474             {
475                 if (txout.scriptPubKey == scriptDefaultKey)
476                 {
477                     CPubKey newDefaultKey;
478                     if (GetKeyFromPool(newDefaultKey, false))
479                     {
480                         SetDefaultKey(newDefaultKey);
481                         SetAddressBookName(vchDefaultKey.GetID(), "");
482                     }
483                 }
484             }
485         }
486 #endif
487         // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
488         WalletUpdateSpent(wtx);
489
490         // Notify UI of new or updated transaction
491         NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
492
493         // notify an external script when a wallet transaction comes in or is updated
494         std::string strCmd = GetArg("-walletnotify", "");
495
496         if ( !strCmd.empty())
497         {
498             boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
499             boost::thread t(runCommand, strCmd); // thread runs free
500         }
501
502     }
503     return true;
504 }
505
506 // Add a transaction to the wallet, or update it.
507 // pblock is optional, but should be provided if the transaction is known to be in a block.
508 // If fUpdate is true, existing transactions will be updated.
509 bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
510 {
511     {
512         LOCK(cs_wallet);
513         bool fExisted = mapWallet.count(hash);
514         if (fExisted && !fUpdate) return false;
515         if (fExisted || IsMine(tx) || IsFromMe(tx))
516         {
517             CWalletTx wtx(this,tx);
518             // Get merkle branch if transaction was found in a block
519             if (pblock)
520                 wtx.SetMerkleBranch(pblock);
521             return AddToWallet(wtx);
522         }
523         else
524             WalletUpdateSpent(tx);
525     }
526     return false;
527 }
528
529 bool CWallet::EraseFromWallet(uint256 hash)
530 {
531     if (!fFileBacked)
532         return false;
533     {
534         LOCK(cs_wallet);
535         if (mapWallet.erase(hash))
536             CWalletDB(strWalletFile).EraseTx(hash);
537     }
538     return true;
539 }
540
541
542 bool CWallet::IsMine(const CTxIn &txin) const
543 {
544     {
545         LOCK(cs_wallet);
546         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
547         if (mi != mapWallet.end())
548         {
549             const CWalletTx& prev = (*mi).second;
550             if (txin.prevout.n < prev.vout.size())
551                 if (IsMine(prev.vout[txin.prevout.n]))
552                     return true;
553         }
554     }
555     return false;
556 }
557
558 int64 CWallet::GetDebit(const CTxIn &txin) const
559 {
560     {
561         LOCK(cs_wallet);
562         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
563         if (mi != mapWallet.end())
564         {
565             const CWalletTx& prev = (*mi).second;
566             if (txin.prevout.n < prev.vout.size())
567                 if (IsMine(prev.vout[txin.prevout.n]))
568                     return prev.vout[txin.prevout.n].nValue;
569         }
570     }
571     return 0;
572 }
573
574 bool CWallet::IsChange(const CTxOut& txout) const
575 {
576     CTxDestination address;
577
578     // TODO: fix handling of 'change' outputs. The assumption is that any
579     // payment to a TX_PUBKEYHASH that is mine but isn't in the address book
580     // is change. That assumption is likely to break when we implement multisignature
581     // wallets that return change back into a multi-signature-protected address;
582     // a better way of identifying which outputs are 'the send' and which are
583     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
584     // which output, if any, was change).
585     if (ExtractDestination(txout.scriptPubKey, address) && ::IsMine(*this, address))
586     {
587         LOCK(cs_wallet);
588         if (!mapAddressBook.count(address))
589             return true;
590     }
591     return false;
592 }
593
594 int64 CWalletTx::GetTxTime() const
595 {
596     int64 n = nTimeSmart;
597     return n ? n : nTimeReceived;
598 }
599
600 int CWalletTx::GetRequestCount() const
601 {
602     // Returns -1 if it wasn't being tracked
603     int nRequests = -1;
604     {
605         LOCK(pwallet->cs_wallet);
606         if (IsCoinBase())
607         {
608             // Generated block
609             if (hashBlock != 0)
610             {
611                 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
612                 if (mi != pwallet->mapRequestCount.end())
613                     nRequests = (*mi).second;
614             }
615         }
616         else
617         {
618             // Did anyone request this transaction?
619             map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
620             if (mi != pwallet->mapRequestCount.end())
621             {
622                 nRequests = (*mi).second;
623
624                 // How about the block it's in?
625                 if (nRequests == 0 && hashBlock != 0)
626                 {
627                     map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
628                     if (mi != pwallet->mapRequestCount.end())
629                         nRequests = (*mi).second;
630                     else
631                         nRequests = 1; // If it's in someone else's block it must have got out
632                 }
633             }
634         }
635     }
636     return nRequests;
637 }
638
639 void CWalletTx::GetAmounts(list<pair<CTxDestination, int64> >& listReceived,
640                            list<pair<CTxDestination, int64> >& listSent, int64& nFee, string& strSentAccount) const
641 {
642     nFee = 0;
643     listReceived.clear();
644     listSent.clear();
645     strSentAccount = strFromAccount;
646
647     // Compute fee:
648     int64 nDebit = GetDebit();
649     if (nDebit > 0) // debit>0 means we signed/sent this transaction
650     {
651         int64 nValueOut = GetValueOut();
652         nFee = nDebit - nValueOut;
653     }
654
655     // Sent/received.
656     BOOST_FOREACH(const CTxOut& txout, vout)
657     {
658         bool fIsMine;
659         // Only need to handle txouts if AT LEAST one of these is true:
660         //   1) they debit from us (sent)
661         //   2) the output is to us (received)
662         if (nDebit > 0)
663         {
664             // Don't report 'change' txouts
665             if (pwallet->IsChange(txout))
666                 continue;
667             fIsMine = pwallet->IsMine(txout);
668         }
669         else if (!(fIsMine = pwallet->IsMine(txout)))
670             continue;
671
672         // In either case, we need to get the destination address
673         CTxDestination address;
674         if (!ExtractDestination(txout.scriptPubKey, address))
675         {
676             printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
677                    this->GetHash().ToString().c_str());
678             address = CNoDestination();
679         }
680
681         // If we are debited by the transaction, add the output as a "sent" entry
682         if (nDebit > 0)
683             listSent.push_back(make_pair(address, txout.nValue));
684
685         // If we are receiving the output, add it as a "received" entry
686         if (fIsMine)
687             listReceived.push_back(make_pair(address, txout.nValue));
688     }
689
690 }
691
692 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nReceived,
693                                   int64& nSent, int64& nFee) const
694 {
695     nReceived = nSent = nFee = 0;
696
697     int64 allFee;
698     string strSentAccount;
699     list<pair<CTxDestination, int64> > listReceived;
700     list<pair<CTxDestination, int64> > listSent;
701     GetAmounts(listReceived, listSent, allFee, strSentAccount);
702
703     if (strAccount == strSentAccount)
704     {
705         BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent)
706             nSent += s.second;
707         nFee = allFee;
708     }
709     {
710         LOCK(pwallet->cs_wallet);
711         BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
712         {
713             if (pwallet->mapAddressBook.count(r.first))
714             {
715                 map<CTxDestination, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
716                 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
717                     nReceived += r.second;
718             }
719             else if (strAccount.empty())
720             {
721                 nReceived += r.second;
722             }
723         }
724     }
725 }
726
727 void CWalletTx::AddSupportingTransactions()
728 {
729     vtxPrev.clear();
730
731     const int COPY_DEPTH = 3;
732     if (SetMerkleBranch() < COPY_DEPTH)
733     {
734         vector<uint256> vWorkQueue;
735         BOOST_FOREACH(const CTxIn& txin, vin)
736             vWorkQueue.push_back(txin.prevout.hash);
737
738         {
739             LOCK(pwallet->cs_wallet);
740             map<uint256, const CMerkleTx*> mapWalletPrev;
741             set<uint256> setAlreadyDone;
742             for (unsigned int i = 0; i < vWorkQueue.size(); i++)
743             {
744                 uint256 hash = vWorkQueue[i];
745                 if (setAlreadyDone.count(hash))
746                     continue;
747                 setAlreadyDone.insert(hash);
748
749                 CMerkleTx tx;
750                 map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
751                 if (mi != pwallet->mapWallet.end())
752                 {
753                     tx = (*mi).second;
754                     BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
755                         mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
756                 }
757                 else if (mapWalletPrev.count(hash))
758                 {
759                     tx = *mapWalletPrev[hash];
760                 }
761                 else
762                 {
763                     continue;
764                 }
765
766                 int nDepth = tx.SetMerkleBranch();
767                 vtxPrev.push_back(tx);
768
769                 if (nDepth < COPY_DEPTH)
770                 {
771                     BOOST_FOREACH(const CTxIn& txin, tx.vin)
772                         vWorkQueue.push_back(txin.prevout.hash);
773                 }
774             }
775         }
776     }
777
778     reverse(vtxPrev.begin(), vtxPrev.end());
779 }
780
781 bool CWalletTx::WriteToDisk()
782 {
783     return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
784 }
785
786 // Scan the block chain (starting in pindexStart) for transactions
787 // from or to us. If fUpdate is true, found transactions that already
788 // exist in the wallet will be updated.
789 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
790 {
791     int ret = 0;
792
793     CBlockIndex* pindex = pindexStart;
794     {
795         LOCK(cs_wallet);
796         while (pindex)
797         {
798             CBlock block;
799             block.ReadFromDisk(pindex);
800             BOOST_FOREACH(CTransaction& tx, block.vtx)
801             {
802                 if (AddToWalletIfInvolvingMe(tx.GetHash(), tx, &block, fUpdate))
803                     ret++;
804             }
805             pindex = pindex->pnext;
806         }
807     }
808     return ret;
809 }
810
811 void CWallet::ReacceptWalletTransactions()
812 {
813     bool fRepeat = true;
814     while (fRepeat)
815     {
816         LOCK(cs_wallet);
817         fRepeat = false;
818         bool fMissing = false;
819         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
820         {
821             CWalletTx& wtx = item.second;
822             if (wtx.IsCoinBase() && wtx.IsSpent(0))
823                 continue;
824
825             CCoins coins;
826             bool fUpdated = false;
827             bool fFound = pcoinsTip->GetCoins(wtx.GetHash(), coins);
828             if (fFound || wtx.GetDepthInMainChain() > 0)
829             {
830                 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
831                 for (unsigned int i = 0; i < wtx.vout.size(); i++)
832                 {
833                     if (wtx.IsSpent(i))
834                         continue;
835                     if ((i >= coins.vout.size() || coins.vout[i].IsNull()) && IsMine(wtx.vout[i]))
836                     {
837                         wtx.MarkSpent(i);
838                         fUpdated = true;
839                         fMissing = true;
840                     }
841                 }
842                 if (fUpdated)
843                 {
844                     printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
845                     wtx.MarkDirty();
846                     wtx.WriteToDisk();
847                 }
848             }
849             else
850             {
851                 // Re-accept any txes of ours that aren't already in a block
852                 if (!wtx.IsCoinBase())
853                     wtx.AcceptWalletTransaction(false);
854             }
855         }
856         if (fMissing)
857         {
858             // TODO: optimize this to scan just part of the block chain?
859             if (ScanForWalletTransactions(pindexGenesisBlock))
860                 fRepeat = true;  // Found missing transactions: re-do re-accept.
861         }
862     }
863 }
864
865 void CWalletTx::RelayWalletTransaction()
866 {
867     BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
868     {
869         // Important: versions of bitcoin before 0.8.6 had a bug that inserted
870         // empty transactions into the vtxPrev, which will cause the node to be
871         // banned when retransmitted, hence the check for !tx.vin.empty()
872         if (!tx.IsCoinBase() && !tx.vin.empty())
873             if (tx.GetDepthInMainChain() == 0)
874                 RelayTransaction((CTransaction)tx, tx.GetHash());
875     }
876     if (!IsCoinBase())
877     {
878         if (GetDepthInMainChain() == 0) {
879             uint256 hash = GetHash();
880             printf("Relaying wtx %s\n", hash.ToString().c_str());
881             RelayTransaction((CTransaction)*this, hash);
882         }
883     }
884 }
885
886 void CWallet::ResendWalletTransactions()
887 {
888     // Do this infrequently and randomly to avoid giving away
889     // that these are our transactions.
890     static int64 nNextTime;
891     if (GetTime() < nNextTime)
892         return;
893     bool fFirst = (nNextTime == 0);
894     nNextTime = GetTime() + GetRand(30 * 60);
895     if (fFirst)
896         return;
897
898     // Only do it if there's been a new block since last time
899     static int64 nLastTime;
900     if (nTimeBestReceived < nLastTime)
901         return;
902     nLastTime = GetTime();
903
904     // Rebroadcast any of our txes that aren't in a block yet
905     printf("ResendWalletTransactions()\n");
906     {
907         LOCK(cs_wallet);
908         // Sort them in chronological order
909         multimap<unsigned int, CWalletTx*> mapSorted;
910         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
911         {
912             CWalletTx& wtx = item.second;
913             // Don't rebroadcast until it's had plenty of time that
914             // it should have gotten in already by now.
915             if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
916                 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
917         }
918         BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
919         {
920             CWalletTx& wtx = *item.second;
921             wtx.RelayWalletTransaction();
922         }
923     }
924 }
925
926
927
928
929
930
931 //////////////////////////////////////////////////////////////////////////////
932 //
933 // Actions
934 //
935
936
937 int64 CWallet::GetBalance() const
938 {
939     int64 nTotal = 0;
940     {
941         LOCK(cs_wallet);
942         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
943         {
944             const CWalletTx* pcoin = &(*it).second;
945             if (pcoin->IsConfirmed())
946                 nTotal += pcoin->GetAvailableCredit();
947         }
948     }
949
950     return nTotal;
951 }
952
953 int64 CWallet::GetUnconfirmedBalance() const
954 {
955     int64 nTotal = 0;
956     {
957         LOCK(cs_wallet);
958         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
959         {
960             const CWalletTx* pcoin = &(*it).second;
961             if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
962                 nTotal += pcoin->GetAvailableCredit();
963         }
964     }
965     return nTotal;
966 }
967
968 int64 CWallet::GetImmatureBalance() const
969 {
970     int64 nTotal = 0;
971     {
972         LOCK(cs_wallet);
973         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
974         {
975             const CWalletTx* pcoin = &(*it).second;
976             nTotal += pcoin->GetImmatureCredit();
977         }
978     }
979     return nTotal;
980 }
981
982 // populate vCoins with vector of spendable COutputs
983 void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const
984 {
985     vCoins.clear();
986
987     {
988         LOCK(cs_wallet);
989         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
990         {
991             const CWalletTx* pcoin = &(*it).second;
992
993             if (!pcoin->IsFinal())
994                 continue;
995
996             if (fOnlyConfirmed && !pcoin->IsConfirmed())
997                 continue;
998
999             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1000                 continue;
1001
1002             for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
1003                 if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) &&
1004                     !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue >= nMinimumInputValue &&
1005                     (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) 
1006                         vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain()));
1007             }
1008         }
1009     }
1010 }
1011
1012 static void ApproximateBestSubset(vector<pair<int64, pair<const CWalletTx*,unsigned int> > >vValue, int64 nTotalLower, int64 nTargetValue,
1013                                   vector<char>& vfBest, int64& nBest, int iterations = 1000)
1014 {
1015     vector<char> vfIncluded;
1016
1017     vfBest.assign(vValue.size(), true);
1018     nBest = nTotalLower;
1019
1020     seed_insecure_rand();
1021
1022     for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
1023     {
1024         vfIncluded.assign(vValue.size(), false);
1025         int64 nTotal = 0;
1026         bool fReachedTarget = false;
1027         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
1028         {
1029             for (unsigned int i = 0; i < vValue.size(); i++)
1030             {
1031                 //The solver here uses a randomized algorithm,
1032                 //the randomness serves no real security purpose but is just
1033                 //needed to prevent degenerate behavior and it is important
1034                 //that the rng fast. We do not use a constant random sequence,
1035                 //because there may be some privacy improvement by making
1036                 //the selection random.
1037                 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
1038                 {
1039                     nTotal += vValue[i].first;
1040                     vfIncluded[i] = true;
1041                     if (nTotal >= nTargetValue)
1042                     {
1043                         fReachedTarget = true;
1044                         if (nTotal < nBest)
1045                         {
1046                             nBest = nTotal;
1047                             vfBest = vfIncluded;
1048                         }
1049                         nTotal -= vValue[i].first;
1050                         vfIncluded[i] = false;
1051                     }
1052                 }
1053             }
1054         }
1055     }
1056 }
1057
1058 bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
1059                                  set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
1060 {
1061     setCoinsRet.clear();
1062     nValueRet = 0;
1063
1064     // List of values less than target
1065     pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
1066     coinLowestLarger.first = std::numeric_limits<int64>::max();
1067     coinLowestLarger.second.first = NULL;
1068     vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
1069     int64 nTotalLower = 0;
1070
1071     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
1072
1073     BOOST_FOREACH(COutput output, vCoins)
1074     {
1075         const CWalletTx *pcoin = output.tx;
1076
1077         if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
1078             continue;
1079
1080         int i = output.i;
1081         int64 n = pcoin->vout[i].nValue;
1082
1083         pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
1084
1085         if (n == nTargetValue)
1086         {
1087             setCoinsRet.insert(coin.second);
1088             nValueRet += coin.first;
1089             return true;
1090         }
1091         else if (n < nTargetValue + CENT)
1092         {
1093             vValue.push_back(coin);
1094             nTotalLower += n;
1095         }
1096         else if (n < coinLowestLarger.first)
1097         {
1098             coinLowestLarger = coin;
1099         }
1100     }
1101
1102     if (nTotalLower == nTargetValue)
1103     {
1104         for (unsigned int i = 0; i < vValue.size(); ++i)
1105         {
1106             setCoinsRet.insert(vValue[i].second);
1107             nValueRet += vValue[i].first;
1108         }
1109         return true;
1110     }
1111
1112     if (nTotalLower < nTargetValue)
1113     {
1114         if (coinLowestLarger.second.first == NULL)
1115             return false;
1116         setCoinsRet.insert(coinLowestLarger.second);
1117         nValueRet += coinLowestLarger.first;
1118         return true;
1119     }
1120
1121     // Solve subset sum by stochastic approximation
1122     sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
1123     vector<char> vfBest;
1124     int64 nBest;
1125
1126     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
1127     if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
1128         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
1129
1130     // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
1131     //                                   or the next bigger coin is closer), return the bigger coin
1132     if (coinLowestLarger.second.first &&
1133         ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
1134     {
1135         setCoinsRet.insert(coinLowestLarger.second);
1136         nValueRet += coinLowestLarger.first;
1137     }
1138     else {
1139         for (unsigned int i = 0; i < vValue.size(); i++)
1140             if (vfBest[i])
1141             {
1142                 setCoinsRet.insert(vValue[i].second);
1143                 nValueRet += vValue[i].first;
1144             }
1145
1146         //// debug print
1147         printf("SelectCoins() best subset: ");
1148         for (unsigned int i = 0; i < vValue.size(); i++)
1149             if (vfBest[i])
1150                 printf("%s ", FormatMoney(vValue[i].first).c_str());
1151         printf("total %s\n", FormatMoney(nBest).c_str());
1152     }
1153
1154     return true;
1155 }
1156
1157 bool CWallet::SelectCoins(int64 nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet, const CCoinControl* coinControl) const
1158 {
1159     vector<COutput> vCoins;
1160     AvailableCoins(vCoins, true, coinControl);
1161     
1162     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
1163     if (coinControl && coinControl->HasSelected())
1164     {
1165         BOOST_FOREACH(const COutput& out, vCoins)
1166         {
1167             nValueRet += out.tx->vout[out.i].nValue;
1168             setCoinsRet.insert(make_pair(out.tx, out.i));
1169         }
1170         return (nValueRet >= nTargetValue);
1171     }
1172
1173     return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) ||
1174             SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) ||
1175             (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)));
1176 }
1177
1178
1179
1180
1181 bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend,
1182                                 CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
1183 {
1184     int64 nValue = 0;
1185     BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1186     {
1187         if (nValue < 0)
1188         {
1189             strFailReason = _("Transaction amounts must be positive");
1190             return false;
1191         }
1192         nValue += s.second;
1193     }
1194     if (vecSend.empty() || nValue < 0)
1195     {
1196         strFailReason = _("Transaction amounts must be positive");
1197         return false;
1198     }
1199
1200     wtxNew.BindWallet(this);
1201
1202     {
1203         LOCK2(cs_main, cs_wallet);
1204         {
1205             nFeeRet = nTransactionFee;
1206             loop
1207             {
1208                 wtxNew.vin.clear();
1209                 wtxNew.vout.clear();
1210                 wtxNew.fFromMe = true;
1211
1212                 int64 nTotalValue = nValue + nFeeRet;
1213                 double dPriority = 0;
1214                 // vouts to the payees
1215                 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1216                 {
1217                     CTxOut txout(s.second, s.first);
1218                     if (txout.IsDust())
1219                     {
1220                         strFailReason = _("Transaction amount too small");
1221                         return false;
1222                     }
1223                     wtxNew.vout.push_back(txout);
1224                 }
1225
1226                 // Choose coins to use
1227                 set<pair<const CWalletTx*,unsigned int> > setCoins;
1228                 int64 nValueIn = 0;
1229                 if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl))
1230                 {
1231                     strFailReason = _("Insufficient funds");
1232                     return false;
1233                 }
1234                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1235                 {
1236                     int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
1237                     //The priority after the next block (depth+1) is used instead of the current,
1238                     //reflecting an assumption the user would accept a bit more delay for
1239                     //a chance at a free transaction.
1240                     dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1);
1241                 }
1242
1243                 int64 nChange = nValueIn - nValue - nFeeRet;
1244                 // if sub-cent change is required, the fee must be raised to at least nMinTxFee
1245                 // or until nChange becomes zero
1246                 // NOTE: this depends on the exact behaviour of GetMinFee
1247                 if (nFeeRet < CTransaction::nMinTxFee && nChange > 0 && nChange < CENT)
1248                 {
1249                     int64 nMoveToFee = min(nChange, CTransaction::nMinTxFee - nFeeRet);
1250                     nChange -= nMoveToFee;
1251                     nFeeRet += nMoveToFee;
1252                 }
1253
1254                 if (nChange > 0)
1255                 {
1256                     // Fill a vout to ourself
1257                     // TODO: pass in scriptChange instead of reservekey so
1258                     // change transaction isn't always pay-to-bitcoin-address
1259                     CScript scriptChange;
1260                     
1261                     // coin control: send change to custom address
1262                     if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
1263                         scriptChange.SetDestination(coinControl->destChange);
1264                         
1265                     // no coin control: send change to newly generated address
1266                     else
1267                     {
1268                         // Note: We use a new key here to keep it from being obvious which side is the change.
1269                         //  The drawback is that by not reusing a previous key, the change may be lost if a
1270                         //  backup is restored, if the backup doesn't have the new private key for the change.
1271                         //  If we reused the old key, it would be possible to add code to look for and
1272                         //  rediscover unknown transactions that were written with keys of ours to recover
1273                         //  post-backup change.
1274
1275                         // Reserve a new key pair from key pool
1276                         CPubKey vchPubKey;
1277                         assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
1278
1279                         scriptChange.SetDestination(vchPubKey.GetID());
1280                     }
1281
1282                     CTxOut newTxOut(nChange, scriptChange);
1283
1284                     // Never create dust outputs; if we would, just
1285                     // add the dust to the fee.
1286                     if (newTxOut.IsDust())
1287                     {
1288                         nFeeRet += nChange;
1289                         reservekey.ReturnKey();
1290                     }
1291                     else
1292                     {
1293                         // Insert change txn at random position:
1294                         vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()+1);
1295                         wtxNew.vout.insert(position, newTxOut);
1296                     }
1297                 }
1298                 else
1299                     reservekey.ReturnKey();
1300
1301                 // Fill vin
1302                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1303                     wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
1304
1305                 // Sign
1306                 int nIn = 0;
1307                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1308                     if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
1309                     {
1310                         strFailReason = _("Signing transaction failed");
1311                         return false;
1312                     }
1313
1314                 // Limit size
1315                 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
1316                 if (nBytes >= MAX_STANDARD_TX_SIZE)
1317                 {
1318                     strFailReason = _("Transaction too large");
1319                     return false;
1320                 }
1321                 dPriority /= nBytes;
1322
1323                 // Check that enough fee is included
1324                 int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
1325                 bool fAllowFree = CTransaction::AllowFree(dPriority);
1326                 int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND);
1327                 if (nFeeRet < max(nPayFee, nMinFee))
1328                 {
1329                     nFeeRet = max(nPayFee, nMinFee);
1330                     continue;
1331                 }
1332
1333                 // Fill vtxPrev by copying from previous transactions vtxPrev
1334                 wtxNew.AddSupportingTransactions();
1335                 wtxNew.fTimeReceivedIsTxTime = true;
1336
1337                 break;
1338             }
1339         }
1340     }
1341     return true;
1342 }
1343
1344 bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue,
1345                                 CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
1346 {
1347     vector< pair<CScript, int64> > vecSend;
1348     vecSend.push_back(make_pair(scriptPubKey, nValue));
1349     return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl);
1350 }
1351
1352 // Call after CreateTransaction unless you want to abort
1353 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
1354 {
1355     {
1356         LOCK2(cs_main, cs_wallet);
1357         printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
1358         {
1359             // This is only to keep the database open to defeat the auto-flush for the
1360             // duration of this scope.  This is the only place where this optimization
1361             // maybe makes sense; please don't do it anywhere else.
1362             CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
1363
1364             // Take key pair from key pool so it won't be used again
1365             reservekey.KeepKey();
1366
1367             // Add tx to wallet, because if it has change it's also ours,
1368             // otherwise just for transaction history.
1369             AddToWallet(wtxNew);
1370
1371             // Mark old coins as spent
1372             set<CWalletTx*> setCoins;
1373             BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
1374             {
1375                 CWalletTx &coin = mapWallet[txin.prevout.hash];
1376                 coin.BindWallet(this);
1377                 coin.MarkSpent(txin.prevout.n);
1378                 coin.WriteToDisk();
1379                 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
1380             }
1381
1382             if (fFileBacked)
1383                 delete pwalletdb;
1384         }
1385
1386         // Track how many getdata requests our transaction gets
1387         mapRequestCount[wtxNew.GetHash()] = 0;
1388
1389         // Broadcast
1390         if (!wtxNew.AcceptToMemoryPool(true, false))
1391         {
1392             // This must not fail. The transaction has already been signed and recorded.
1393             printf("CommitTransaction() : Error: Transaction not valid");
1394             return false;
1395         }
1396         wtxNew.RelayWalletTransaction();
1397     }
1398     return true;
1399 }
1400
1401
1402
1403
1404 string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
1405 {
1406     CReserveKey reservekey(this);
1407     int64 nFeeRequired;
1408
1409     if (IsLocked())
1410     {
1411         string strError = _("Error: Wallet locked, unable to create transaction!");
1412         printf("SendMoney() : %s", strError.c_str());
1413         return strError;
1414     }
1415     string strError;
1416     if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError))
1417     {
1418         if (nValue + nFeeRequired > GetBalance())
1419             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());
1420         printf("SendMoney() : %s\n", strError.c_str());
1421         return strError;
1422     }
1423
1424     if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired))
1425         return "ABORTED";
1426
1427     if (!CommitTransaction(wtxNew, reservekey))
1428         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.");
1429
1430     return "";
1431 }
1432
1433
1434
1435 string CWallet::SendMoneyToDestination(const CTxDestination& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
1436 {
1437     // Check amount
1438     if (nValue <= 0)
1439         return _("Invalid amount");
1440     if (nValue + nTransactionFee > GetBalance())
1441         return _("Insufficient funds");
1442
1443     // Parse Bitcoin address
1444     CScript scriptPubKey;
1445     scriptPubKey.SetDestination(address);
1446
1447     return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
1448 }
1449
1450
1451
1452
1453 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
1454 {
1455     if (!fFileBacked)
1456         return DB_LOAD_OK;
1457     fFirstRunRet = false;
1458     DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
1459     if (nLoadWalletRet == DB_NEED_REWRITE)
1460     {
1461         if (CDB::Rewrite(strWalletFile, "\x04pool"))
1462         {
1463             setKeyPool.clear();
1464             // Note: can't top-up keypool here, because wallet is locked.
1465             // User will be prompted to unlock wallet the next operation
1466             // the requires a new key.
1467         }
1468     }
1469
1470     if (nLoadWalletRet != DB_LOAD_OK)
1471         return nLoadWalletRet;
1472     fFirstRunRet = !vchDefaultKey.IsValid();
1473
1474     return DB_LOAD_OK;
1475 }
1476
1477
1478 bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName)
1479 {
1480     std::map<CTxDestination, std::string>::iterator mi = mapAddressBook.find(address);
1481     mapAddressBook[address] = strName;
1482     NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
1483     if (!fFileBacked)
1484         return false;
1485     return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
1486 }
1487
1488 bool CWallet::DelAddressBookName(const CTxDestination& address)
1489 {
1490     mapAddressBook.erase(address);
1491     NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED);
1492     if (!fFileBacked)
1493         return false;
1494     return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
1495 }
1496
1497
1498 void CWallet::PrintWallet(const CBlock& block)
1499 {
1500     {
1501         LOCK(cs_wallet);
1502         if (mapWallet.count(block.vtx[0].GetHash()))
1503         {
1504             CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
1505             printf("    mine:  %d  %d  %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
1506         }
1507     }
1508     printf("\n");
1509 }
1510
1511 bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
1512 {
1513     {
1514         LOCK(cs_wallet);
1515         map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
1516         if (mi != mapWallet.end())
1517         {
1518             wtx = (*mi).second;
1519             return true;
1520         }
1521     }
1522     return false;
1523 }
1524
1525 bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
1526 {
1527     if (fFileBacked)
1528     {
1529         if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
1530             return false;
1531     }
1532     vchDefaultKey = vchPubKey;
1533     return true;
1534 }
1535
1536 bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
1537 {
1538     if (!pwallet->fFileBacked)
1539         return false;
1540     strWalletFileOut = pwallet->strWalletFile;
1541     return true;
1542 }
1543
1544 //
1545 // Mark old keypool keys as used,
1546 // and generate all new keys
1547 //
1548 bool CWallet::NewKeyPool()
1549 {
1550     {
1551         LOCK(cs_wallet);
1552         CWalletDB walletdb(strWalletFile);
1553         BOOST_FOREACH(int64 nIndex, setKeyPool)
1554             walletdb.ErasePool(nIndex);
1555         setKeyPool.clear();
1556
1557         if (IsLocked())
1558             return false;
1559
1560         int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
1561         for (int i = 0; i < nKeys; i++)
1562         {
1563             int64 nIndex = i+1;
1564             walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
1565             setKeyPool.insert(nIndex);
1566         }
1567         printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
1568     }
1569     return true;
1570 }
1571
1572 bool CWallet::TopUpKeyPool()
1573 {
1574     {
1575         LOCK(cs_wallet);
1576
1577         if (IsLocked())
1578             return false;
1579
1580         CWalletDB walletdb(strWalletFile);
1581
1582         // Top up key pool
1583         unsigned int nTargetSize = max(GetArg("-keypool", 100), 0LL);
1584         while (setKeyPool.size() < (nTargetSize + 1))
1585         {
1586             int64 nEnd = 1;
1587             if (!setKeyPool.empty())
1588                 nEnd = *(--setKeyPool.end()) + 1;
1589             if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
1590                 throw runtime_error("TopUpKeyPool() : writing generated key failed");
1591             setKeyPool.insert(nEnd);
1592             printf("keypool added key %"PRI64d", size=%"PRIszu"\n", nEnd, setKeyPool.size());
1593         }
1594     }
1595     return true;
1596 }
1597
1598 void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
1599 {
1600     nIndex = -1;
1601     keypool.vchPubKey = CPubKey();
1602     {
1603         LOCK(cs_wallet);
1604
1605         if (!IsLocked())
1606             TopUpKeyPool();
1607
1608         // Get the oldest key
1609         if(setKeyPool.empty())
1610             return;
1611
1612         CWalletDB walletdb(strWalletFile);
1613
1614         nIndex = *(setKeyPool.begin());
1615         setKeyPool.erase(setKeyPool.begin());
1616         if (!walletdb.ReadPool(nIndex, keypool))
1617             throw runtime_error("ReserveKeyFromKeyPool() : read failed");
1618         if (!HaveKey(keypool.vchPubKey.GetID()))
1619             throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
1620         assert(keypool.vchPubKey.IsValid());
1621         printf("keypool reserve %"PRI64d"\n", nIndex);
1622     }
1623 }
1624
1625 int64 CWallet::AddReserveKey(const CKeyPool& keypool)
1626 {
1627     {
1628         LOCK2(cs_main, cs_wallet);
1629         CWalletDB walletdb(strWalletFile);
1630
1631         int64 nIndex = 1 + *(--setKeyPool.end());
1632         if (!walletdb.WritePool(nIndex, keypool))
1633             throw runtime_error("AddReserveKey() : writing added key failed");
1634         setKeyPool.insert(nIndex);
1635         return nIndex;
1636     }
1637     return -1;
1638 }
1639
1640 void CWallet::KeepKey(int64 nIndex)
1641 {
1642     // Remove from key pool
1643     if (fFileBacked)
1644     {
1645         CWalletDB walletdb(strWalletFile);
1646         walletdb.ErasePool(nIndex);
1647     }
1648     printf("keypool keep %"PRI64d"\n", nIndex);
1649 }
1650
1651 void CWallet::ReturnKey(int64 nIndex)
1652 {
1653     // Return to key pool
1654     {
1655         LOCK(cs_wallet);
1656         setKeyPool.insert(nIndex);
1657     }
1658     printf("keypool return %"PRI64d"\n", nIndex);
1659 }
1660
1661 bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
1662 {
1663     int64 nIndex = 0;
1664     CKeyPool keypool;
1665     {
1666         LOCK(cs_wallet);
1667         ReserveKeyFromKeyPool(nIndex, keypool);
1668         if (nIndex == -1)
1669         {
1670             if (fAllowReuse && vchDefaultKey.IsValid())
1671             {
1672                 result = vchDefaultKey;
1673                 return true;
1674             }
1675             if (IsLocked()) return false;
1676             result = GenerateNewKey();
1677             return true;
1678         }
1679         KeepKey(nIndex);
1680         result = keypool.vchPubKey;
1681     }
1682     return true;
1683 }
1684
1685 int64 CWallet::GetOldestKeyPoolTime()
1686 {
1687     int64 nIndex = 0;
1688     CKeyPool keypool;
1689     ReserveKeyFromKeyPool(nIndex, keypool);
1690     if (nIndex == -1)
1691         return GetTime();
1692     ReturnKey(nIndex);
1693     return keypool.nTime;
1694 }
1695
1696 std::map<CTxDestination, int64> CWallet::GetAddressBalances()
1697 {
1698     map<CTxDestination, int64> balances;
1699
1700     {
1701         LOCK(cs_wallet);
1702         BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
1703         {
1704             CWalletTx *pcoin = &walletEntry.second;
1705
1706             if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
1707                 continue;
1708
1709             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1710                 continue;
1711
1712             int nDepth = pcoin->GetDepthInMainChain();
1713             if (nDepth < (pcoin->IsFromMe() ? 0 : 1))
1714                 continue;
1715
1716             for (unsigned int i = 0; i < pcoin->vout.size(); i++)
1717             {
1718                 CTxDestination addr;
1719                 if (!IsMine(pcoin->vout[i]))
1720                     continue;
1721                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
1722                     continue;
1723
1724                 int64 n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue;
1725
1726                 if (!balances.count(addr))
1727                     balances[addr] = 0;
1728                 balances[addr] += n;
1729             }
1730         }
1731     }
1732
1733     return balances;
1734 }
1735
1736 set< set<CTxDestination> > CWallet::GetAddressGroupings()
1737 {
1738     set< set<CTxDestination> > groupings;
1739     set<CTxDestination> grouping;
1740
1741     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
1742     {
1743         CWalletTx *pcoin = &walletEntry.second;
1744
1745         if (pcoin->vin.size() > 0)
1746         {
1747             bool any_mine = false;
1748             // group all input addresses with each other
1749             BOOST_FOREACH(CTxIn txin, pcoin->vin)
1750             {
1751                 CTxDestination address;
1752                 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
1753                     continue;
1754                 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
1755                     continue;
1756                 grouping.insert(address);
1757                 any_mine = true;
1758             }
1759
1760             // group change with input addresses
1761             if (any_mine)
1762             {
1763                BOOST_FOREACH(CTxOut txout, pcoin->vout)
1764                    if (IsChange(txout))
1765                    {
1766                        CTxDestination txoutAddr;
1767                        if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
1768                            continue;
1769                        grouping.insert(txoutAddr);
1770                    }
1771             }
1772             if (grouping.size() > 0)
1773             {
1774                 groupings.insert(grouping);
1775                 grouping.clear();
1776             }
1777         }
1778
1779         // group lone addrs by themselves
1780         for (unsigned int i = 0; i < pcoin->vout.size(); i++)
1781             if (IsMine(pcoin->vout[i]))
1782             {
1783                 CTxDestination address;
1784                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
1785                     continue;
1786                 grouping.insert(address);
1787                 groupings.insert(grouping);
1788                 grouping.clear();
1789             }
1790     }
1791
1792     set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
1793     map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
1794     BOOST_FOREACH(set<CTxDestination> grouping, groupings)
1795     {
1796         // make a set of all the groups hit by this new group
1797         set< set<CTxDestination>* > hits;
1798         map< CTxDestination, set<CTxDestination>* >::iterator it;
1799         BOOST_FOREACH(CTxDestination address, grouping)
1800             if ((it = setmap.find(address)) != setmap.end())
1801                 hits.insert((*it).second);
1802
1803         // merge all hit groups into a new single group and delete old groups
1804         set<CTxDestination>* merged = new set<CTxDestination>(grouping);
1805         BOOST_FOREACH(set<CTxDestination>* hit, hits)
1806         {
1807             merged->insert(hit->begin(), hit->end());
1808             uniqueGroupings.erase(hit);
1809             delete hit;
1810         }
1811         uniqueGroupings.insert(merged);
1812
1813         // update setmap
1814         BOOST_FOREACH(CTxDestination element, *merged)
1815             setmap[element] = merged;
1816     }
1817
1818     set< set<CTxDestination> > ret;
1819     BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
1820     {
1821         ret.insert(*uniqueGrouping);
1822         delete uniqueGrouping;
1823     }
1824
1825     return ret;
1826 }
1827
1828 bool CReserveKey::GetReservedKey(CPubKey& pubkey)
1829 {
1830     if (nIndex == -1)
1831     {
1832         CKeyPool keypool;
1833         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
1834         if (nIndex != -1)
1835             vchPubKey = keypool.vchPubKey;
1836         else {
1837             if (pwallet->vchDefaultKey.IsValid()) {
1838                 printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
1839                 vchPubKey = pwallet->vchDefaultKey;
1840             } else
1841                 return false;
1842         }
1843     }
1844     assert(vchPubKey.IsValid());
1845     pubkey = vchPubKey;
1846     return true;
1847 }
1848
1849 void CReserveKey::KeepKey()
1850 {
1851     if (nIndex != -1)
1852         pwallet->KeepKey(nIndex);
1853     nIndex = -1;
1854     vchPubKey = CPubKey();
1855 }
1856
1857 void CReserveKey::ReturnKey()
1858 {
1859     if (nIndex != -1)
1860         pwallet->ReturnKey(nIndex);
1861     nIndex = -1;
1862     vchPubKey = CPubKey();
1863 }
1864
1865 void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress)
1866 {
1867     setAddress.clear();
1868
1869     CWalletDB walletdb(strWalletFile);
1870
1871     LOCK2(cs_main, cs_wallet);
1872     BOOST_FOREACH(const int64& id, setKeyPool)
1873     {
1874         CKeyPool keypool;
1875         if (!walletdb.ReadPool(id, keypool))
1876             throw runtime_error("GetAllReserveKeyHashes() : read failed");
1877         assert(keypool.vchPubKey.IsValid());
1878         CKeyID keyID = keypool.vchPubKey.GetID();
1879         if (!HaveKey(keyID))
1880             throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
1881         setAddress.insert(keyID);
1882     }
1883 }
1884
1885 void CWallet::UpdatedTransaction(const uint256 &hashTx)
1886 {
1887     {
1888         LOCK(cs_wallet);
1889         // Only notify UI if this transaction is in this wallet
1890         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
1891         if (mi != mapWallet.end())
1892             NotifyTransactionChanged(this, hashTx, CT_UPDATED);
1893     }
1894 }
1895
1896 void CWallet::LockCoin(COutPoint& output)
1897 {
1898     setLockedCoins.insert(output);
1899 }
1900
1901 void CWallet::UnlockCoin(COutPoint& output)
1902 {
1903     setLockedCoins.erase(output);
1904 }
1905
1906 void CWallet::UnlockAllCoins()
1907 {
1908     setLockedCoins.clear();
1909 }
1910
1911 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
1912 {
1913     COutPoint outpt(hash, n);
1914
1915     return (setLockedCoins.count(outpt) > 0);
1916 }
1917
1918 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
1919 {
1920     for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
1921          it != setLockedCoins.end(); it++) {
1922         COutPoint outpt = (*it);
1923         vOutpts.push_back(outpt);
1924     }
1925 }
1926