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