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