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