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