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