fix bug "refresh minting tab"
[novacoin.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 "txdb.h"
7 #include "wallet.h"
8 #include "walletdb.h"
9 #include "crypter.h"
10 #include "ui_interface.h"
11 #include "base58.h"
12 #include "kernel.h"
13 #include "coincontrol.h"
14 #include <boost/algorithm/string/replace.hpp>
15
16 #include "main.h"
17
18 using namespace std;
19
20
21 bool fCoinsDataActual;
22
23 //////////////////////////////////////////////////////////////////////////////
24 //
25 // mapWallet
26 //
27
28 struct CompareValueOnly
29 {
30     bool operator()(const pair<int64, pair<const CWalletTx*, unsigned int> >& t1,
31                     const pair<int64, pair<const CWalletTx*, unsigned int> >& t2) const
32     {
33         return t1.first < t2.first;
34     }
35 };
36
37 CPubKey CWallet::GenerateNewKey()
38 {
39     bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
40
41     RandAddSeedPerfmon();
42     CKey key;
43     key.MakeNewKey(fCompressed);
44
45     // Compressed public keys were introduced in version 0.6.0
46     if (fCompressed)
47         SetMinVersion(FEATURE_COMPRPUBKEY);
48
49     CPubKey pubkey = key.GetPubKey();
50
51     // Create new metadata
52     int64 nCreationTime = GetTime();
53     mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
54     if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
55         nTimeFirstKey = nCreationTime;
56
57     if (!AddKey(key))
58         throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
59     return key.GetPubKey();
60 }
61
62 bool CWallet::AddKey(const CKey& key)
63 {
64     CPubKey pubkey = key.GetPubKey();
65
66     if (!CCryptoKeyStore::AddKey(key))
67         return false;
68     if (!fFileBacked)
69         return true;
70     if (!IsCrypted())
71         return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]);
72     return true;
73 }
74
75 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
76 {
77     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
78         return false;
79     if (!fFileBacked)
80         return true;
81     {
82         LOCK(cs_wallet);
83         if (pwalletdbEncryption)
84             return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
85         else
86             return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
87     }
88     return false;
89 }
90
91 bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
92 {
93     if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
94         nTimeFirstKey = meta.nCreateTime;
95
96     mapKeyMetadata[pubkey.GetID()] = meta;
97     return true;
98 }
99
100 bool CWallet::AddCScript(const CScript& redeemScript)
101 {
102     if (!CCryptoKeyStore::AddCScript(redeemScript))
103         return false;
104     if (!fFileBacked)
105         return true;
106     return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
107 }
108
109 bool CWallet::AddWatchOnly(const CScript &dest)
110 {
111     if (!CCryptoKeyStore::AddWatchOnly(dest))
112         return false;
113     nTimeFirstKey = 1; // No birthday information for watch-only keys.
114     if (!fFileBacked)
115         return true;
116     return CWalletDB(strWalletFile).WriteWatchOnly(dest);
117 }
118
119 bool CWallet::LoadWatchOnly(const CScript &dest)
120 {
121     return CCryptoKeyStore::AddWatchOnly(dest);
122 }
123
124 // ppcoin: optional setting to unlock wallet for block minting only;
125 //         serves to disable the trivial sendmoney when OS account compromised
126 bool fWalletUnlockMintOnly = false;
127
128 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
129 {
130     if (!IsLocked())
131         return false;
132
133     CCrypter crypter;
134     CKeyingMaterial vMasterKey;
135
136     {
137         LOCK(cs_wallet);
138         BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
139         {
140             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
141                 return false;
142             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
143                 return false;
144             if (CCryptoKeyStore::Unlock(vMasterKey))
145                 return true;
146         }
147     }
148     return false;
149 }
150
151 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
152 {
153     bool fWasLocked = IsLocked();
154
155     {
156         LOCK(cs_wallet);
157         Lock();
158
159         CCrypter crypter;
160         CKeyingMaterial vMasterKey;
161         BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
162         {
163             if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
164                 return false;
165             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
166                 return false;
167             if (CCryptoKeyStore::Unlock(vMasterKey))
168             {
169                 int64 nStartTime = GetTimeMillis();
170                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
171                 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
172
173                 nStartTime = GetTimeMillis();
174                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
175                 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
176
177                 if (pMasterKey.second.nDeriveIterations < 25000)
178                     pMasterKey.second.nDeriveIterations = 25000;
179
180                 printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
181
182                 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
183                     return false;
184                 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
185                     return false;
186                 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
187                 if (fWasLocked)
188                     Lock();
189                 return true;
190             }
191         }
192     }
193
194     return false;
195 }
196
197 void CWallet::SetBestChain(const CBlockLocator& loc)
198 {
199     CWalletDB walletdb(strWalletFile);
200     walletdb.WriteBestBlock(loc);
201 }
202
203 // This class implements an addrIncoming entry that causes pre-0.4
204 // clients to crash on startup if reading a private-key-encrypted wallet.
205 class CCorruptAddress
206 {
207 public:
208     IMPLEMENT_SERIALIZE
209     (
210         if (nType & SER_DISK)
211             READWRITE(nVersion);
212     )
213 };
214
215 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
216 {
217     if (nWalletVersion >= nVersion)
218         return true;
219
220     // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
221     if (fExplicit && nVersion > nWalletMaxVersion)
222             nVersion = FEATURE_LATEST;
223
224     nWalletVersion = nVersion;
225
226     if (nVersion > nWalletMaxVersion)
227         nWalletMaxVersion = nVersion;
228
229     if (fFileBacked)
230     {
231         CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
232         if (nWalletVersion >= 40000)
233         {
234             // Versions prior to 0.4.0 did not support the "minversion" record.
235             // Use a CCorruptAddress to make them crash instead.
236             CCorruptAddress corruptAddress;
237             pwalletdb->WriteSetting("addrIncoming", corruptAddress);
238         }
239         if (nWalletVersion > 40000)
240             pwalletdb->WriteMinVersion(nWalletVersion);
241         if (!pwalletdbIn)
242             delete pwalletdb;
243     }
244
245     return true;
246 }
247
248 bool CWallet::SetMaxVersion(int nVersion)
249 {
250     // cannot downgrade below current version
251     if (nWalletVersion > nVersion)
252         return false;
253
254     nWalletMaxVersion = nVersion;
255
256     return true;
257 }
258
259 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
260 {
261     if (IsCrypted())
262         return false;
263
264     CKeyingMaterial vMasterKey;
265     RandAddSeedPerfmon();
266
267     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
268     RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
269
270     CMasterKey kMasterKey(nDerivationMethodIndex);
271
272     RandAddSeedPerfmon();
273     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
274     RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
275
276     CCrypter crypter;
277     int64 nStartTime = GetTimeMillis();
278     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
279     kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
280
281     nStartTime = GetTimeMillis();
282     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
283     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
284
285     if (kMasterKey.nDeriveIterations < 25000)
286         kMasterKey.nDeriveIterations = 25000;
287
288     printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
289
290     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
291         return false;
292     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
293         return false;
294
295     {
296         LOCK(cs_wallet);
297         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
298         if (fFileBacked)
299         {
300             pwalletdbEncryption = new CWalletDB(strWalletFile);
301             if (!pwalletdbEncryption->TxnBegin())
302                 return false;
303             pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
304         }
305
306         if (!EncryptKeys(vMasterKey))
307         {
308             if (fFileBacked)
309                 pwalletdbEncryption->TxnAbort();
310             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.
311         }
312
313         // Encryption was introduced in version 0.4.0
314         SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
315
316         if (fFileBacked)
317         {
318             if (!pwalletdbEncryption->TxnCommit())
319                 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.
320
321             delete pwalletdbEncryption;
322             pwalletdbEncryption = NULL;
323         }
324
325         Lock();
326         Unlock(strWalletPassphrase);
327         NewKeyPool();
328         Lock();
329
330         // Need to completely rewrite the wallet file; if we don't, bdb might keep
331         // bits of the unencrypted private key in slack space in the database file.
332         CDB::Rewrite(strWalletFile);
333
334     }
335     NotifyStatusChanged(this);
336
337     return true;
338 }
339
340 int64 CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
341 {
342     int64 nRet = nOrderPosNext++;
343     if (pwalletdb) {
344         pwalletdb->WriteOrderPosNext(nOrderPosNext);
345     } else {
346         CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
347     }
348     return nRet;
349 }
350
351 CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
352 {
353     CWalletDB walletdb(strWalletFile);
354
355     // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
356     TxItems txOrdered;
357
358     // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
359     // would make this much faster for applications that do this a lot.
360     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
361     {
362         CWalletTx* wtx = &((*it).second);
363         txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
364     }
365     acentries.clear();
366     walletdb.ListAccountCreditDebit(strAccount, acentries);
367     BOOST_FOREACH(CAccountingEntry& entry, acentries)
368     {
369         txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
370     }
371
372     return txOrdered;
373 }
374
375 void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock)
376 {
377     // Anytime a signature is successfully verified, it's proof the outpoint is spent.
378     // Update the wallet spent flag if it doesn't know due to wallet.dat being
379     // restored from backup or the user making copies of wallet.dat.
380     {
381         LOCK(cs_wallet);
382         BOOST_FOREACH(const CTxIn& txin, tx.vin)
383         {
384             map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
385             if (mi != mapWallet.end())
386             {
387                 CWalletTx& wtx = (*mi).second;
388                 if (txin.prevout.n >= wtx.vout.size())
389                     printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
390                 else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
391                 {
392                     printf("WalletUpdateSpent found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
393                     wtx.MarkSpent(txin.prevout.n);
394                     wtx.WriteToDisk();
395                     NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED);
396                 }
397             }
398         }
399
400         if (fBlock)
401         {
402             uint256 hash = tx.GetHash();
403             map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
404             CWalletTx& wtx = (*mi).second;
405
406             BOOST_FOREACH(const CTxOut& txout, tx.vout)
407             {
408                 if (IsMine(txout))
409                 {
410                     wtx.MarkUnspent(&txout - &tx.vout[0]);
411                     wtx.WriteToDisk();
412                     NotifyTransactionChanged(this, hash, CT_UPDATED);
413                 }
414             }
415         }
416
417     }
418 }
419
420 void CWallet::MarkDirty()
421 {
422     {
423         LOCK(cs_wallet);
424         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
425             item.second.MarkDirty();
426     }
427 }
428
429 bool CWallet::AddToWallet(const CWalletTx& wtxIn)
430 {
431     uint256 hash = wtxIn.GetHash();
432     {
433         LOCK(cs_wallet);
434         // Inserts only if not already there, returns tx inserted or tx found
435         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
436         CWalletTx& wtx = (*ret.first).second;
437         wtx.BindWallet(this);
438         bool fInsertedNew = ret.second;
439         if (fInsertedNew)
440         {
441             wtx.nTimeReceived = GetAdjustedTime();
442             wtx.nOrderPos = IncOrderPosNext();
443
444             wtx.nTimeSmart = wtx.nTimeReceived;
445             if (wtxIn.hashBlock != 0)
446             {
447                 if (mapBlockIndex.count(wtxIn.hashBlock))
448                 {
449                     unsigned int latestNow = wtx.nTimeReceived;
450                     unsigned int latestEntry = 0;
451                     {
452                         // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
453                         int64 latestTolerated = latestNow + 300;
454                         std::list<CAccountingEntry> acentries;
455                         TxItems txOrdered = OrderedTxItems(acentries);
456                         for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
457                         {
458                             CWalletTx *const pwtx = (*it).second.first;
459                             if (pwtx == &wtx)
460                                 continue;
461                             CAccountingEntry *const pacentry = (*it).second.second;
462                             int64 nSmartTime;
463                             if (pwtx)
464                             {
465                                 nSmartTime = pwtx->nTimeSmart;
466                                 if (!nSmartTime)
467                                     nSmartTime = pwtx->nTimeReceived;
468                             }
469                             else
470                                 nSmartTime = pacentry->nTime;
471                             if (nSmartTime <= latestTolerated)
472                             {
473                                 latestEntry = nSmartTime;
474                                 if (nSmartTime > latestNow)
475                                     latestNow = nSmartTime;
476                                 break;
477                             }
478                         }
479                     }
480
481                     unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime;
482                     wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
483                 }
484                 else
485                     printf("AddToWallet() : found %s in block %s not in index\n",
486                            wtxIn.GetHash().ToString().substr(0,10).c_str(),
487                            wtxIn.hashBlock.ToString().c_str());
488             }
489         }
490
491         bool fUpdated = false;
492         if (!fInsertedNew)
493         {
494             // Merge
495             if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
496             {
497                 wtx.hashBlock = wtxIn.hashBlock;
498                 fUpdated = true;
499             }
500             if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
501             {
502                 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
503                 wtx.nIndex = wtxIn.nIndex;
504                 fUpdated = true;
505             }
506             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
507             {
508                 wtx.fFromMe = wtxIn.fFromMe;
509                 fUpdated = true;
510             }
511             fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
512         }
513
514         //// debug print
515         printf("AddToWallet %s  %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
516
517         // Write to disk
518         if (fInsertedNew || fUpdated)
519             if (!wtx.WriteToDisk())
520                 return false;
521 #ifndef QT_GUI
522         // If default receiving address gets used, replace it with a new one
523         CScript scriptDefaultKey;
524         scriptDefaultKey.SetDestination(vchDefaultKey.GetID());
525         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
526         {
527             if (txout.scriptPubKey == scriptDefaultKey)
528             {
529                 CPubKey newDefaultKey;
530                 if (GetKeyFromPool(newDefaultKey, false))
531                 {
532                     SetDefaultKey(newDefaultKey);
533                     SetAddressBookName(vchDefaultKey.GetID(), "");
534                 }
535             }
536         }
537 #endif
538         // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
539         WalletUpdateSpent(wtx, (wtxIn.hashBlock != 0));
540
541         // Notify UI of new or updated transaction
542         NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
543
544         // notify an external script when a wallet transaction comes in or is updated
545         std::string strCmd = GetArg("-walletnotify", "");
546
547         if ( !strCmd.empty())
548         {
549             boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
550             boost::thread t(runCommand, strCmd); // thread runs free
551         }
552
553     }
554     return true;
555 }
556
557 // Add a transaction to the wallet, or update it.
558 // pblock is optional, but should be provided if the transaction is known to be in a block.
559 // If fUpdate is true, existing transactions will be updated.
560 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
561 {
562     uint256 hash = tx.GetHash();
563     {
564         LOCK(cs_wallet);
565         bool fExisted = mapWallet.count(hash);
566         if (fExisted && !fUpdate) return false;
567         if (fExisted || IsMine(tx) || IsFromMe(tx))
568         {
569             CWalletTx wtx(this,tx);
570             // Get merkle branch if transaction was found in a block
571             if (pblock)
572                 wtx.SetMerkleBranch(pblock);
573             return AddToWallet(wtx);
574         }
575         else
576             WalletUpdateSpent(tx);
577     }
578     return false;
579 }
580
581 bool CWallet::EraseFromWallet(uint256 hash)
582 {
583     if (!fFileBacked)
584         return false;
585     {
586         LOCK(cs_wallet);
587         if (mapWallet.erase(hash))
588             CWalletDB(strWalletFile).EraseTx(hash);
589     }
590     return true;
591 }
592
593
594 isminetype CWallet::IsMine(const CTxIn &txin) const
595 {
596     {
597         LOCK(cs_wallet);
598         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
599         if (mi != mapWallet.end())
600         {
601             const CWalletTx& prev = (*mi).second;
602             if (txin.prevout.n < prev.vout.size())
603                 return IsMine(prev.vout[txin.prevout.n]);
604         }
605     }
606     return MINE_NO;
607 }
608
609 int64 CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
610 {
611     {
612         LOCK(cs_wallet);
613         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
614         if (mi != mapWallet.end())
615         {
616             const CWalletTx& prev = (*mi).second;
617             if (txin.prevout.n < prev.vout.size())
618                 if (IsMine(prev.vout[txin.prevout.n]) & filter)
619                     return prev.vout[txin.prevout.n].nValue;
620         }
621     }
622     return 0;
623 }
624
625 bool CWallet::IsChange(const CTxOut& txout) const
626 {
627     // TODO: fix handling of 'change' outputs. The assumption is that any
628     // payment to a script that is ours, but isn't in the address book
629     // is change. That assumption is likely to break when we implement multisignature
630     // wallets that return change back into a multi-signature-protected address;
631     // a better way of identifying which outputs are 'the send' and which are
632     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
633     // which output, if any, was change).
634     if (::IsMine(*this, txout.scriptPubKey))
635     {
636         CTxDestination address;
637         if (!ExtractDestination(txout.scriptPubKey, address))
638             return true;
639
640         LOCK(cs_wallet);
641         if (!mapAddressBook.count(address))
642             return true;
643     }
644     return false;
645 }
646
647 int64 CWalletTx::GetTxTime() const
648 {
649     int64 n = nTimeSmart;
650     return n ? n : nTimeReceived;
651 }
652
653 int CWalletTx::GetRequestCount() const
654 {
655     // Returns -1 if it wasn't being tracked
656     int nRequests = -1;
657     {
658         LOCK(pwallet->cs_wallet);
659         if (IsCoinBase() || IsCoinStake())
660         {
661             // Generated block
662             if (hashBlock != 0)
663             {
664                 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
665                 if (mi != pwallet->mapRequestCount.end())
666                     nRequests = (*mi).second;
667             }
668         }
669         else
670         {
671             // Did anyone request this transaction?
672             map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
673             if (mi != pwallet->mapRequestCount.end())
674             {
675                 nRequests = (*mi).second;
676
677                 // How about the block it's in?
678                 if (nRequests == 0 && hashBlock != 0)
679                 {
680                     map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
681                     if (mi != pwallet->mapRequestCount.end())
682                         nRequests = (*mi).second;
683                     else
684                         nRequests = 1; // If it's in someone else's block it must have got out
685                 }
686             }
687         }
688     }
689     return nRequests;
690 }
691
692 void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CTxDestination, int64> >& listReceived,
693                            list<pair<CTxDestination, int64> >& listSent, int64& nFee, string& strSentAccount, const isminefilter& filter) const
694 {
695     nGeneratedImmature = nGeneratedMature = nFee = 0;
696     listReceived.clear();
697     listSent.clear();
698     strSentAccount = strFromAccount;
699
700     if (IsCoinBase() || IsCoinStake())
701     {
702         if (GetBlocksToMaturity() > 0)
703             nGeneratedImmature = pwallet->GetCredit(*this, filter);
704         else
705             nGeneratedMature = GetCredit(filter);
706         return;
707     }
708
709     // Compute fee:
710     int64 nDebit = GetDebit(filter);
711     if (nDebit > 0) // debit>0 means we signed/sent this transaction
712     {
713         int64 nValueOut = GetValueOut();
714         nFee = nDebit - nValueOut;
715     }
716
717     // Sent/received.
718     BOOST_FOREACH(const CTxOut& txout, vout)
719     {
720         isminetype fIsMine = pwallet->IsMine(txout);
721         // Only need to handle txouts if AT LEAST one of these is true:
722         //   1) they debit from us (sent)
723         //   2) the output is to us (received)
724         if (nDebit > 0)
725         {
726             // Don't report 'change' txouts
727             if (pwallet->IsChange(txout))
728                 continue;
729         }
730         else if (!(fIsMine & filter))
731             continue;
732
733         // In either case, we need to get the destination address
734         CTxDestination address;
735         if (!ExtractDestination(txout.scriptPubKey, address))
736         {
737             printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
738                    this->GetHash().ToString().c_str());
739             address = CNoDestination();
740         }
741
742         // If we are debited by the transaction, add the output as a "sent" entry
743         if (nDebit > 0)
744             listSent.push_back(make_pair(address, txout.nValue));
745
746         // If we are receiving the output, add it as a "received" entry
747         if (fIsMine & filter)
748             listReceived.push_back(make_pair(address, txout.nValue));
749     }
750
751 }
752
753 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
754                                   int64& nSent, int64& nFee, const isminefilter& filter) const
755 {
756     nGenerated = nReceived = nSent = nFee = 0;
757
758     int64 allGeneratedImmature, allGeneratedMature, allFee;
759     allGeneratedImmature = allGeneratedMature = allFee = 0;
760     string strSentAccount;
761     list<pair<CTxDestination, int64> > listReceived;
762     list<pair<CTxDestination, int64> > listSent;
763     GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter);
764
765     if (strAccount == "")
766         nGenerated = allGeneratedMature;
767     if (strAccount == strSentAccount)
768     {
769         BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent)
770             nSent += s.second;
771         nFee = allFee;
772     }
773     {
774         LOCK(pwallet->cs_wallet);
775         BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived)
776         {
777             if (pwallet->mapAddressBook.count(r.first))
778             {
779                 map<CTxDestination, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
780                 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
781                     nReceived += r.second;
782             }
783             else if (strAccount.empty())
784             {
785                 nReceived += r.second;
786             }
787         }
788     }
789 }
790
791 void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
792 {
793     vtxPrev.clear();
794
795     const int COPY_DEPTH = 3;
796     if (SetMerkleBranch() < COPY_DEPTH)
797     {
798         vector<uint256> vWorkQueue;
799         BOOST_FOREACH(const CTxIn& txin, vin)
800             vWorkQueue.push_back(txin.prevout.hash);
801
802         // This critsect is OK because txdb is already open
803         {
804             LOCK(pwallet->cs_wallet);
805             map<uint256, const CMerkleTx*> mapWalletPrev;
806             set<uint256> setAlreadyDone;
807             for (unsigned int i = 0; i < vWorkQueue.size(); i++)
808             {
809                 uint256 hash = vWorkQueue[i];
810                 if (setAlreadyDone.count(hash))
811                     continue;
812                 setAlreadyDone.insert(hash);
813
814                 CMerkleTx tx;
815                 map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
816                 if (mi != pwallet->mapWallet.end())
817                 {
818                     tx = (*mi).second;
819                     BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
820                         mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
821                 }
822                 else if (mapWalletPrev.count(hash))
823                 {
824                     tx = *mapWalletPrev[hash];
825                 }
826                 else if (!fClient && txdb.ReadDiskTx(hash, tx))
827                 {
828                     ;
829                 }
830                 else
831                 {
832                     printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
833                     continue;
834                 }
835
836                 int nDepth = tx.SetMerkleBranch();
837                 vtxPrev.push_back(tx);
838
839                 if (nDepth < COPY_DEPTH)
840                 {
841                     BOOST_FOREACH(const CTxIn& txin, tx.vin)
842                         vWorkQueue.push_back(txin.prevout.hash);
843                 }
844             }
845         }
846     }
847
848     reverse(vtxPrev.begin(), vtxPrev.end());
849 }
850
851 bool CWalletTx::WriteToDisk()
852 {
853     return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
854 }
855
856 // Scan the block chain (starting in pindexStart) for transactions
857 // from or to us. If fUpdate is true, found transactions that already
858 // exist in the wallet will be updated.
859 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
860 {
861     int ret = 0;
862
863     CBlockIndex* pindex = pindexStart;
864     {
865         LOCK(cs_wallet);
866         while (pindex)
867         {
868             CBlock block;
869             block.ReadFromDisk(pindex, true);
870             BOOST_FOREACH(CTransaction& tx, block.vtx)
871             {
872                 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
873                     ret++;
874             }
875             pindex = pindex->pnext;
876         }
877     }
878     return ret;
879 }
880
881 int CWallet::ScanForWalletTransaction(const uint256& hashTx)
882 {
883     CTransaction tx;
884     tx.ReadFromDisk(COutPoint(hashTx, 0));
885     if (AddToWalletIfInvolvingMe(tx, NULL, true, true))
886         return 1;
887     return 0;
888 }
889
890 void CWallet::ReacceptWalletTransactions()
891 {
892     CTxDB txdb("r");
893     bool fRepeat = true;
894     while (fRepeat)
895     {
896         LOCK(cs_wallet);
897         fRepeat = false;
898         vector<CDiskTxPos> vMissingTx;
899         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
900         {
901             CWalletTx& wtx = item.second;
902             if ((wtx.IsCoinBase() && wtx.IsSpent(0)) || (wtx.IsCoinStake() && wtx.IsSpent(1)))
903                 continue;
904
905             CTxIndex txindex;
906             bool fUpdated = false;
907             if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
908             {
909                 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
910                 if (txindex.vSpent.size() != wtx.vout.size())
911                 {
912                     printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %"PRIszu" != wtx.vout.size() %"PRIszu"\n", txindex.vSpent.size(), wtx.vout.size());
913                     continue;
914                 }
915                 for (unsigned int i = 0; i < txindex.vSpent.size(); i++)
916                 {
917                     if (wtx.IsSpent(i))
918                         continue;
919                     if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i]))
920                     {
921                         wtx.MarkSpent(i);
922                         fUpdated = true;
923                         vMissingTx.push_back(txindex.vSpent[i]);
924                     }
925                 }
926                 if (fUpdated)
927                 {
928                     printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
929                     wtx.MarkDirty();
930                     wtx.WriteToDisk();
931                 }
932             }
933             else
934             {
935                 // Re-accept any txes of ours that aren't already in a block
936                 if (!(wtx.IsCoinBase() || wtx.IsCoinStake()))
937                     wtx.AcceptWalletTransaction(txdb, false);
938             }
939         }
940         if (!vMissingTx.empty())
941         {
942             // TODO: optimize this to scan just part of the block chain?
943             if (ScanForWalletTransactions(pindexGenesisBlock))
944                 fRepeat = true;  // Found missing transactions: re-do re-accept.
945         }
946     }
947 }
948
949 void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
950 {
951     BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
952     {
953         if (!(tx.IsCoinBase() || tx.IsCoinStake()))
954         {
955             uint256 hash = tx.GetHash();
956             if (!txdb.ContainsTx(hash))
957                 RelayTransaction((CTransaction)tx, hash);
958         }
959     }
960     if (!(IsCoinBase() || IsCoinStake()))
961     {
962         uint256 hash = GetHash();
963         if (!txdb.ContainsTx(hash))
964         {
965             printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
966             RelayTransaction((CTransaction)*this, hash);
967         }
968     }
969 }
970
971 void CWalletTx::RelayWalletTransaction()
972 {
973    CTxDB txdb("r");
974    RelayWalletTransaction(txdb);
975 }
976
977 void CWallet::ResendWalletTransactions()
978 {
979     // Do this infrequently and randomly to avoid giving away
980     // that these are our transactions.
981     static int64 nNextTime;
982     if (GetTime() < nNextTime)
983         return;
984     bool fFirst = (nNextTime == 0);
985     nNextTime = GetTime() + GetRand(30 * 60);
986     if (fFirst)
987         return;
988
989     // Only do it if there's been a new block since last time
990     static int64 nLastTime;
991     if (nTimeBestReceived < nLastTime)
992         return;
993     nLastTime = GetTime();
994
995     // Rebroadcast any of our txes that aren't in a block yet
996     printf("ResendWalletTransactions()\n");
997     CTxDB txdb("r");
998     {
999         LOCK(cs_wallet);
1000         // Sort them in chronological order
1001         multimap<unsigned int, CWalletTx*> mapSorted;
1002         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1003         {
1004             CWalletTx& wtx = item.second;
1005             // Don't rebroadcast until it's had plenty of time that
1006             // it should have gotten in already by now.
1007             if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
1008                 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
1009         }
1010         BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
1011         {
1012             CWalletTx& wtx = *item.second;
1013             if (wtx.CheckTransaction())
1014                 wtx.RelayWalletTransaction(txdb);
1015             else
1016                 printf("ResendWalletTransactions() : CheckTransaction failed for transaction %s\n", wtx.GetHash().ToString().c_str());
1017         }
1018     }
1019 }
1020
1021
1022
1023
1024
1025
1026 //////////////////////////////////////////////////////////////////////////////
1027 //
1028 // Actions
1029 //
1030
1031
1032 int64 CWallet::GetBalance() const
1033 {
1034     int64 nTotal = 0;
1035     {
1036         LOCK(cs_wallet);
1037         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1038         {
1039             const CWalletTx* pcoin = &(*it).second;
1040             if (pcoin->IsTrusted())
1041                 nTotal += pcoin->GetAvailableCredit();
1042         }
1043     }
1044
1045     return nTotal;
1046 }
1047
1048 int64 CWallet::GetWatchOnlyBalance() const
1049 {
1050     int64 nTotal = 0;
1051     {
1052         LOCK(cs_wallet);
1053         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1054         {
1055             const CWalletTx* pcoin = &(*it).second;
1056             if (pcoin->IsTrusted())
1057                 nTotal += pcoin->GetAvailableWatchCredit();
1058         }
1059     }
1060
1061     return nTotal;
1062 }
1063
1064 int64 CWallet::GetUnconfirmedBalance() const
1065 {
1066     int64 nTotal = 0;
1067     {
1068         LOCK(cs_wallet);
1069         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1070         {
1071             const CWalletTx* pcoin = &(*it).second;
1072             if (!pcoin->IsFinal() || !pcoin->IsTrusted())
1073                 nTotal += pcoin->GetAvailableCredit();
1074         }
1075     }
1076     return nTotal;
1077 }
1078
1079 int64 CWallet::GetUnconfirmedWatchOnlyBalance() const
1080 {
1081     int64 nTotal = 0;
1082     {
1083         LOCK(cs_wallet);
1084         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1085         {
1086             const CWalletTx* pcoin = &(*it).second;
1087             if (!pcoin->IsFinal() || !pcoin->IsTrusted())
1088                 nTotal += pcoin->GetAvailableWatchCredit();
1089         }
1090     }
1091     return nTotal;
1092 }
1093
1094 int64 CWallet::GetImmatureBalance() const
1095 {
1096     int64 nTotal = 0;
1097     {
1098         LOCK(cs_wallet);
1099         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1100         {
1101             const CWalletTx* pcoin = &(*it).second;
1102             nTotal += pcoin->GetImmatureCredit();
1103         }
1104     }
1105     return nTotal;
1106 }
1107
1108 int64 CWallet::GetImmatureWatchOnlyBalance() const
1109 {
1110     int64 nTotal = 0;
1111     {
1112         LOCK(cs_wallet);
1113         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1114         {
1115             const CWalletTx* pcoin = &(*it).second;
1116             nTotal += pcoin->GetImmatureWatchOnlyCredit();
1117         }
1118     }
1119     return nTotal;
1120 }
1121
1122 // populate vCoins with vector of spendable COutputs
1123 void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const
1124 {
1125     vCoins.clear();
1126
1127     {
1128         LOCK(cs_wallet);
1129         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1130         {
1131             const CWalletTx* pcoin = &(*it).second;
1132
1133             if (!pcoin->IsFinal())
1134                 continue;
1135
1136             if (fOnlyConfirmed && !pcoin->IsTrusted())
1137                 continue;
1138
1139             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1140                 continue;
1141
1142             if(pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0)
1143                 continue;
1144
1145             for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
1146                 isminetype mine = IsMine(pcoin->vout[i]);
1147                 if (!(pcoin->IsSpent(i)) && mine != MINE_NO && 
1148                     pcoin->vout[i].nValue >= nMinimumInputValue &&
1149                     (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
1150                 {
1151                     vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain(), mine == MINE_SPENDABLE));
1152                 }
1153             }
1154         }
1155     }
1156 }
1157
1158 void CWallet::AvailableCoinsMinConf(vector<COutput>& vCoins, int nConf, int64 nMinValue, int64 nMaxValue) const
1159 {
1160     vCoins.clear();
1161
1162     {
1163         LOCK(cs_wallet);
1164         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1165         {
1166             const CWalletTx* pcoin = &(*it).second;
1167
1168             if (!pcoin->IsFinal())
1169                 continue;
1170
1171             if(pcoin->GetDepthInMainChain() < nConf)
1172                 continue;
1173
1174             for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
1175                 isminetype mine = IsMine(pcoin->vout[i]);
1176
1177                 // ignore coin if it was already spent or we don't own it
1178                 if (pcoin->IsSpent(i) || mine == MINE_NO)
1179                     continue;
1180
1181                 // if coin value is between required limits then add new item to vector
1182                 if (pcoin->vout[i].nValue >= nMinValue && pcoin->vout[i].nValue < nMaxValue)
1183                     vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain(), mine == MINE_SPENDABLE));
1184             }
1185         }
1186     }
1187 }
1188
1189 static void ApproximateBestSubset(vector<pair<int64, pair<const CWalletTx*,unsigned int> > >vValue, int64 nTotalLower, int64 nTargetValue,
1190                                   vector<char>& vfBest, int64& nBest, int iterations = 1000)
1191 {
1192     vector<char> vfIncluded;
1193
1194     vfBest.assign(vValue.size(), true);
1195     nBest = nTotalLower;
1196
1197     for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
1198     {
1199         vfIncluded.assign(vValue.size(), false);
1200         int64 nTotal = 0;
1201         bool fReachedTarget = false;
1202         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
1203         {
1204             for (unsigned int i = 0; i < vValue.size(); i++)
1205             {
1206                 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
1207                 {
1208                     nTotal += vValue[i].first;
1209                     vfIncluded[i] = true;
1210                     if (nTotal >= nTargetValue)
1211                     {
1212                         fReachedTarget = true;
1213                         if (nTotal < nBest)
1214                         {
1215                             nBest = nTotal;
1216                             vfBest = vfIncluded;
1217                         }
1218                         nTotal -= vValue[i].first;
1219                         vfIncluded[i] = false;
1220                     }
1221                 }
1222             }
1223         }
1224     }
1225 }
1226
1227 int64 CWallet::GetStake() const
1228 {
1229     int64 nTotal = 0;
1230     LOCK(cs_wallet);
1231     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1232     {
1233         const CWalletTx* pcoin = &(*it).second;
1234         if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1235             nTotal += CWallet::GetCredit(*pcoin, MINE_ALL);
1236     }
1237     return nTotal;
1238 }
1239
1240 int64 CWallet::GetWatchOnlyStake() const
1241 {
1242     int64 nTotal = 0;
1243     LOCK(cs_wallet);
1244     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1245     {
1246         const CWalletTx* pcoin = &(*it).second;
1247         if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1248             nTotal += CWallet::GetCredit(*pcoin, MINE_WATCH_ONLY);
1249     }
1250     return nTotal;
1251 }
1252
1253 int64 CWallet::GetNewMint() const
1254 {
1255     int64 nTotal = 0;
1256     LOCK(cs_wallet);
1257     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1258     {
1259         const CWalletTx* pcoin = &(*it).second;
1260         if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1261             nTotal += CWallet::GetCredit(*pcoin, MINE_ALL);
1262     }
1263     return nTotal;
1264 }
1265
1266 int64 CWallet::GetWatchOnlyNewMint() const
1267 {
1268     int64 nTotal = 0;
1269     LOCK(cs_wallet);
1270     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1271     {
1272         const CWalletTx* pcoin = &(*it).second;
1273         if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1274             nTotal += CWallet::GetCredit(*pcoin, MINE_WATCH_ONLY);
1275     }
1276     return nTotal;
1277 }
1278
1279 bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, vector<COutput> vCoins, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
1280 {
1281     setCoinsRet.clear();
1282     nValueRet = 0;
1283
1284     // List of values less than target
1285     pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
1286     coinLowestLarger.first = std::numeric_limits<int64>::max();
1287     coinLowestLarger.second.first = NULL;
1288     vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
1289     int64 nTotalLower = 0;
1290
1291     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
1292
1293     BOOST_FOREACH(const COutput &output, vCoins)
1294     {
1295         if (!output.fSpendable)
1296             continue;
1297
1298         const CWalletTx *pcoin = output.tx;
1299
1300         if (output.nDepth < (pcoin->IsFromMe(MINE_ALL) ? nConfMine : nConfTheirs))
1301             continue;
1302
1303         int i = output.i;
1304
1305         // Follow the timestamp rules
1306         if (pcoin->nTime > nSpendTime)
1307             continue;
1308
1309         int64 n = pcoin->vout[i].nValue;
1310
1311         pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
1312
1313         if (n == nTargetValue)
1314         {
1315             setCoinsRet.insert(coin.second);
1316             nValueRet += coin.first;
1317             return true;
1318         }
1319         else if (n < nTargetValue + CENT)
1320         {
1321             vValue.push_back(coin);
1322             nTotalLower += n;
1323         }
1324         else if (n < coinLowestLarger.first)
1325         {
1326             coinLowestLarger = coin;
1327         }
1328     }
1329
1330     if (nTotalLower == nTargetValue)
1331     {
1332         for (unsigned int i = 0; i < vValue.size(); ++i)
1333         {
1334             setCoinsRet.insert(vValue[i].second);
1335             nValueRet += vValue[i].first;
1336         }
1337         return true;
1338     }
1339
1340     if (nTotalLower < nTargetValue)
1341     {
1342         if (coinLowestLarger.second.first == NULL)
1343             return false;
1344         setCoinsRet.insert(coinLowestLarger.second);
1345         nValueRet += coinLowestLarger.first;
1346         return true;
1347     }
1348
1349     // Solve subset sum by stochastic approximation
1350     sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
1351     vector<char> vfBest;
1352     int64 nBest;
1353
1354     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
1355     if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
1356         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
1357
1358     // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
1359     //                                   or the next bigger coin is closer), return the bigger coin
1360     if (coinLowestLarger.second.first &&
1361         ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
1362     {
1363         setCoinsRet.insert(coinLowestLarger.second);
1364         nValueRet += coinLowestLarger.first;
1365     }
1366     else {
1367         for (unsigned int i = 0; i < vValue.size(); i++)
1368             if (vfBest[i])
1369             {
1370                 setCoinsRet.insert(vValue[i].second);
1371                 nValueRet += vValue[i].first;
1372             }
1373
1374         if (fDebug && GetBoolArg("-printpriority"))
1375         {
1376             //// debug print
1377             printf("SelectCoins() best subset: ");
1378             for (unsigned int i = 0; i < vValue.size(); i++)
1379                 if (vfBest[i])
1380                     printf("%s ", FormatMoney(vValue[i].first).c_str());
1381             printf("total %s\n", FormatMoney(nBest).c_str());
1382         }
1383     }
1384
1385     return true;
1386 }
1387
1388 bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet, const CCoinControl* coinControl) const
1389 {
1390     vector<COutput> vCoins;
1391     AvailableCoins(vCoins, true, coinControl);
1392
1393     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
1394     if (coinControl && coinControl->HasSelected())
1395     {
1396         BOOST_FOREACH(const COutput& out, vCoins)
1397         {
1398             if(!out.fSpendable)
1399                 continue;
1400             nValueRet += out.tx->vout[out.i].nValue;
1401             setCoinsRet.insert(make_pair(out.tx, out.i));
1402         }
1403         return (nValueRet >= nTargetValue);
1404     }
1405
1406     return (SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 6, vCoins, setCoinsRet, nValueRet) ||
1407             SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 1, vCoins, setCoinsRet, nValueRet) ||
1408             SelectCoinsMinConf(nTargetValue, nSpendTime, 0, 1, vCoins, setCoinsRet, nValueRet));
1409 }
1410
1411 // Select some coins without random shuffle or best subset approximation
1412 bool CWallet::SelectCoinsSimple(int64 nTargetValue, int64 nMinValue, int64 nMaxValue, unsigned int nSpendTime, int nMinConf, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
1413 {
1414     vector<COutput> vCoins;
1415     AvailableCoinsMinConf(vCoins, nMinConf, nMinValue, nMaxValue);
1416
1417     setCoinsRet.clear();
1418     nValueRet = 0;
1419
1420     BOOST_FOREACH(COutput output, vCoins)
1421     {
1422         if(!output.fSpendable)
1423             continue;
1424         const CWalletTx *pcoin = output.tx;
1425         int i = output.i;
1426
1427         // Ignore immature coins
1428         if (pcoin->GetBlocksToMaturity() > 0)
1429             continue;
1430
1431         // Stop if we've chosen enough inputs
1432         if (nValueRet >= nTargetValue)
1433             break;
1434
1435         // Follow the timestamp rules
1436         if (pcoin->nTime > nSpendTime)
1437             continue;
1438
1439         int64 n = pcoin->vout[i].nValue;
1440
1441         pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
1442
1443         if (n >= nTargetValue)
1444         {
1445             // If input value is greater or equal to target then simply insert
1446             //    it into the current subset and exit
1447             setCoinsRet.insert(coin.second);
1448             nValueRet += coin.first;
1449             break;
1450         }
1451         else if (n < nTargetValue + CENT)
1452         {
1453             setCoinsRet.insert(coin.second);
1454             nValueRet += coin.first;
1455         }
1456     }
1457
1458     return true;
1459 }
1460
1461 bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl* coinControl)
1462 {
1463     int64 nValue = 0;
1464     BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1465     {
1466         if (nValue < 0)
1467             return false;
1468         nValue += s.second;
1469     }
1470     if (vecSend.empty() || nValue < 0)
1471         return false;
1472
1473     wtxNew.BindWallet(this);
1474
1475     {
1476         LOCK2(cs_main, cs_wallet);
1477         // txdb must be opened before the mapWallet lock
1478         CTxDB txdb("r");
1479         {
1480             nFeeRet = nTransactionFee;
1481             while (true)
1482             {
1483                 wtxNew.vin.clear();
1484                 wtxNew.vout.clear();
1485                 wtxNew.fFromMe = true;
1486
1487                 int64 nTotalValue = nValue + nFeeRet;
1488                 double dPriority = 0;
1489                 // vouts to the payees
1490                 BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
1491                     wtxNew.vout.push_back(CTxOut(s.second, s.first));
1492
1493                 // Choose coins to use
1494                 set<pair<const CWalletTx*,unsigned int> > setCoins;
1495                 int64 nValueIn = 0;
1496                 if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn, coinControl))
1497                     return false;
1498                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1499                 {
1500                     int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
1501                     dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
1502                 }
1503
1504                 int64 nChange = nValueIn - nValue - nFeeRet;
1505                 // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
1506                 // or until nChange becomes zero
1507                 // NOTE: this depends on the exact behaviour of GetMinFee
1508                 if (wtxNew.nTime < FEE_SWITCH_TIME && !fTestNet)
1509                 {
1510                     if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
1511                     {
1512                         int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
1513                         nChange -= nMoveToFee;
1514                         nFeeRet += nMoveToFee;
1515                     }
1516
1517                     // sub-cent change is moved to fee
1518                     if (nChange > 0 && nChange < CENT)
1519                     {
1520                         nFeeRet += nChange;
1521                         nChange = 0;
1522                     }
1523                 }
1524
1525                 if (nChange > 0)
1526                 {
1527                     // Fill a vout to ourself
1528                     // TODO: pass in scriptChange instead of reservekey so
1529                     // change transaction isn't always pay-to-bitcoin-address
1530                     CScript scriptChange;
1531
1532                     // coin control: send change to custom address
1533                     if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
1534                         scriptChange.SetDestination(coinControl->destChange);
1535
1536                     // no coin control: send change to newly generated address
1537                     else
1538                     {
1539                         // Note: We use a new key here to keep it from being obvious which side is the change.
1540                         //  The drawback is that by not reusing a previous key, the change may be lost if a
1541                         //  backup is restored, if the backup doesn't have the new private key for the change.
1542                         //  If we reused the old key, it would be possible to add code to look for and
1543                         //  rediscover unknown transactions that were written with keys of ours to recover
1544                         //  post-backup change.
1545
1546                         // Reserve a new key pair from key pool
1547                         CPubKey vchPubKey = reservekey.GetReservedKey();
1548
1549                         scriptChange.SetDestination(vchPubKey.GetID());
1550                     }
1551
1552                     // Insert change txn at random position:
1553                     vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
1554                     wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
1555                 }
1556                 else
1557                     reservekey.ReturnKey();
1558
1559                 // Fill vin
1560                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1561                     wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
1562
1563                 // Sign
1564                 int nIn = 0;
1565                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1566                     if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
1567                         return false;
1568
1569                 // Limit size
1570                 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
1571                 if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
1572                     return false;
1573                 dPriority /= nBytes;
1574
1575                 // Check that enough fee is included
1576                 int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
1577                 bool fAllowFree = CTransaction::AllowFree(dPriority);
1578
1579                 // Disable free transactions until 1 July 2014
1580                 if (!fTestNet && wtxNew.nTime < FEE_SWITCH_TIME)
1581                 {
1582                     fAllowFree = false;
1583                 }
1584
1585                 int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes);
1586
1587                 if (nFeeRet < max(nPayFee, nMinFee))
1588                 {
1589                     nFeeRet = max(nPayFee, nMinFee);
1590                     continue;
1591                 }
1592
1593                 // Fill vtxPrev by copying from previous transactions vtxPrev
1594                 wtxNew.AddSupportingTransactions(txdb);
1595                 wtxNew.fTimeReceivedIsTxTime = true;
1596
1597                 break;
1598             }
1599         }
1600     }
1601     return true;
1602 }
1603
1604 bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl* coinControl)
1605 {
1606     vector< pair<CScript, int64> > vecSend;
1607     vecSend.push_back(make_pair(scriptPubKey, nValue));
1608     return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, coinControl);
1609 }
1610
1611 void CWallet::GetStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight)
1612 {
1613     int64 nTimeWeight = GetWeight(nTime, (int64)GetTime());
1614
1615     // If time weight is lower or equal to zero then weight is zero.
1616     if (nTimeWeight <= 0)
1617     {
1618         nWeight = 0;
1619         return;
1620     }
1621
1622     CBigNum bnCoinDayWeight = CBigNum(nValue) * nTimeWeight / COIN / (24 * 60 * 60);
1623     nWeight = bnCoinDayWeight.getuint64();
1624 }
1625
1626
1627 // NovaCoin: get current stake weight
1628 bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight)
1629 {
1630     // Choose coins to use
1631     int64 nBalance = GetBalance();
1632     int64 nReserveBalance = 0;
1633
1634     if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance))
1635         return error("CreateCoinStake : invalid reserve balance amount");
1636
1637     if (nBalance <= nReserveBalance)
1638         return false;
1639
1640     CTxDB txdb("r");
1641     {
1642         LOCK2(cs_main, cs_wallet);
1643         // Cache outputs unless best block or wallet transaction set changed
1644         if (!fCoinsDataActual)
1645         {
1646             mapMeta.clear();
1647             int64 nValueIn = 0;
1648             CoinsSet setCoins;
1649             if (!SelectCoinsSimple(nBalance - nReserveBalance, MIN_TX_FEE, MAX_MONEY, GetAdjustedTime(), nCoinbaseMaturity * 10, setCoins, nValueIn))
1650                 return false;
1651
1652             if (setCoins.empty())
1653                 return false;
1654
1655             {
1656                 CTxIndex txindex;
1657                 CBlock block;
1658                 for(CoinsSet::iterator pcoin = setCoins.begin(); pcoin != setCoins.end(); pcoin++)
1659                 {
1660                     // Load transaction index item
1661                     if (!txdb.ReadTxIndex(pcoin->first->GetHash(), txindex))
1662                         continue;
1663
1664                     // Read block header
1665                     if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
1666                         continue;
1667
1668                     uint64 nStakeModifier = 0;
1669                     if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier))
1670                         continue;
1671
1672                     // Add meta record
1673                     // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier))
1674                     mapMeta[make_pair(pcoin->first->GetHash(), pcoin->second)] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier));
1675
1676                     if (fDebug)
1677                         printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str());
1678                 }
1679             }
1680
1681             if (fDebug)
1682                 printf("Get stake weight: %zu meta items loaded for %zu coins\n", mapMeta.size(), setCoins.size());
1683
1684             fCoinsDataActual = true;
1685         }
1686     }
1687
1688
1689     // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier))
1690     for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++)
1691     {
1692         // Get coin
1693         CoinsSet::value_type pcoin = meta_item->second.first.second;
1694
1695         int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime());
1696         CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60);
1697
1698         // Weight is greater than zero
1699         if (nTimeWeight > 0)
1700         {
1701             nWeight += bnCoinDayWeight.getuint64();
1702         }
1703
1704         // Weight is greater than zero, but the maximum value isn't reached yet
1705         if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge)
1706         {
1707             nMinWeight += bnCoinDayWeight.getuint64();
1708         }
1709
1710         // Maximum weight was reached
1711         if (nTimeWeight == nStakeMaxAge)
1712         {
1713             nMaxWeight += bnCoinDayWeight.getuint64();
1714         }
1715     }
1716
1717     return true;
1718 }
1719
1720 bool CWallet::MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nOutputValue, list<uint256>& listMerged)
1721 {
1722     int64 nBalance = GetBalance();
1723
1724     if (nAmount > nBalance)
1725         return false;
1726
1727     listMerged.clear();
1728     int64 nValueIn = 0;
1729     set<pair<const CWalletTx*,unsigned int> > setCoins;
1730
1731     // Simple coins selection - no randomization
1732     if (!SelectCoinsSimple(nAmount, nMinValue, nOutputValue, GetTime(), 1, setCoins, nValueIn))
1733         return false;
1734
1735     if (setCoins.empty())
1736         return false;
1737
1738     CWalletTx wtxNew;
1739     vector<const CWalletTx*> vwtxPrev;
1740
1741     // Reserve a new key pair from key pool
1742     CReserveKey reservekey(this);
1743     CPubKey vchPubKey = reservekey.GetReservedKey();
1744
1745     // Output script
1746     CScript scriptOutput;
1747     scriptOutput.SetDestination(vchPubKey.GetID());
1748
1749     // Insert output
1750     wtxNew.vout.push_back(CTxOut(0, scriptOutput));
1751
1752     double dWeight = 0;
1753     BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1754     {
1755         int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
1756
1757         // Add current coin to inputs list and add its credit to transaction output
1758         wtxNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
1759         wtxNew.vout[0].nValue += nCredit;
1760         vwtxPrev.push_back(pcoin.first);
1761
1762 /*
1763         // Replaced with estimation for performance purposes
1764
1765         for (unsigned int i = 0; i < wtxNew.vin.size(); i++) {
1766             const CWalletTx *txin = vwtxPrev[i];
1767
1768             // Sign scripts to get actual transaction size for fee calculation
1769             if (!SignSignature(*this, *txin, wtxNew, i))
1770                 return false;
1771         }
1772 */
1773
1774         // Assuming that average scriptsig size is 110 bytes
1775         int64 nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION) + wtxNew.vin.size() * 110;
1776         dWeight += (double)nCredit * pcoin.first->GetDepthInMainChain();
1777
1778         double dFinalPriority = dWeight /= nBytes;
1779         bool fAllowFree = CTransaction::AllowFree(dFinalPriority);
1780
1781         // Get actual transaction fee according to its estimated size and priority
1782         int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes);
1783
1784         // Prepare transaction for commit if sum is enough ot its size is too big
1785         if (nBytes >= MAX_BLOCK_SIZE_GEN/6 || wtxNew.vout[0].nValue >= nOutputValue)
1786         {
1787             wtxNew.vout[0].nValue -= nMinFee; // Set actual fee
1788
1789             for (unsigned int i = 0; i < wtxNew.vin.size(); i++) {
1790                 const CWalletTx *txin = vwtxPrev[i];
1791
1792                 // Sign all scripts
1793                 if (!SignSignature(*this, *txin, wtxNew, i))
1794                     return false;
1795             }
1796
1797             // Try to commit, return false on failure
1798             if (!CommitTransaction(wtxNew, reservekey))
1799                 return false;
1800
1801             listMerged.push_back(wtxNew.GetHash()); // Add to hashes list
1802
1803             dWeight = 0;  // Reset all temporary values
1804             vwtxPrev.clear();
1805             wtxNew.SetNull();
1806             wtxNew.vout.push_back(CTxOut(0, scriptOutput));
1807         }
1808     }
1809
1810     // Create transactions if there are some unhandled coins left
1811     if (wtxNew.vout[0].nValue > 0) {
1812         int64 nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION) + wtxNew.vin.size() * 110;
1813
1814         double dFinalPriority = dWeight /= nBytes;
1815         bool fAllowFree = CTransaction::AllowFree(dFinalPriority);
1816
1817         // Get actual transaction fee according to its size and priority
1818         int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes);
1819
1820         wtxNew.vout[0].nValue -= nMinFee; // Set actual fee
1821
1822         if (wtxNew.vout[0].nValue <= 0)
1823             return false;
1824
1825         for (unsigned int i = 0; i < wtxNew.vin.size(); i++) {
1826             const CWalletTx *txin = vwtxPrev[i];
1827
1828             // Sign all scripts again
1829             if (!SignSignature(*this, *txin, wtxNew, i))
1830                 return false;
1831         }
1832
1833         // Try to commit, return false on failure
1834         if (!CommitTransaction(wtxNew, reservekey))
1835             return false;
1836
1837         listMerged.push_back(wtxNew.GetHash()); // Add to hashes list
1838     }
1839
1840     return true;
1841 }
1842
1843
1844 bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key)
1845 {
1846     // The following combine threshold is important to security
1847     // Should not be adjusted if you don't understand the consequences
1848     int64 nCombineThreshold = GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits) / 3;
1849
1850     CBigNum bnTargetPerCoinDay;
1851     bnTargetPerCoinDay.SetCompact(nBits);
1852
1853     txNew.vin.clear();
1854     txNew.vout.clear();
1855
1856     // Mark coin stake transaction
1857     CScript scriptEmpty;
1858     scriptEmpty.clear();
1859     txNew.vout.push_back(CTxOut(0, scriptEmpty));
1860
1861     // Choose coins to use
1862     int64 nBalance = GetBalance();
1863     int64 nReserveBalance = 0;
1864
1865     if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance))
1866         return error("CreateCoinStake : invalid reserve balance amount");
1867
1868     if (nBalance <= nReserveBalance)
1869         return false;
1870
1871     vector<const CWalletTx*> vwtxPrev;
1872
1873     CTxDB txdb("r");
1874     {
1875         LOCK2(cs_main, cs_wallet);
1876         // Cache outputs unless best block or wallet transaction set changed
1877         if (!fCoinsDataActual)
1878         {
1879             mapMeta.clear();
1880             int64 nValueIn = 0;
1881             CoinsSet setCoins;
1882             if (!SelectCoinsSimple(nBalance - nReserveBalance, MIN_TX_FEE, MAX_MONEY, txNew.nTime, nCoinbaseMaturity * 10, setCoins, nValueIn))
1883                 return false;
1884
1885             if (setCoins.empty())
1886                 return false;
1887
1888             {
1889                 CTxIndex txindex;
1890                 CBlock block;
1891                 for(CoinsSet::iterator pcoin = setCoins.begin(); pcoin != setCoins.end(); pcoin++)
1892                 {
1893                     // Load transaction index item
1894                     if (!txdb.ReadTxIndex(pcoin->first->GetHash(), txindex))
1895                         continue;
1896
1897                     // Read block header
1898                     if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
1899                         continue;
1900
1901                     uint64 nStakeModifier = 0;
1902                     if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier))
1903                         continue;
1904
1905                     // Add meta record
1906                     // txid => ((txindex, (tx, vout.n)), (block, modifier))
1907                     mapMeta[make_pair(pcoin->first->GetHash(), pcoin->second)] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier));
1908
1909                     if (fDebug)
1910                         printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str());
1911                 }
1912             }
1913
1914             if (fDebug)
1915                 printf("Stake miner: %zu meta items loaded for %zu coins\n", mapMeta.size(), setCoins.size());
1916
1917             fCoinsDataActual = true;
1918         }
1919     }
1920
1921     int64 nCredit = 0;
1922     CScript scriptPubKeyKernel;
1923
1924     KernelSearchSettings settings;
1925     settings.nBits = nBits;
1926     settings.nTime = txNew.nTime;
1927     settings.nOffset = 0;
1928     settings.nLimit = mapMeta.size();
1929     settings.nSearchInterval = nSearchInterval;
1930
1931     unsigned int nTimeTx, nBlockTime;
1932     COutPoint prevoutStake;
1933     CoinsSet::value_type kernelcoin;
1934
1935     if (ScanForStakeKernelHash(mapMeta, settings, kernelcoin, nTimeTx, nBlockTime))
1936     {
1937         // Found a kernel
1938         if (fDebug && GetBoolArg("-printcoinstake"))
1939             printf("CreateCoinStake : kernel found\n");
1940         vector<valtype> vSolutions;
1941         txnouttype whichType;
1942         CScript scriptPubKeyOut;
1943         scriptPubKeyKernel = kernelcoin.first->vout[kernelcoin.second].scriptPubKey;
1944         if (!Solver(scriptPubKeyKernel, whichType, vSolutions))
1945         {
1946             if (fDebug && GetBoolArg("-printcoinstake"))
1947                 printf("CreateCoinStake : failed to parse kernel\n");
1948             return false;
1949         }
1950         if (fDebug && GetBoolArg("-printcoinstake"))
1951             printf("CreateCoinStake : parsed kernel type=%d\n", whichType);
1952         if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH)
1953         {
1954             if (fDebug && GetBoolArg("-printcoinstake"))
1955                 printf("CreateCoinStake : no support for kernel type=%d\n", whichType);
1956             return false;  // only support pay to public key and pay to address
1957         }
1958         if (whichType == TX_PUBKEYHASH) // pay to address type
1959         {
1960             // convert to pay to public key type
1961             if (!keystore.GetKey(uint160(vSolutions[0]), key))
1962             {
1963                 if (fDebug && GetBoolArg("-printcoinstake"))
1964                     printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
1965                 return false;  // unable to find corresponding public key
1966             }
1967             scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG;
1968         }
1969         if (whichType == TX_PUBKEY)
1970         {
1971             valtype& vchPubKey = vSolutions[0];
1972             if (!keystore.GetKey(Hash160(vchPubKey), key))
1973             {
1974                 if (fDebug && GetBoolArg("-printcoinstake"))
1975                     printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
1976                 return false;  // unable to find corresponding public key
1977             }
1978             if (key.GetPubKey() != vchPubKey)
1979             {
1980                 if (fDebug && GetBoolArg("-printcoinstake"))
1981                     printf("CreateCoinStake : invalid key for kernel type=%d\n", whichType);
1982                 return false; // keys mismatch
1983             }
1984
1985             scriptPubKeyOut = scriptPubKeyKernel;
1986         }
1987
1988         txNew.nTime = nTimeTx;
1989         txNew.vin.push_back(CTxIn(kernelcoin.first->GetHash(), kernelcoin.second));
1990         nCredit += kernelcoin.first->vout[kernelcoin.second].nValue;
1991         vwtxPrev.push_back(kernelcoin.first);
1992         txNew.vout.push_back(CTxOut(0, scriptPubKeyOut));
1993
1994         if (GetWeight((int64)nBlockTime, (int64)txNew.nTime) < nStakeMaxAge)
1995             txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake
1996         if (fDebug && GetBoolArg("-printcoinstake"))
1997             printf("CreateCoinStake : added kernel type=%d\n", whichType);
1998     }
1999
2000     if (nCredit == 0 || nCredit > nBalance - nReserveBalance)
2001         return false;
2002
2003     // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier))
2004     for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++)
2005     {
2006         // Get coin
2007         CoinsSet::value_type pcoin = meta_item->second.first.second;
2008
2009         // Attempt to add more inputs
2010         // Only add coins of the same key/address as kernel
2011         if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey))
2012             && pcoin.first->GetHash() != txNew.vin[0].prevout.hash)
2013         {
2014             int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)txNew.nTime);
2015
2016             // Stop adding more inputs if already too many inputs
2017             if (txNew.vin.size() >= 100)
2018                 break;
2019             // Stop adding more inputs if value is already pretty significant
2020             if (nCredit > nCombineThreshold)
2021                 break;
2022             // Stop adding inputs if reached reserve limit
2023             if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance)
2024                 break;
2025             // Do not add additional significant input
2026             if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold)
2027                 continue;
2028             // Do not add input that is still too young
2029             if (nTimeWeight < nStakeMaxAge)
2030                 continue;
2031
2032             txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
2033             nCredit += pcoin.first->vout[pcoin.second].nValue;
2034             vwtxPrev.push_back(pcoin.first);
2035         }
2036     }
2037
2038     // Calculate coin age reward
2039     {
2040         uint64 nCoinAge;
2041         CTxDB txdb("r");
2042         if (!txNew.GetCoinAge(txdb, nCoinAge))
2043             return error("CreateCoinStake : failed to calculate coin age");
2044         nCredit += GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime);
2045     }
2046
2047     int64 nMinFee = 0;
2048     while (true)
2049     {
2050         // Set output amount
2051         if (txNew.vout.size() == 3)
2052         {
2053             txNew.vout[1].nValue = ((nCredit - nMinFee) / 2 / CENT) * CENT;
2054             txNew.vout[2].nValue = nCredit - nMinFee - txNew.vout[1].nValue;
2055         }
2056         else
2057             txNew.vout[1].nValue = nCredit - nMinFee;
2058
2059         // Sign
2060         int nIn = 0;
2061         BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev)
2062         {
2063             if (!SignSignature(*this, *pcoin, txNew, nIn++))
2064                 return error("CreateCoinStake : failed to sign coinstake");
2065         }
2066
2067         // Limit size
2068         unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
2069         if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
2070             return error("CreateCoinStake : exceeded coinstake size limit");
2071
2072         // Check enough fee is paid
2073         if (nMinFee < txNew.GetMinFee(1, false, GMF_BLOCK, nBytes) - CENT)
2074         {
2075             nMinFee = txNew.GetMinFee(1, false, GMF_BLOCK, nBytes) - CENT;
2076             continue; // try signing again
2077         }
2078         else
2079         {
2080             if (fDebug && GetBoolArg("-printfee"))
2081                 printf("CreateCoinStake : fee for coinstake %s\n", FormatMoney(nMinFee).c_str());
2082             break;
2083         }
2084     }
2085
2086     // Successfully generated coinstake
2087     return true;
2088 }
2089
2090
2091 // Call after CreateTransaction unless you want to abort
2092 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
2093 {
2094     {
2095         LOCK2(cs_main, cs_wallet);
2096         printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
2097         {
2098             // This is only to keep the database open to defeat the auto-flush for the
2099             // duration of this scope.  This is the only place where this optimization
2100             // maybe makes sense; please don't do it anywhere else.
2101             CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
2102
2103             // Take key pair from key pool so it won't be used again
2104             reservekey.KeepKey();
2105
2106             // Add tx to wallet, because if it has change it's also ours,
2107             // otherwise just for transaction history.
2108             AddToWallet(wtxNew);
2109
2110             // Mark old coins as spent
2111             set<CWalletTx*> setCoins;
2112             BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
2113             {
2114                 CWalletTx &coin = mapWallet[txin.prevout.hash];
2115                 coin.BindWallet(this);
2116                 coin.MarkSpent(txin.prevout.n);
2117                 coin.WriteToDisk();
2118                 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
2119             }
2120
2121             if (fFileBacked)
2122                 delete pwalletdb;
2123         }
2124
2125         // Track how many getdata requests our transaction gets
2126         mapRequestCount[wtxNew.GetHash()] = 0;
2127
2128         // Broadcast
2129         if (!wtxNew.AcceptToMemoryPool())
2130         {
2131             // This must not fail. The transaction has already been signed and recorded.
2132             printf("CommitTransaction() : Error: Transaction not valid");
2133             return false;
2134         }
2135         wtxNew.RelayWalletTransaction();
2136     }
2137     return true;
2138 }
2139
2140
2141
2142
2143 string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
2144 {
2145     CReserveKey reservekey(this);
2146     int64 nFeeRequired;
2147
2148     if (IsLocked())
2149     {
2150         string strError = _("Error: Wallet locked, unable to create transaction  ");
2151         printf("SendMoney() : %s", strError.c_str());
2152         return strError;
2153     }
2154     if (fWalletUnlockMintOnly)
2155     {
2156         string strError = _("Error: Wallet unlocked for block minting only, unable to create transaction.");
2157         printf("SendMoney() : %s", strError.c_str());
2158         return strError;
2159     }
2160     if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
2161     {
2162         string strError;
2163         if (nValue + nFeeRequired > GetBalance())
2164             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());
2165         else
2166             strError = _("Error: Transaction creation failed  ");
2167         printf("SendMoney() : %s", strError.c_str());
2168         return strError;
2169     }
2170
2171     if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending...")))
2172         return "ABORTED";
2173
2174     if (!CommitTransaction(wtxNew, reservekey))
2175         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.");
2176
2177     return "";
2178 }
2179
2180
2181
2182 string CWallet::SendMoneyToDestination(const CTxDestination& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
2183 {
2184     // Check amount
2185     if (nValue <= 0)
2186         return _("Invalid amount");
2187     if (nValue + nTransactionFee > GetBalance())
2188         return _("Insufficient funds");
2189
2190     // Parse Bitcoin address
2191     CScript scriptPubKey;
2192     scriptPubKey.SetDestination(address);
2193
2194     return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
2195 }
2196
2197
2198
2199
2200 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
2201 {
2202     if (!fFileBacked)
2203         return DB_LOAD_OK;
2204     fFirstRunRet = false;
2205     DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
2206     if (nLoadWalletRet == DB_NEED_REWRITE)
2207     {
2208         if (CDB::Rewrite(strWalletFile, "\x04pool"))
2209         {
2210             setKeyPool.clear();
2211             // Note: can't top-up keypool here, because wallet is locked.
2212             // User will be prompted to unlock wallet the next operation
2213             // the requires a new key.
2214         }
2215     }
2216
2217     if (nLoadWalletRet != DB_LOAD_OK)
2218         return nLoadWalletRet;
2219     fFirstRunRet = !vchDefaultKey.IsValid();
2220
2221     NewThread(ThreadFlushWalletDB, &strWalletFile);
2222     return DB_LOAD_OK;
2223 }
2224
2225
2226 bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName)
2227 {
2228     std::map<CTxDestination, std::string>::iterator mi = mapAddressBook.find(address);
2229     mapAddressBook[address] = strName;
2230     NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
2231     if (!fFileBacked)
2232         return false;
2233     return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
2234 }
2235
2236 bool CWallet::DelAddressBookName(const CTxDestination& address)
2237 {
2238     mapAddressBook.erase(address);
2239     NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED);
2240     if (!fFileBacked)
2241         return false;
2242     return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
2243 }
2244
2245
2246 void CWallet::PrintWallet(const CBlock& block)
2247 {
2248     {
2249         LOCK(cs_wallet);
2250         if (block.IsProofOfWork() && mapWallet.count(block.vtx[0].GetHash()))
2251         {
2252             CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
2253             printf("    mine:  %d  %d  %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
2254         }
2255         if (block.IsProofOfStake() && mapWallet.count(block.vtx[1].GetHash()))
2256         {
2257             CWalletTx& wtx = mapWallet[block.vtx[1].GetHash()];
2258             printf("    stake: %d  %d  %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
2259          }
2260
2261     }
2262     printf("\n");
2263 }
2264
2265 bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
2266 {
2267     {
2268         LOCK(cs_wallet);
2269         map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
2270         if (mi != mapWallet.end())
2271         {
2272             wtx = (*mi).second;
2273             return true;
2274         }
2275     }
2276     return false;
2277 }
2278
2279 bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
2280 {
2281     if (fFileBacked)
2282     {
2283         if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
2284             return false;
2285     }
2286     vchDefaultKey = vchPubKey;
2287     return true;
2288 }
2289
2290 bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
2291 {
2292     if (!pwallet->fFileBacked)
2293         return false;
2294     strWalletFileOut = pwallet->strWalletFile;
2295     return true;
2296 }
2297
2298 //
2299 // Mark old keypool keys as used,
2300 // and generate all new keys
2301 //
2302 bool CWallet::NewKeyPool()
2303 {
2304     {
2305         LOCK(cs_wallet);
2306         CWalletDB walletdb(strWalletFile);
2307         BOOST_FOREACH(int64 nIndex, setKeyPool)
2308             walletdb.ErasePool(nIndex);
2309         setKeyPool.clear();
2310
2311         if (IsLocked())
2312             return false;
2313
2314         int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
2315         for (int i = 0; i < nKeys; i++)
2316         {
2317             int64 nIndex = i+1;
2318             walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
2319             setKeyPool.insert(nIndex);
2320         }
2321         printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
2322     }
2323     return true;
2324 }
2325
2326 bool CWallet::TopUpKeyPool(unsigned int nSize)
2327 {
2328     {
2329         LOCK(cs_wallet);
2330
2331         if (IsLocked())
2332             return false;
2333
2334         CWalletDB walletdb(strWalletFile);
2335
2336         // Top up key pool
2337         unsigned int nTargetSize;
2338         if (nSize > 0)
2339             nTargetSize = nSize;
2340         else
2341             nTargetSize = max(GetArg("-keypool", 100), 0LL);
2342
2343         while (setKeyPool.size() < (nTargetSize + 1))
2344         {
2345             int64 nEnd = 1;
2346             if (!setKeyPool.empty())
2347                 nEnd = *(--setKeyPool.end()) + 1;
2348             if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
2349                 throw runtime_error("TopUpKeyPool() : writing generated key failed");
2350             setKeyPool.insert(nEnd);
2351             printf("keypool added key %"PRI64d", size=%"PRIszu"\n", nEnd, setKeyPool.size());
2352         }
2353     }
2354     return true;
2355 }
2356
2357 void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
2358 {
2359     nIndex = -1;
2360     keypool.vchPubKey = CPubKey();
2361     {
2362         LOCK(cs_wallet);
2363
2364         if (!IsLocked())
2365             TopUpKeyPool();
2366
2367         // Get the oldest key
2368         if(setKeyPool.empty())
2369             return;
2370
2371         CWalletDB walletdb(strWalletFile);
2372
2373         nIndex = *(setKeyPool.begin());
2374         setKeyPool.erase(setKeyPool.begin());
2375         if (!walletdb.ReadPool(nIndex, keypool))
2376             throw runtime_error("ReserveKeyFromKeyPool() : read failed");
2377         if (!HaveKey(keypool.vchPubKey.GetID()))
2378             throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
2379         assert(keypool.vchPubKey.IsValid());
2380         if (fDebug && GetBoolArg("-printkeypool"))
2381             printf("keypool reserve %"PRI64d"\n", nIndex);
2382     }
2383 }
2384
2385 int64 CWallet::AddReserveKey(const CKeyPool& keypool)
2386 {
2387     {
2388         LOCK2(cs_main, cs_wallet);
2389         CWalletDB walletdb(strWalletFile);
2390
2391         int64 nIndex = 1 + *(--setKeyPool.end());
2392         if (!walletdb.WritePool(nIndex, keypool))
2393             throw runtime_error("AddReserveKey() : writing added key failed");
2394         setKeyPool.insert(nIndex);
2395         return nIndex;
2396     }
2397     return -1;
2398 }
2399
2400 void CWallet::KeepKey(int64 nIndex)
2401 {
2402     // Remove from key pool
2403     if (fFileBacked)
2404     {
2405         CWalletDB walletdb(strWalletFile);
2406         walletdb.ErasePool(nIndex);
2407     }
2408     if(fDebug)
2409         printf("keypool keep %"PRI64d"\n", nIndex);
2410 }
2411
2412 void CWallet::ReturnKey(int64 nIndex)
2413 {
2414     // Return to key pool
2415     {
2416         LOCK(cs_wallet);
2417         setKeyPool.insert(nIndex);
2418     }
2419     if(fDebug)
2420         printf("keypool return %"PRI64d"\n", nIndex);
2421 }
2422
2423 bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
2424 {
2425     int64 nIndex = 0;
2426     CKeyPool keypool;
2427     {
2428         LOCK(cs_wallet);
2429         ReserveKeyFromKeyPool(nIndex, keypool);
2430         if (nIndex == -1)
2431         {
2432             if (fAllowReuse && vchDefaultKey.IsValid())
2433             {
2434                 result = vchDefaultKey;
2435                 return true;
2436             }
2437             if (IsLocked()) return false;
2438             result = GenerateNewKey();
2439             return true;
2440         }
2441         KeepKey(nIndex);
2442         result = keypool.vchPubKey;
2443     }
2444     return true;
2445 }
2446
2447 int64 CWallet::GetOldestKeyPoolTime()
2448 {
2449     int64 nIndex = 0;
2450     CKeyPool keypool;
2451     ReserveKeyFromKeyPool(nIndex, keypool);
2452     if (nIndex == -1)
2453         return GetTime();
2454     ReturnKey(nIndex);
2455     return keypool.nTime;
2456 }
2457
2458 std::map<CTxDestination, int64> CWallet::GetAddressBalances()
2459 {
2460     map<CTxDestination, int64> balances;
2461
2462     {
2463         LOCK(cs_wallet);
2464         BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
2465         {
2466             CWalletTx *pcoin = &walletEntry.second;
2467
2468             if (!pcoin->IsFinal() || !pcoin->IsTrusted())
2469                 continue;
2470
2471             if ((pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetBlocksToMaturity() > 0)
2472                 continue;
2473
2474             int nDepth = pcoin->GetDepthInMainChain();
2475             if (nDepth < (pcoin->IsFromMe(MINE_ALL) ? 0 : 1))
2476                 continue;
2477
2478             for (unsigned int i = 0; i < pcoin->vout.size(); i++)
2479             {
2480                 CTxDestination addr;
2481                 if (!IsMine(pcoin->vout[i]))
2482                     continue;
2483                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
2484                     continue;
2485
2486                 int64 n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue;
2487
2488                 if (!balances.count(addr))
2489                     balances[addr] = 0;
2490                 balances[addr] += n;
2491             }
2492         }
2493     }
2494
2495     return balances;
2496 }
2497
2498 set< set<CTxDestination> > CWallet::GetAddressGroupings()
2499 {
2500     set< set<CTxDestination> > groupings;
2501     set<CTxDestination> grouping;
2502
2503     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
2504     {
2505         CWalletTx *pcoin = &walletEntry.second;
2506
2507         if (pcoin->vin.size() > 0 && IsMine(pcoin->vin[0]))
2508         {
2509             // group all input addresses with each other
2510             BOOST_FOREACH(CTxIn txin, pcoin->vin)
2511             {
2512                 CTxDestination address;
2513                 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
2514                     continue;
2515                 grouping.insert(address);
2516             }
2517
2518             // group change with input addresses
2519             BOOST_FOREACH(CTxOut txout, pcoin->vout)
2520                 if (IsChange(txout))
2521                 {
2522                     CWalletTx tx = mapWallet[pcoin->vin[0].prevout.hash];
2523                     CTxDestination txoutAddr;
2524                     if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
2525                         continue;
2526                     grouping.insert(txoutAddr);
2527                 }
2528             groupings.insert(grouping);
2529             grouping.clear();
2530         }
2531
2532         // group lone addrs by themselves
2533         for (unsigned int i = 0; i < pcoin->vout.size(); i++)
2534             if (IsMine(pcoin->vout[i]))
2535             {
2536                 CTxDestination address;
2537                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
2538                     continue;
2539                 grouping.insert(address);
2540                 groupings.insert(grouping);
2541                 grouping.clear();
2542             }
2543     }
2544
2545     set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
2546     map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
2547     BOOST_FOREACH(set<CTxDestination> grouping, groupings)
2548     {
2549         // make a set of all the groups hit by this new group
2550         set< set<CTxDestination>* > hits;
2551         map< CTxDestination, set<CTxDestination>* >::iterator it;
2552         BOOST_FOREACH(CTxDestination address, grouping)
2553             if ((it = setmap.find(address)) != setmap.end())
2554                 hits.insert((*it).second);
2555
2556         // merge all hit groups into a new single group and delete old groups
2557         set<CTxDestination>* merged = new set<CTxDestination>(grouping);
2558         BOOST_FOREACH(set<CTxDestination>* hit, hits)
2559         {
2560             merged->insert(hit->begin(), hit->end());
2561             uniqueGroupings.erase(hit);
2562             delete hit;
2563         }
2564         uniqueGroupings.insert(merged);
2565
2566         // update setmap
2567         BOOST_FOREACH(CTxDestination element, *merged)
2568             setmap[element] = merged;
2569     }
2570
2571     set< set<CTxDestination> > ret;
2572     BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
2573     {
2574         ret.insert(*uniqueGrouping);
2575         delete uniqueGrouping;
2576     }
2577
2578     return ret;
2579 }
2580
2581 // ppcoin: check 'spent' consistency between wallet and txindex
2582 // ppcoin: fix wallet spent state according to txindex
2583 void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool fCheckOnly)
2584 {
2585     nMismatchFound = 0;
2586     nBalanceInQuestion = 0;
2587
2588     LOCK(cs_wallet);
2589     vector<CWalletTx*> vCoins;
2590     vCoins.reserve(mapWallet.size());
2591     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2592         vCoins.push_back(&(*it).second);
2593
2594     CTxDB txdb("r");
2595     BOOST_FOREACH(CWalletTx* pcoin, vCoins)
2596     {
2597         // Find the corresponding transaction index
2598         CTxIndex txindex;
2599         if (!txdb.ReadTxIndex(pcoin->GetHash(), txindex))
2600             continue;
2601         for (unsigned int n=0; n < pcoin->vout.size(); n++)
2602         {
2603             if (IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull()))
2604             {
2605                 printf("FixSpentCoins found lost coin %sppc %s[%d], %s\n",
2606                     FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing");
2607                 nMismatchFound++;
2608                 nBalanceInQuestion += pcoin->vout[n].nValue;
2609                 if (!fCheckOnly)
2610                 {
2611                     pcoin->MarkUnspent(n);
2612                     pcoin->WriteToDisk();
2613                 }
2614             }
2615             else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull()))
2616             {
2617                 printf("FixSpentCoins found spent coin %sppc %s[%d], %s\n",
2618                     FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing");
2619                 nMismatchFound++;
2620                 nBalanceInQuestion += pcoin->vout[n].nValue;
2621                 if (!fCheckOnly)
2622                 {
2623                     pcoin->MarkSpent(n);
2624                     pcoin->WriteToDisk();
2625                 }
2626             }
2627
2628         }
2629
2630         if(IsMine((CTransaction)*pcoin) && (pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetDepthInMainChain() == 0)
2631         {
2632             printf("FixSpentCoins %s tx %s\n", fCheckOnly ? "found" : "removed", pcoin->GetHash().ToString().c_str());
2633             if (!fCheckOnly)
2634             {
2635                 EraseFromWallet(pcoin->GetHash());
2636             }
2637         }
2638     }
2639 }
2640
2641 // ppcoin: disable transaction (only for coinstake)
2642 void CWallet::DisableTransaction(const CTransaction &tx)
2643 {
2644     if (!tx.IsCoinStake() || !IsFromMe(tx))
2645         return; // only disconnecting coinstake requires marking input unspent
2646
2647     LOCK(cs_wallet);
2648     BOOST_FOREACH(const CTxIn& txin, tx.vin)
2649     {
2650         map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
2651         if (mi != mapWallet.end())
2652         {
2653             CWalletTx& prev = (*mi).second;
2654             if (txin.prevout.n < prev.vout.size() && IsMine(prev.vout[txin.prevout.n]))
2655             {
2656                 prev.MarkUnspent(txin.prevout.n);
2657                 prev.WriteToDisk();
2658             }
2659         }
2660     }
2661 }
2662
2663 CPubKey CReserveKey::GetReservedKey()
2664 {
2665     if (nIndex == -1)
2666     {
2667         CKeyPool keypool;
2668         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
2669         if (nIndex != -1)
2670             vchPubKey = keypool.vchPubKey;
2671         else
2672         {
2673             printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
2674             vchPubKey = pwallet->vchDefaultKey;
2675         }
2676     }
2677     assert(vchPubKey.IsValid());
2678     return vchPubKey;
2679 }
2680
2681 void CReserveKey::KeepKey()
2682 {
2683     if (nIndex != -1)
2684         pwallet->KeepKey(nIndex);
2685     nIndex = -1;
2686     vchPubKey = CPubKey();
2687 }
2688
2689 void CReserveKey::ReturnKey()
2690 {
2691     if (nIndex != -1)
2692         pwallet->ReturnKey(nIndex);
2693     nIndex = -1;
2694     vchPubKey = CPubKey();
2695 }
2696
2697 void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
2698 {
2699     setAddress.clear();
2700
2701     CWalletDB walletdb(strWalletFile);
2702
2703     LOCK2(cs_main, cs_wallet);
2704     BOOST_FOREACH(const int64& id, setKeyPool)
2705     {
2706         CKeyPool keypool;
2707         if (!walletdb.ReadPool(id, keypool))
2708             throw runtime_error("GetAllReserveKeyHashes() : read failed");
2709         assert(keypool.vchPubKey.IsValid());
2710         CKeyID keyID = keypool.vchPubKey.GetID();
2711         if (!HaveKey(keyID))
2712             throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
2713         setAddress.insert(keyID);
2714     }
2715 }
2716
2717 void CWallet::UpdatedTransaction(const uint256 &hashTx)
2718 {
2719     {
2720         LOCK(cs_wallet);
2721         // Only notify UI if this transaction is in this wallet
2722         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
2723         if (mi != mapWallet.end())
2724         {
2725             NotifyTransactionChanged(this, hashTx, CT_UPDATED);
2726             vMintingWalletUpdated.push_back(hashTx);
2727         }
2728     }
2729 }
2730
2731 void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64> &mapKeyBirth) const {
2732     mapKeyBirth.clear();
2733
2734     // get birth times for keys with metadata
2735     for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
2736         if (it->second.nCreateTime)
2737             mapKeyBirth[it->first] = it->second.nCreateTime;
2738
2739     // map in which we'll infer heights of other keys
2740     CBlockIndex *pindexMax = FindBlockByHeight(std::max(0, nBestHeight - 144)); // the tip can be reorganised; use a 144-block safety margin
2741     std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
2742     std::set<CKeyID> setKeys;
2743     GetKeys(setKeys);
2744     BOOST_FOREACH(const CKeyID &keyid, setKeys) {
2745         if (mapKeyBirth.count(keyid) == 0)
2746             mapKeyFirstBlock[keyid] = pindexMax;
2747     }
2748     setKeys.clear();
2749
2750     // if there are no such keys, we're done
2751     if (mapKeyFirstBlock.empty())
2752         return;
2753
2754     // find first block that affects those keys, if there are any left
2755     std::vector<CKeyID> vAffected;
2756     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
2757         // iterate over all wallet transactions...
2758         const CWalletTx &wtx = (*it).second;
2759         std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
2760         if (blit != mapBlockIndex.end() && blit->second->IsInMainChain()) {
2761             // ... which are already in a block
2762             int nHeight = blit->second->nHeight;
2763             BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
2764                 // iterate over all their outputs
2765                 ::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected);
2766                 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
2767                     // ... and all their affected keys
2768                     std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
2769                     if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
2770                         rit->second = blit->second;
2771                 }
2772                 vAffected.clear();
2773             }
2774         }
2775     }
2776
2777     // Extract block timestamps for those keys
2778     for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
2779         mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off
2780 }