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