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