]> Git Repo - VerusCoin.git/blob - src/wallet/wallet.cpp
Reserve transaction and conversion fix
[VerusCoin.git] / src / wallet / wallet.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "wallet/wallet.h"
7
8 #include "checkpoints.h"
9 #include "coincontrol.h"
10 #include "consensus/upgrades.h"
11 #include "consensus/validation.h"
12 #include "consensus/consensus.h"
13 #include "init.h"
14 #include "key_io.h"
15 #include "main.h"
16 #include "mmr.h"
17 #include "net.h"
18 #include "rpc/protocol.h"
19 #include "script/script.h"
20 #include "script/sign.h"
21 #include "timedata.h"
22 #include "utilmoneystr.h"
23 #include "zcash/Note.hpp"
24 #include "crypter.h"
25 #include "coins.h"
26 #include "zcash/zip32.h"
27 #include "cc/StakeGuard.h"
28 #include "pbaas/pbaas.h"
29
30 #include <assert.h>
31
32 #include <boost/algorithm/string/replace.hpp>
33 #include <boost/filesystem.hpp>
34 #include <boost/thread.hpp>
35
36 using namespace std;
37 using namespace libzcash;
38
39 /**
40  * Settings
41  */
42 CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
43 CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
44 unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
45 bool bSpendZeroConfChange = true;
46 bool fSendFreeTransactions = false;
47 bool fPayAtLeastCustomFee = true;
48 #include "komodo_defs.h"
49
50 extern int32_t USE_EXTERNAL_PUBKEY;
51 extern std::string NOTARY_PUBKEY;
52 extern int32_t KOMODO_EXCHANGEWALLET;
53 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
54 extern uint160 ASSETCHAINS_CHAINID;
55 extern int32_t VERUS_MIN_STAKEAGE;
56 CBlockIndex *komodo_chainactive(int32_t height);
57 extern std::string DONATION_PUBKEY;
58
59 /**
60  * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
61  * Override with -mintxfee
62  */
63 CFeeRate CWallet::minTxFee = CFeeRate(1000);
64
65 /** @defgroup mapWallet
66  *
67  * @{
68  */
69
70 struct CompareValueOnly
71 {
72     bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1,
73                     const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const
74     {
75         return t1.first < t2.first;
76     }
77 };
78
79 std::string JSOutPoint::ToString() const
80 {
81     return strprintf("JSOutPoint(%s, %d, %d)", hash.ToString().substr(0,10), js, n);
82 }
83
84 std::string COutput::ToString() const
85 {
86     return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue));
87 }
88
89 const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
90 {
91     LOCK(cs_wallet);
92     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
93     if (it == mapWallet.end())
94         return NULL;
95     return &(it->second);
96 }
97
98 // Generate a new spending key and return its public payment address
99 libzcash::SproutPaymentAddress CWallet::GenerateNewSproutZKey()
100 {
101     AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata
102
103     auto k = SproutSpendingKey::random();
104     auto addr = k.address();
105
106     // Check for collision, even though it is unlikely to ever occur
107     if (CCryptoKeyStore::HaveSproutSpendingKey(addr))
108         throw std::runtime_error("CWallet::GenerateNewSproutZKey(): Collision detected");
109
110     // Create new metadata
111     int64_t nCreationTime = GetTime();
112     mapSproutZKeyMetadata[addr] = CKeyMetadata(nCreationTime);
113
114     if (!AddSproutZKey(k))
115         throw std::runtime_error("CWallet::GenerateNewSproutZKey(): AddSproutZKey failed");
116     return addr;
117 }
118
119 // Generate a new Sapling spending key and return its public payment address
120 SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
121 {
122     AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
123
124     // Create new metadata
125     int64_t nCreationTime = GetTime();
126     CKeyMetadata metadata(nCreationTime);
127
128     // Try to get the seed
129     HDSeed seed;
130     if (!GetHDSeed(seed))
131         throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): HD seed not found");
132
133     auto m = libzcash::SaplingExtendedSpendingKey::Master(seed);
134     uint32_t bip44CoinType = Params().BIP44CoinType();
135
136     // We use a fixed keypath scheme of m/32'/coin_type'/account'
137     // Derive m/32'
138     auto m_32h = m.Derive(32 | ZIP32_HARDENED_KEY_LIMIT);
139     // Derive m/32'/coin_type'
140     auto m_32h_cth = m_32h.Derive(bip44CoinType | ZIP32_HARDENED_KEY_LIMIT);
141
142     // Derive account key at next index, skip keys already known to the wallet
143     libzcash::SaplingExtendedSpendingKey xsk;
144     do
145     {
146         xsk = m_32h_cth.Derive(hdChain.saplingAccountCounter | ZIP32_HARDENED_KEY_LIMIT);
147         metadata.hdKeypath = "m/32'/" + std::to_string(bip44CoinType) + "'/" + std::to_string(hdChain.saplingAccountCounter) + "'";
148         metadata.seedFp = hdChain.seedFp;
149         // Increment childkey index
150         hdChain.saplingAccountCounter++;
151     } while (HaveSaplingSpendingKey(xsk.expsk.full_viewing_key()));
152
153     // Update the chain model in the database
154     if (fFileBacked && !CWalletDB(strWalletFile).WriteHDChain(hdChain))
155         throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): Writing HD chain model failed");
156
157     auto ivk = xsk.expsk.full_viewing_key().in_viewing_key();
158     mapSaplingZKeyMetadata[ivk] = metadata;
159
160     auto addr = xsk.DefaultAddress();
161     if (!AddSaplingZKey(xsk, addr)) {
162         throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed");
163     }
164     // return default sapling payment address.
165     return addr;
166 }
167
168 // Add spending key to keystore 
169 bool CWallet::AddSaplingZKey(
170     const libzcash::SaplingExtendedSpendingKey &sk,
171     const libzcash::SaplingPaymentAddress &defaultAddr)
172 {
173     AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
174
175     if (!CCryptoKeyStore::AddSaplingSpendingKey(sk, defaultAddr)) {
176         return false;
177     }
178     
179     if (!fFileBacked) {
180         return true;
181     }
182
183     if (!IsCrypted()) {
184         auto ivk = sk.expsk.full_viewing_key().in_viewing_key();
185         return CWalletDB(strWalletFile).WriteSaplingZKey(ivk, sk, mapSaplingZKeyMetadata[ivk]);
186     }
187     
188     return true;
189 }
190
191 // Add payment address -> incoming viewing key map entry
192 bool CWallet::AddSaplingIncomingViewingKey(
193     const libzcash::SaplingIncomingViewingKey &ivk,
194     const libzcash::SaplingPaymentAddress &addr)
195 {
196     AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
197
198     if (!CCryptoKeyStore::AddSaplingIncomingViewingKey(ivk, addr)) {
199         return false;
200     }
201
202     if (!fFileBacked) {
203         return true;
204     }
205
206     if (!IsCrypted()) {
207         return CWalletDB(strWalletFile).WriteSaplingPaymentAddress(addr, ivk);
208     }
209
210     return true;
211 }
212
213
214 // Add spending key to keystore and persist to disk
215 bool CWallet::AddSproutZKey(const libzcash::SproutSpendingKey &key)
216 {
217     AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata
218     auto addr = key.address();
219
220     if (!CCryptoKeyStore::AddSproutSpendingKey(key))
221         return false;
222
223     // check if we need to remove from viewing keys
224     if (HaveSproutViewingKey(addr))
225         RemoveSproutViewingKey(key.viewing_key());
226
227     if (!fFileBacked)
228         return true;
229
230     if (!IsCrypted()) {
231         return CWalletDB(strWalletFile).WriteZKey(addr,
232                                                   key,
233                                                   mapSproutZKeyMetadata[addr]);
234     }
235     return true;
236 }
237
238 CPubKey CWallet::GenerateNewKey()
239 {
240     AssertLockHeld(cs_wallet); // mapKeyMetadata
241     bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
242
243     CKey secret;
244     secret.MakeNewKey(fCompressed);
245
246     // Compressed public keys were introduced in version 0.6.0
247     if (fCompressed)
248         SetMinVersion(FEATURE_COMPRPUBKEY);
249
250     CPubKey pubkey = secret.GetPubKey();
251     assert(secret.VerifyPubKey(pubkey));
252
253     // Create new metadata
254     int64_t nCreationTime = GetTime();
255     mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
256     if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
257         nTimeFirstKey = nCreationTime;
258
259     if (!AddKeyPubKey(secret, pubkey))
260         throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
261     return pubkey;
262 }
263
264 bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
265 {
266     AssertLockHeld(cs_wallet); // mapKeyMetadata
267     if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
268         return false;
269
270     // check if we need to remove from watch-only
271     CScript script;
272     script = GetScriptForDestination(pubkey.GetID());
273     if (HaveWatchOnly(script))
274         RemoveWatchOnly(script);
275
276     if (!fFileBacked)
277         return true;
278     if (!IsCrypted()) {
279         return CWalletDB(strWalletFile).WriteKey(pubkey,
280                                                  secret.GetPrivKey(),
281                                                  mapKeyMetadata[pubkey.GetID()]);
282     }
283     return true;
284 }
285
286 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
287                             const vector<unsigned char> &vchCryptedSecret)
288 {
289
290     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
291         return false;
292     if (!fFileBacked)
293         return true;
294     {
295         LOCK(cs_wallet);
296         if (pwalletdbEncryption)
297             return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
298                                                         vchCryptedSecret,
299                                                         mapKeyMetadata[vchPubKey.GetID()]);
300         else
301             return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
302                                                             vchCryptedSecret,
303                                                             mapKeyMetadata[vchPubKey.GetID()]);
304     }
305     return false;
306 }
307
308
309 bool CWallet::AddCryptedSproutSpendingKey(
310     const libzcash::SproutPaymentAddress &address,
311     const libzcash::ReceivingKey &rk,
312     const std::vector<unsigned char> &vchCryptedSecret)
313 {
314     if (!CCryptoKeyStore::AddCryptedSproutSpendingKey(address, rk, vchCryptedSecret))
315         return false;
316     if (!fFileBacked)
317         return true;
318     {
319         LOCK(cs_wallet);
320         if (pwalletdbEncryption) {
321             return pwalletdbEncryption->WriteCryptedZKey(address,
322                                                          rk,
323                                                          vchCryptedSecret,
324                                                          mapSproutZKeyMetadata[address]);
325         } else {
326             return CWalletDB(strWalletFile).WriteCryptedZKey(address,
327                                                              rk,
328                                                              vchCryptedSecret,
329                                                              mapSproutZKeyMetadata[address]);
330         }
331     }
332     return false;
333 }
334
335 bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
336                                            const std::vector<unsigned char> &vchCryptedSecret,
337                                            const libzcash::SaplingPaymentAddress &defaultAddr)
338 {
339     if (!CCryptoKeyStore::AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, defaultAddr))
340         return false;
341     if (!fFileBacked)
342         return true;
343     {
344         LOCK(cs_wallet);
345         if (pwalletdbEncryption) {
346             return pwalletdbEncryption->WriteCryptedSaplingZKey(extfvk,
347                                                          vchCryptedSecret,
348                                                          mapSaplingZKeyMetadata[extfvk.fvk.in_viewing_key()]);
349         } else {
350             return CWalletDB(strWalletFile).WriteCryptedSaplingZKey(extfvk,
351                                                          vchCryptedSecret,
352                                                          mapSaplingZKeyMetadata[extfvk.fvk.in_viewing_key()]);
353         }
354     }
355     return false;
356 }
357
358 bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
359 {
360     AssertLockHeld(cs_wallet); // mapKeyMetadata
361     if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
362         nTimeFirstKey = meta.nCreateTime;
363
364     mapKeyMetadata[pubkey.GetID()] = meta;
365     return true;
366 }
367
368 bool CWallet::LoadZKeyMetadata(const SproutPaymentAddress &addr, const CKeyMetadata &meta)
369 {
370     AssertLockHeld(cs_wallet); // mapSproutZKeyMetadata
371     mapSproutZKeyMetadata[addr] = meta;
372     return true;
373 }
374
375 bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
376 {
377     return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
378 }
379
380 bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
381 {
382     return CCryptoKeyStore::AddCryptedSproutSpendingKey(addr, rk, vchCryptedSecret);
383 }
384
385 bool CWallet::LoadCryptedSaplingZKey(
386     const libzcash::SaplingExtendedFullViewingKey &extfvk,
387     const std::vector<unsigned char> &vchCryptedSecret)
388 {
389      return CCryptoKeyStore::AddCryptedSaplingSpendingKey(extfvk, vchCryptedSecret, extfvk.DefaultAddress());
390 }
391
392 bool CWallet::LoadSaplingZKeyMetadata(const libzcash::SaplingIncomingViewingKey &ivk, const CKeyMetadata &meta)
393 {
394     AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
395     mapSaplingZKeyMetadata[ivk] = meta;
396     return true;
397 }
398
399 bool CWallet::LoadSaplingZKey(const libzcash::SaplingExtendedSpendingKey &key)
400 {
401     return CCryptoKeyStore::AddSaplingSpendingKey(key, key.DefaultAddress());
402 }
403
404 bool CWallet::LoadSaplingPaymentAddress(
405     const libzcash::SaplingPaymentAddress &addr,
406     const libzcash::SaplingIncomingViewingKey &ivk)
407 {
408     return CCryptoKeyStore::AddSaplingIncomingViewingKey(ivk, addr);
409 }
410
411 bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key)
412 {
413     return CCryptoKeyStore::AddSproutSpendingKey(key);
414 }
415
416 bool CWallet::AddSproutViewingKey(const libzcash::SproutViewingKey &vk)
417 {
418     if (!CCryptoKeyStore::AddSproutViewingKey(vk)) {
419         return false;
420     }
421     nTimeFirstKey = 1; // No birthday information for viewing keys.
422     if (!fFileBacked) {
423         return true;
424     }
425     return CWalletDB(strWalletFile).WriteSproutViewingKey(vk);
426 }
427
428 bool CWallet::RemoveSproutViewingKey(const libzcash::SproutViewingKey &vk)
429 {
430     AssertLockHeld(cs_wallet);
431     if (!CCryptoKeyStore::RemoveSproutViewingKey(vk)) {
432         return false;
433     }
434     if (fFileBacked) {
435         if (!CWalletDB(strWalletFile).EraseSproutViewingKey(vk)) {
436             return false;
437         }
438     }
439
440     return true;
441 }
442
443 bool CWallet::LoadSproutViewingKey(const libzcash::SproutViewingKey &vk)
444 {
445     return CCryptoKeyStore::AddSproutViewingKey(vk);
446 }
447
448 bool CWallet::AddCScript(const CScript& redeemScript)
449 {
450     if (!CCryptoKeyStore::AddCScript(redeemScript))
451         return false;
452     if (!fFileBacked)
453         return true;
454     return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
455 }
456
457 bool CWallet::LoadCScript(const CScript& redeemScript)
458 {
459     /* A sanity check was added in pull #3843 to avoid adding redeemScripts
460      * that never can be redeemed. However, old wallets may still contain
461      * these. Do not add them to the wallet and warn. */
462     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
463     {
464         std::string strAddr = EncodeDestination(CScriptID(redeemScript));
465         LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
466             __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
467         return true;
468     }
469
470     return CCryptoKeyStore::AddCScript(redeemScript);
471 }
472
473 bool CWallet::AddWatchOnly(const CScript &dest)
474 {
475     if (!CCryptoKeyStore::AddWatchOnly(dest))
476         return false;
477     nTimeFirstKey = 1; // No birthday information for watch-only keys.
478     NotifyWatchonlyChanged(true);
479     if (!fFileBacked)
480         return true;
481     return CWalletDB(strWalletFile).WriteWatchOnly(dest);
482 }
483
484 bool CWallet::RemoveWatchOnly(const CScript &dest)
485 {
486     AssertLockHeld(cs_wallet);
487     if (!CCryptoKeyStore::RemoveWatchOnly(dest))
488         return false;
489     if (!HaveWatchOnly())
490         NotifyWatchonlyChanged(false);
491     if (fFileBacked)
492         if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
493             return false;
494
495     return true;
496 }
497
498 bool CWallet::LoadWatchOnly(const CScript &dest)
499 {
500     return CCryptoKeyStore::AddWatchOnly(dest);
501 }
502
503 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
504 {
505     CCrypter crypter;
506     CKeyingMaterial vMasterKey;
507
508     {
509         LOCK(cs_wallet);
510         BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
511         {
512             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
513                 return false;
514             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
515                 continue; // try another master key
516             if (CCryptoKeyStore::Unlock(vMasterKey))
517                 return true;
518         }
519     }
520     return false;
521 }
522
523 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
524 {
525     bool fWasLocked = IsLocked();
526
527     {
528         LOCK(cs_wallet);
529         Lock();
530
531         CCrypter crypter;
532         CKeyingMaterial vMasterKey;
533         BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
534         {
535             if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
536                 return false;
537             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
538                 return false;
539             if (CCryptoKeyStore::Unlock(vMasterKey))
540             {
541                 int64_t nStartTime = GetTimeMillis();
542                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
543                 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
544
545                 nStartTime = GetTimeMillis();
546                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
547                 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
548
549                 if (pMasterKey.second.nDeriveIterations < 25000)
550                     pMasterKey.second.nDeriveIterations = 25000;
551
552                 LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
553
554                 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
555                     return false;
556                 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
557                     return false;
558                 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
559                 if (fWasLocked)
560                     Lock();
561                 return true;
562             }
563         }
564     }
565
566     return false;
567 }
568
569 void CWallet::ChainTip(const CBlockIndex *pindex, 
570                        const CBlock *pblock,
571                        SproutMerkleTree sproutTree,
572                        SaplingMerkleTree saplingTree, 
573                        bool added)
574 {
575     if (added) {
576         IncrementNoteWitnesses(pindex, pblock, sproutTree, saplingTree);
577     } else {
578         DecrementNoteWitnesses(pindex);
579     }
580     UpdateSaplingNullifierNoteMapForBlock(pblock);
581 }
582
583 void CWallet::SetBestChain(const CBlockLocator& loc)
584 {
585     CWalletDB walletdb(strWalletFile);
586     SetBestChainINTERNAL(walletdb, loc);
587 }
588
589 std::set<std::pair<libzcash::PaymentAddress, uint256>> CWallet::GetNullifiersForAddresses(
590         const std::set<libzcash::PaymentAddress> & addresses)
591 {
592     std::set<std::pair<libzcash::PaymentAddress, uint256>> nullifierSet;
593     // Sapling ivk -> list of addrs map
594     // (There may be more than one diversified address for a given ivk.)
595     std::map<libzcash::SaplingIncomingViewingKey, std::vector<libzcash::SaplingPaymentAddress>> ivkMap;
596     for (const auto & addr : addresses) {
597         auto saplingAddr = boost::get<libzcash::SaplingPaymentAddress>(&addr);
598         if (saplingAddr != nullptr) {
599             libzcash::SaplingIncomingViewingKey ivk;
600             this->GetSaplingIncomingViewingKey(*saplingAddr, ivk);
601             ivkMap[ivk].push_back(*saplingAddr);
602         }
603     }
604     for (const auto & txPair : mapWallet) {
605         // Sprout
606         for (const auto & noteDataPair : txPair.second.mapSproutNoteData) {
607             auto & noteData = noteDataPair.second;
608             auto & nullifier = noteData.nullifier;
609             auto & address = noteData.address;
610             if (nullifier && addresses.count(address)) {
611                 nullifierSet.insert(std::make_pair(address, nullifier.get()));
612             }
613         }
614         // Sapling
615         for (const auto & noteDataPair : txPair.second.mapSaplingNoteData) {
616             auto & noteData = noteDataPair.second;
617             auto & nullifier = noteData.nullifier;
618             auto & ivk = noteData.ivk;
619             if (nullifier && ivkMap.count(ivk)) {
620                 for (const auto & addr : ivkMap[ivk]) {
621                     nullifierSet.insert(std::make_pair(addr, nullifier.get()));
622                 }
623             }
624         }
625     }
626     return nullifierSet;
627 }
628
629 bool CWallet::IsNoteSproutChange(
630         const std::set<std::pair<libzcash::PaymentAddress, uint256>> & nullifierSet,
631         const PaymentAddress & address,
632         const JSOutPoint & jsop)
633 {
634     // A Note is marked as "change" if the address that received it
635     // also spent Notes in the same transaction. This will catch,
636     // for instance:
637     // - Change created by spending fractions of Notes (because
638     //   z_sendmany sends change to the originating z-address).
639     // - "Chaining Notes" used to connect JoinSplits together.
640     // - Notes created by consolidation transactions (e.g. using
641     //   z_mergetoaddress).
642     // - Notes sent from one address to itself.
643     for (const JSDescription & jsd : mapWallet[jsop.hash].vjoinsplit) {
644         for (const uint256 & nullifier : jsd.nullifiers) {
645             if (nullifierSet.count(std::make_pair(address, nullifier))) {
646                 return true;
647             }
648         }
649     }
650     return false;
651 }
652
653 bool CWallet::IsNoteSaplingChange(const std::set<std::pair<libzcash::PaymentAddress, uint256>> & nullifierSet,
654         const libzcash::PaymentAddress & address,
655         const SaplingOutPoint & op)
656 {
657     // A Note is marked as "change" if the address that received it
658     // also spent Notes in the same transaction. This will catch,
659     // for instance:
660     // - Change created by spending fractions of Notes (because
661     //   z_sendmany sends change to the originating z-address).
662     // - Notes created by consolidation transactions (e.g. using
663     //   z_mergetoaddress).
664     // - Notes sent from one address to itself.
665     for (const SpendDescription &spend : mapWallet[op.hash].vShieldedSpend) {
666         if (nullifierSet.count(std::make_pair(address, spend.nullifier))) {
667             return true;
668         }
669     }
670     return false;
671 }
672
673 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
674 {
675     LOCK(cs_wallet); // nWalletVersion
676     if (nWalletVersion >= nVersion)
677         return true;
678
679     // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
680     if (fExplicit && nVersion > nWalletMaxVersion)
681             nVersion = FEATURE_LATEST;
682
683     nWalletVersion = nVersion;
684
685     if (nVersion > nWalletMaxVersion)
686         nWalletMaxVersion = nVersion;
687
688     if (fFileBacked)
689     {
690         CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
691         if (nWalletVersion > 40000)
692             pwalletdb->WriteMinVersion(nWalletVersion);
693         if (!pwalletdbIn)
694             delete pwalletdb;
695     }
696
697     return true;
698 }
699
700 bool CWallet::SetMaxVersion(int nVersion)
701 {
702     LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
703     // cannot downgrade below current version
704     if (nWalletVersion > nVersion)
705         return false;
706
707     nWalletMaxVersion = nVersion;
708
709     return true;
710 }
711
712 set<uint256> CWallet::GetConflicts(const uint256& txid) const
713 {
714     set<uint256> result;
715     AssertLockHeld(cs_wallet);
716
717     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
718     if (it == mapWallet.end())
719         return result;
720     const CWalletTx& wtx = it->second;
721
722     std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
723
724     BOOST_FOREACH(const CTxIn& txin, wtx.vin)
725     {
726         if (mapTxSpends.count(txin.prevout) <= 1)
727             continue;  // No conflict if zero or one spends
728         range = mapTxSpends.equal_range(txin.prevout);
729         for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
730             result.insert(it->second);
731     }
732
733     std::pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range_n;
734
735     for (const JSDescription& jsdesc : wtx.vjoinsplit) {
736         for (const uint256& nullifier : jsdesc.nullifiers) {
737             if (mapTxSproutNullifiers.count(nullifier) <= 1) {
738                 continue;  // No conflict if zero or one spends
739             }
740             range_n = mapTxSproutNullifiers.equal_range(nullifier);
741             for (TxNullifiers::const_iterator it = range_n.first; it != range_n.second; ++it) {
742                 result.insert(it->second);
743             }
744         }
745     }
746
747     std::pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range_o;
748
749     for (const SpendDescription &spend : wtx.vShieldedSpend) {
750         uint256 nullifier = spend.nullifier;
751         if (mapTxSaplingNullifiers.count(nullifier) <= 1) {
752             continue;  // No conflict if zero or one spends
753         }
754         range_o = mapTxSaplingNullifiers.equal_range(nullifier);
755         for (TxNullifiers::const_iterator it = range_o.first; it != range_o.second; ++it) {
756             result.insert(it->second);
757         }
758     }
759     return result;
760 }
761
762 void CWallet::Flush(bool shutdown)
763 {
764     bitdb.Flush(shutdown);
765 }
766
767 bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString)
768 {
769     if (!bitdb.Open(GetDataDir()))
770     {
771         // try moving the database env out of the way
772         boost::filesystem::path pathDatabase = GetDataDir() / "database";
773         boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
774         try {
775             boost::filesystem::rename(pathDatabase, pathDatabaseBak);
776             LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
777         } catch (const boost::filesystem::filesystem_error&) {
778             // failure is ok (well, not really, but it's not worse than what we started with)
779         }
780
781         // try again
782         if (!bitdb.Open(GetDataDir())) {
783             // if it still fails, it probably means we can't even create the database env
784             string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
785             errorString += msg;
786             return true;
787         }
788     }
789
790     if (GetBoolArg("-salvagewallet", false))
791     {
792         // Recover readable keypairs:
793         if (!CWalletDB::Recover(bitdb, walletFile, true))
794             return false;
795     }
796
797     if (boost::filesystem::exists(GetDataDir() / walletFile))
798     {
799         CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
800         if (r == CDBEnv::RECOVER_OK)
801         {
802             warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
803                                      " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
804                                      " your balance or transactions are incorrect you should"
805                                      " restore from a backup."), GetDataDir());
806         }
807         if (r == CDBEnv::RECOVER_FAIL)
808             errorString += _("wallet.dat corrupt, salvage failed");
809     }
810
811     return true;
812 }
813
814 template <class T>
815 void CWallet::SyncMetaData(pair<typename TxSpendMap<T>::iterator, typename TxSpendMap<T>::iterator> range)
816 {
817     // We want all the wallet transactions in range to have the same metadata as
818     // the oldest (smallest nOrderPos).
819     // So: find smallest nOrderPos:
820
821     int nMinOrderPos = std::numeric_limits<int>::max();
822     const CWalletTx* copyFrom = NULL;
823     for (typename TxSpendMap<T>::iterator it = range.first; it != range.second; ++it)
824     {
825         const uint256& hash = it->second;
826         int n = mapWallet[hash].nOrderPos;
827         if (n < nMinOrderPos)
828         {
829             nMinOrderPos = n;
830             copyFrom = &mapWallet[hash];
831         }
832     }
833     // Now copy data from copyFrom to rest:
834     for (typename TxSpendMap<T>::iterator it = range.first; it != range.second; ++it)
835     {
836         const uint256& hash = it->second;
837         CWalletTx* copyTo = &mapWallet[hash];
838         if (copyFrom == copyTo) continue;
839         copyTo->mapValue = copyFrom->mapValue;
840         // mapSproutNoteData and mapSaplingNoteData not copied on purpose
841         // (it is always set correctly for each CWalletTx)
842         copyTo->vOrderForm = copyFrom->vOrderForm;
843         // fTimeReceivedIsTxTime not copied on purpose
844         // nTimeReceived not copied on purpose
845         copyTo->nTimeSmart = copyFrom->nTimeSmart;
846         copyTo->fFromMe = copyFrom->fFromMe;
847         copyTo->strFromAccount = copyFrom->strFromAccount;
848         // nOrderPos not copied on purpose
849         // cached members not copied on purpose
850     }
851 }
852
853 /**
854  * Outpoint is spent if any non-conflicted transaction
855  * spends it:
856  */
857 bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
858 {
859     const COutPoint outpoint(hash, n);
860     pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
861     range = mapTxSpends.equal_range(outpoint);
862
863     for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
864     {
865         const uint256& wtxid = it->second;
866         std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
867         if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
868             return true; // Spent
869     }
870     return false;
871 }
872
873 /**
874  * Note is spent if any non-conflicted transaction
875  * spends it:
876  */
877 bool CWallet::IsSproutSpent(const uint256& nullifier) const {
878     pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
879     range = mapTxSproutNullifiers.equal_range(nullifier);
880
881     for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) {
882         const uint256& wtxid = it->second;
883         std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
884         if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) {
885             return true; // Spent
886         }
887     }
888     return false;
889 }
890
891 bool CWallet::IsSaplingSpent(const uint256& nullifier) const {
892     pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
893     range = mapTxSaplingNullifiers.equal_range(nullifier);
894
895     for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) {
896         const uint256& wtxid = it->second;
897         std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
898         if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) {
899             return true; // Spent
900         }
901     }
902     return false;
903 }
904
905 void CWallet::AddToTransparentSpends(const COutPoint& outpoint, const uint256& wtxid)
906 {
907     mapTxSpends.insert(make_pair(outpoint, wtxid));
908
909     pair<TxSpends::iterator, TxSpends::iterator> range;
910     range = mapTxSpends.equal_range(outpoint);
911     SyncMetaData<COutPoint>(range);
912 }
913
914 void CWallet::AddToSproutSpends(const uint256& nullifier, const uint256& wtxid)
915 {
916     mapTxSproutNullifiers.insert(make_pair(nullifier, wtxid));
917
918     pair<TxNullifiers::iterator, TxNullifiers::iterator> range;
919     range = mapTxSproutNullifiers.equal_range(nullifier);
920     SyncMetaData<uint256>(range);
921 }
922
923 void CWallet::AddToSaplingSpends(const uint256& nullifier, const uint256& wtxid)
924 {
925     mapTxSaplingNullifiers.insert(make_pair(nullifier, wtxid));
926
927     pair<TxNullifiers::iterator, TxNullifiers::iterator> range;
928     range = mapTxSaplingNullifiers.equal_range(nullifier);
929     SyncMetaData<uint256>(range);
930 }
931
932 void CWallet::AddToSpends(const uint256& wtxid)
933 {
934     assert(mapWallet.count(wtxid));
935     CWalletTx& thisTx = mapWallet[wtxid];
936     if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
937         return;
938
939     for (const CTxIn& txin : thisTx.vin) {
940         AddToTransparentSpends(txin.prevout, wtxid);
941     }
942     for (const JSDescription& jsdesc : thisTx.vjoinsplit) {
943         for (const uint256& nullifier : jsdesc.nullifiers) {
944             AddToSproutSpends(nullifier, wtxid);
945         }
946     }
947     for (const SpendDescription &spend : thisTx.vShieldedSpend) {
948         AddToSaplingSpends(spend.nullifier, wtxid);
949     }
950 }
951
952 void CWallet::ClearNoteWitnessCache()
953 {
954     LOCK(cs_wallet);
955     for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
956         for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) {
957             item.second.witnesses.clear();
958             item.second.witnessHeight = -1;
959         }
960         for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) {
961             item.second.witnesses.clear();
962             item.second.witnessHeight = -1;
963         }
964     }
965     nWitnessCacheSize = 0;
966     //fprintf(stderr,"Clear witness cache\n");
967 }
968
969 template<typename NoteDataMap>
970 void CopyPreviousWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
971 {
972     for (auto& item : noteDataMap) {
973         auto* nd = &(item.second);
974         // Only increment witnesses that are behind the current height
975         if (nd->witnessHeight < indexHeight) {
976             // Check the validity of the cache
977             // The only time a note witnessed above the current height
978             // would be invalid here is during a reindex when blocks
979             // have been decremented, and we are incrementing the blocks
980             // immediately after.
981             assert(nWitnessCacheSize >= nd->witnesses.size());
982             // Witnesses being incremented should always be either -1
983             // (never incremented or decremented) or one below indexHeight
984             assert((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight - 1));
985             // Copy the witness for the previous block if we have one
986             if (nd->witnesses.size() > 0) {
987                 nd->witnesses.push_front(nd->witnesses.front());
988             }
989             if (nd->witnesses.size() > WITNESS_CACHE_SIZE) {
990                 nd->witnesses.pop_back();
991             }
992         }
993     }
994 }
995
996 template<typename NoteDataMap>
997 void AppendNoteCommitment(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize, const uint256& note_commitment)
998 {
999     for (auto& item : noteDataMap) {
1000         auto* nd = &(item.second);
1001         if (nd->witnessHeight < indexHeight && nd->witnesses.size() > 0) {
1002             // Check the validity of the cache
1003             // See comment in CopyPreviousWitnesses about validity.
1004             assert(nWitnessCacheSize >= nd->witnesses.size());
1005             nd->witnesses.front().append(note_commitment);
1006         }
1007     }
1008 }
1009
1010 template<typename OutPoint, typename NoteData, typename Witness>
1011 void WitnessNoteIfMine(std::map<OutPoint, NoteData>& noteDataMap, int indexHeight, int64_t nWitnessCacheSize, const OutPoint& key, const Witness& witness)
1012 {
1013     if (noteDataMap.count(key) && noteDataMap[key].witnessHeight < indexHeight) {
1014         auto* nd = &(noteDataMap[key]);
1015         if (nd->witnesses.size() > 0) {
1016             // We think this can happen because we write out the
1017             // witness cache state after every block increment or
1018             // decrement, but the block index itself is written in
1019             // batches. So if the node crashes in between these two
1020             // operations, it is possible for IncrementNoteWitnesses
1021             // to be called again on previously-cached blocks. This
1022             // doesn't affect existing cached notes because of the
1023             // NoteData::witnessHeight checks. See #1378 for details.
1024             LogPrintf("Inconsistent witness cache state found for %s\n- Cache size: %d\n- Top (height %d): %s\n- New (height %d): %s\n",
1025                         key.ToString(), nd->witnesses.size(),
1026                         nd->witnessHeight,
1027                         nd->witnesses.front().root().GetHex(),
1028                         indexHeight,
1029                         witness.root().GetHex());
1030             nd->witnesses.clear();
1031         }
1032         nd->witnesses.push_front(witness);
1033         // Set height to one less than pindex so it gets incremented
1034         nd->witnessHeight = indexHeight - 1;
1035         // Check the validity of the cache
1036         assert(nWitnessCacheSize >= nd->witnesses.size());
1037     }
1038 }
1039
1040
1041 template<typename NoteDataMap>
1042 void UpdateWitnessHeights(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
1043 {
1044     for (auto& item : noteDataMap) {
1045         auto* nd = &(item.second);
1046         if (nd->witnessHeight < indexHeight) {
1047             nd->witnessHeight = indexHeight;
1048             // Check the validity of the cache
1049             // See comment in CopyPreviousWitnesses about validity.
1050             assert(nWitnessCacheSize >= nd->witnesses.size());
1051         }
1052     }
1053 }
1054
1055 void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
1056                                      const CBlock* pblockIn,
1057                                      SproutMerkleTree& sproutTree,
1058                                      SaplingMerkleTree& saplingTree)
1059 {
1060     LOCK(cs_wallet);
1061     for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1062        ::CopyPreviousWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize);
1063        ::CopyPreviousWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize);
1064     }
1065
1066     if (nWitnessCacheSize < WITNESS_CACHE_SIZE) {
1067         nWitnessCacheSize += 1;
1068     }
1069
1070     const CBlock* pblock {pblockIn};
1071     CBlock block;
1072     if (!pblock) {
1073         ReadBlockFromDisk(block, pindex, false);
1074         pblock = &block;
1075     }
1076
1077     for (const CTransaction& tx : pblock->vtx) {
1078         auto hash = tx.GetHash();
1079         bool txIsOurs = mapWallet.count(hash);
1080         // Sprout
1081         for (size_t i = 0; i < tx.vjoinsplit.size(); i++) {
1082             const JSDescription& jsdesc = tx.vjoinsplit[i];
1083             for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) {
1084                 const uint256& note_commitment = jsdesc.commitments[j];
1085                 sproutTree.append(note_commitment);
1086
1087                 // Increment existing witnesses
1088                 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1089                     ::AppendNoteCommitment(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize, note_commitment);
1090                 }
1091
1092                 // If this is our note, witness it
1093                 if (txIsOurs) {
1094                     JSOutPoint jsoutpt {hash, i, j};
1095                     ::WitnessNoteIfMine(mapWallet[hash].mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize, jsoutpt, sproutTree.witness());
1096                 }
1097             }
1098         }
1099         // Sapling
1100         for (uint32_t i = 0; i < tx.vShieldedOutput.size(); i++) {
1101             const uint256& note_commitment = tx.vShieldedOutput[i].cm;
1102             saplingTree.append(note_commitment);
1103
1104             // Increment existing witnesses
1105             for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1106                 ::AppendNoteCommitment(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize, note_commitment);
1107             }
1108
1109             // If this is our note, witness it
1110             if (txIsOurs) {
1111                 SaplingOutPoint outPoint {hash, i};
1112                 ::WitnessNoteIfMine(mapWallet[hash].mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize, outPoint, saplingTree.witness());
1113             }
1114         }
1115     }
1116
1117     // Update witness heights
1118     for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1119         ::UpdateWitnessHeights(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize);
1120         ::UpdateWitnessHeights(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize);
1121     }
1122
1123     // For performance reasons, we write out the witness cache in
1124     // CWallet::SetBestChain() (which also ensures that overall consistency
1125     // of the wallet.dat is maintained).
1126 }
1127
1128 template<typename NoteDataMap>
1129 bool DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
1130 {
1131     extern int32_t KOMODO_REWIND;
1132
1133     for (auto& item : noteDataMap) {
1134         auto* nd = &(item.second);
1135         // Only decrement witnesses that are not above the current height
1136         if (nd->witnessHeight <= indexHeight) {
1137             // Check the validity of the cache
1138             // See comment below (this would be invalid if there were a
1139             // prior decrement).
1140             assert(nWitnessCacheSize >= nd->witnesses.size());
1141             // Witnesses being decremented should always be either -1
1142             // (never incremented or decremented) or equal to the height
1143             // of the block being removed (indexHeight)
1144             if (!((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight)))
1145             {
1146                 printf("at height %d\n", indexHeight);
1147                 return false;
1148             }
1149             if (nd->witnesses.size() > 0) {
1150                 nd->witnesses.pop_front();
1151             }
1152             // indexHeight is the height of the block being removed, so 
1153             // the new witness cache height is one below it.
1154             nd->witnessHeight = indexHeight - 1;
1155         }
1156         // Check the validity of the cache
1157         // Technically if there are notes witnessed above the current
1158         // height, their cache will now be invalid (relative to the new
1159         // value of nWitnessCacheSize). However, this would only occur
1160         // during a reindex, and by the time the reindex reaches the tip
1161         // of the chain again, the existing witness caches will be valid
1162         // again.
1163         // We don't set nWitnessCacheSize to zero at the start of the
1164         // reindex because the on-disk blocks had already resulted in a
1165         // chain that didn't trigger the assertion below.
1166         if (nd->witnessHeight < indexHeight) {
1167             // Subtract 1 to compare to what nWitnessCacheSize will be after
1168             // decrementing.
1169             assert((nWitnessCacheSize - 1) >= nd->witnesses.size());
1170         }
1171     }
1172     assert(KOMODO_REWIND != 0 || nWitnessCacheSize > 0);
1173     return true;
1174 }
1175
1176 void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex)
1177 {
1178     LOCK(cs_wallet);
1179     for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1180         if (!::DecrementNoteWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize))
1181             needsRescan = true;
1182         if (!::DecrementNoteWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize))
1183             needsRescan = true;
1184     }
1185     nWitnessCacheSize -= 1;
1186     // TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302)
1187     assert(nWitnessCacheSize > 0);
1188
1189     // For performance reasons, we write out the witness cache in
1190     // CWallet::SetBestChain() (which also ensures that overall consistency
1191     // of the wallet.dat is maintained).
1192 }
1193
1194 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
1195 {
1196     if (IsCrypted())
1197         return false;
1198
1199     CKeyingMaterial vMasterKey;
1200
1201     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
1202     GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
1203
1204     CMasterKey kMasterKey;
1205
1206     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
1207     GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
1208
1209     CCrypter crypter;
1210     int64_t nStartTime = GetTimeMillis();
1211     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
1212     kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
1213
1214     nStartTime = GetTimeMillis();
1215     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
1216     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
1217
1218     if (kMasterKey.nDeriveIterations < 25000)
1219         kMasterKey.nDeriveIterations = 25000;
1220
1221     LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
1222
1223     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
1224         return false;
1225     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
1226         return false;
1227
1228     {
1229         LOCK(cs_wallet);
1230         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
1231         if (fFileBacked)
1232         {
1233             assert(!pwalletdbEncryption);
1234             pwalletdbEncryption = new CWalletDB(strWalletFile);
1235             if (!pwalletdbEncryption->TxnBegin()) {
1236                 delete pwalletdbEncryption;
1237                 pwalletdbEncryption = NULL;
1238                 return false;
1239             }
1240             pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
1241         }
1242
1243         if (!EncryptKeys(vMasterKey))
1244         {
1245             if (fFileBacked) {
1246                 pwalletdbEncryption->TxnAbort();
1247                 delete pwalletdbEncryption;
1248             }
1249             // We now probably have half of our keys encrypted in memory, and half not...
1250             // die and let the user reload the unencrypted wallet.
1251             assert(false);
1252         }
1253
1254         // Encryption was introduced in version 0.4.0
1255         SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
1256
1257         if (fFileBacked)
1258         {
1259             if (!pwalletdbEncryption->TxnCommit()) {
1260                 delete pwalletdbEncryption;
1261                 // We now have keys encrypted in memory, but not on disk...
1262                 // die to avoid confusion and let the user reload the unencrypted wallet.
1263                 assert(false);
1264             }
1265
1266             delete pwalletdbEncryption;
1267             pwalletdbEncryption = NULL;
1268         }
1269
1270         Lock();
1271         Unlock(strWalletPassphrase);
1272         NewKeyPool();
1273         Lock();
1274
1275         // Need to completely rewrite the wallet file; if we don't, bdb might keep
1276         // bits of the unencrypted private key in slack space in the database file.
1277         CDB::Rewrite(strWalletFile);
1278
1279     }
1280     NotifyStatusChanged(this);
1281
1282     return true;
1283 }
1284
1285 int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
1286 {
1287     AssertLockHeld(cs_wallet); // nOrderPosNext
1288     int64_t nRet = nOrderPosNext++;
1289     if (pwalletdb) {
1290         pwalletdb->WriteOrderPosNext(nOrderPosNext);
1291     } else {
1292         CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
1293     }
1294     return nRet;
1295 }
1296
1297 CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
1298 {
1299     AssertLockHeld(cs_wallet); // mapWallet
1300     CWalletDB walletdb(strWalletFile);
1301
1302     // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
1303     TxItems txOrdered;
1304
1305     // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
1306     // would make this much faster for applications that do this a lot.
1307     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1308     {
1309         CWalletTx* wtx = &((*it).second);
1310         txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
1311     }
1312     acentries.clear();
1313     walletdb.ListAccountCreditDebit(strAccount, acentries);
1314     BOOST_FOREACH(CAccountingEntry& entry, acentries)
1315     {
1316         txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
1317     }
1318
1319     return txOrdered;
1320 }
1321
1322 // looks through all wallet UTXOs and checks to see if any qualify to stake the block at the current height. it always returns the qualified
1323 // UTXO with the smallest coin age if there is more than one, as larger coin age will win more often and is worth saving
1324 // each attempt consists of taking a VerusHash of the following values:
1325 //  ASSETCHAINS_MAGIC, nHeight, txid, voutNum
1326 bool CWallet::VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult, CTransaction &stakeSource, int32_t &voutNum, int32_t nHeight, uint32_t &bnTarget) const
1327 {
1328     arith_uint256 target;
1329     arith_uint256 curHash;
1330     vector<COutput> vecOutputs;
1331     COutput *pwinner = NULL;
1332     CBlockIndex *pastBlockIndex;
1333     txnouttype whichType;
1334     std:vector<std::vector<unsigned char>> vSolutions;
1335
1336     pBlock->nNonce.SetPOSTarget(bnTarget, pBlock->nVersion);
1337     target.SetCompact(bnTarget);
1338
1339     auto consensusParams = Params().GetConsensus();
1340     CValidationState state;
1341
1342     pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, !consensusParams.fCoinbaseMustBeProtected);
1343
1344     if (pastBlockIndex = komodo_chainactive(nHeight - 100))
1345     {
1346         uint256 pastHash = pastBlockIndex->GetVerusEntropyHash();
1347         CPOSNonce curNonce;
1348         uint32_t srcIndex;
1349
1350         BOOST_FOREACH(COutput &txout, vecOutputs)
1351         {
1352             if (txout.fSpendable && (UintToArith256(txout.tx->GetVerusPOSHash(&(pBlock->nNonce), txout.i, nHeight, pastHash)) <= target) && (txout.nDepth >= VERUS_MIN_STAKEAGE))
1353             {
1354                 CDataStream s(SER_NETWORK, PROTOCOL_VERSION);
1355                 int32_t txSize = GetSerializeSize(s, *(CTransaction *)txout.tx);
1356
1357                 //printf("Serialized size of transaction %s is %lu\n", txout.tx->GetHash().GetHex().c_str(), txSize);
1358                 if (txSize > MAX_TX_SIZE_FOR_STAKING)
1359                 {
1360                     LogPrintf("Transaction %s is too large to stake. Serialized size == %lu\n", txout.tx->GetHash().GetHex().c_str(), txSize);
1361                 }
1362
1363                 CCoinsViewCache view(pcoinsTip);
1364                 CMutableTransaction checkStakeTx = CreateNewContextualCMutableTransaction(consensusParams, nHeight);
1365                 uint256 txHash = txout.tx->GetHash();
1366                 checkStakeTx.vin.push_back(CTxIn(COutPoint(txHash, txout.i)));
1367
1368                 if (txSize <= MAX_TX_SIZE_FOR_STAKING &&
1369                     (!pwinner || UintToArith256(curNonce) > UintToArith256(pBlock->nNonce)) &&
1370                     (Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH)) &&
1371                     !cheatList.IsUTXOInList(COutPoint(txHash, txout.i), nHeight <= 100 ? 1 : nHeight-100) &&
1372                     view.AccessCoins(txHash) &&
1373                     Consensus::CheckTxInputs(checkStakeTx, state, view, nHeight, consensusParams))
1374                 {
1375                     //printf("Found PoS block\nnNonce:    %s\n", pBlock->nNonce.GetHex().c_str());
1376                     pwinner = &txout;
1377                     curNonce = pBlock->nNonce;
1378                     srcIndex = (nHeight - txout.nDepth) - 1;
1379                 }
1380             }
1381         }
1382         if (pwinner)
1383         {
1384             stakeSource = *(pwinner->tx);
1385             voutNum = pwinner->i;
1386             pBlock->nNonce = curNonce;
1387
1388             if (CConstVerusSolutionVector::activationHeight.ActiveVersion(nHeight) == CActivationHeight::SOLUTION_VERUSV3)
1389             {
1390                 CDataStream txStream = CDataStream(SER_NETWORK, PROTOCOL_VERSION);
1391
1392                 // store:
1393                 // 1. PBaaS header for this block
1394                 // 2. source transaction
1395                 // 3. block index of base MMR being used
1396                 // 4. source tx block index for proof
1397                 // 5. full merkle proof of source tx up to prior MMR root
1398                 // 6. block hash of block of entropyhash
1399                 // 7. proof of block hash (not full header) in the MMR for the block height of the entropy hash block
1400                 // all that data includes enough information to verify
1401                 // prior MMR, blockhash, transaction, entropy hash, and block indexes match
1402                 // also checks root match & block power
1403                 auto view = chainActive.GetMMV();
1404                 pBlock->AddUpdatePBaaSHeader(view.GetRoot());
1405
1406                 txStream << *(CTransaction *)pwinner->tx;
1407
1408                 // start with the tx proof
1409                 CMerkleBranch branch(pwinner->tx->nIndex, pwinner->tx->vMerkleBranch);
1410
1411                 // add the Merkle proof bridge to the MMR
1412                 chainActive[srcIndex]->AddMerkleProofBridge(branch);
1413
1414                 // use the block that we got entropy hash from as the validating block
1415                 // which immediately provides all but unspent proof for PoS block
1416                 view.resize(pastBlockIndex->GetHeight());
1417
1418                 view.GetProof(branch, srcIndex);
1419
1420                 // store block height of MMR root, block index of entry, and full blockchain proof of transaction with that root
1421                 txStream << pastBlockIndex->GetHeight();
1422                 txStream << srcIndex;
1423                 txStream << branch;
1424
1425                 // now we get a fresh branch for the block proof
1426                 branch = CMerkleBranch();
1427
1428                 // prove the block 100 blocks ago with its coincident MMR
1429                 // it must hash to the same value with a different path, providing both a consistency check and
1430                 // an asserted MMR root for the n - 100 block if matched
1431                 pastBlockIndex->AddBlockProofBridge(branch);
1432                 view.GetProof(branch, pastBlockIndex->GetHeight());
1433
1434                 // block proof of the same block using the MMR of that block height, so we don't need to add additional data
1435                 // beyond the block hash.
1436                 txStream << pastBlockIndex->GetBlockHash();
1437                 txStream << branch;
1438
1439                 std::vector<unsigned char> stx(txStream.begin(), txStream.end());
1440
1441                 // printf("\nFound Stake transaction... all proof serialized size == %lu\n", stx.size());
1442
1443                 CVerusSolutionVector(pBlock->nSolution).ResizeExtraData(stx.size());
1444
1445                 pBlock->SetExtraData(stx.data(), stx.size());
1446             }
1447             return true;
1448         }
1449     }
1450     return false;
1451 }
1452
1453 int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &bnTarget, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey pk) const
1454 {
1455     CTransaction stakeSource;
1456     int32_t voutNum, siglen = 0;
1457     int64_t nValue;
1458     txnouttype whichType;
1459     std::vector<std::vector<unsigned char>> vSolutions;
1460
1461     CBlockIndex *tipindex = chainActive.LastTip();
1462     uint32_t stakeHeight = tipindex->GetHeight() + 1;
1463     bool extendedStake = stakeHeight >= Params().GetConsensus().vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight;
1464
1465     if (!extendedStake)
1466         pk = CPubKey();
1467
1468     bnTarget = lwmaGetNextPOSRequired(tipindex, Params().GetConsensus());
1469
1470     if (!VerusSelectStakeOutput(pBlock, hashResult, stakeSource, voutNum, stakeHeight, bnTarget) ||
1471         !Solver(stakeSource.vout[voutNum].scriptPubKey, whichType, vSolutions))
1472     {
1473         LogPrintf("Searched for eligible staking transactions, no winners found\n");
1474         return 0;
1475     }
1476
1477     bool signSuccess; 
1478     SignatureData sigdata; 
1479     uint64_t txfee;
1480     auto consensusBranchId = CurrentEpochBranchId(stakeHeight, Params().GetConsensus());
1481
1482     const CKeyStore& keystore = *pwalletMain;
1483     txNew.vin.resize(1);
1484     txNew.vout.resize(1);
1485     txfee = extendedStake ? DEFAULT_STAKE_TXFEE : 0;
1486     txNew.vin[0].prevout.hash = stakeSource.GetHash();
1487     txNew.vin[0].prevout.n = voutNum;
1488
1489     if (whichType == TX_PUBKEY)
1490     {
1491         txNew.vout[0].scriptPubKey << ToByteVector(vSolutions[0]) << OP_CHECKSIG;
1492         if (!pk.IsValid())
1493             pk = CPubKey(vSolutions[0]);
1494     }
1495     else if (whichType == TX_PUBKEYHASH)
1496     {
1497         txNew.vout[0].scriptPubKey << OP_DUP << OP_HASH160 << ToByteVector(vSolutions[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
1498         if (extendedStake && !pk.IsValid())
1499         {
1500             // we need a pubkey, so try to get one from the key ID, if not there, fail
1501             if (!keystore.GetPubKey(CKeyID(uint160(vSolutions[0])), pk))
1502                 return 0;
1503         }
1504     }
1505     else
1506         return 0;
1507
1508     // if we are staking with the extended format, add the opreturn data required
1509     if (extendedStake)
1510     {
1511         // set expiry to time out after 100 blocks, so we can remove the transaction if it orphans
1512         txNew.nExpiryHeight = stakeHeight + 100;
1513
1514         uint256 srcBlock = uint256();
1515         CBlockIndex *pSrcIndex;
1516
1517         txNew.vout.push_back(CTxOut());
1518         CTxOut &txOut1 = txNew.vout[1];
1519         txOut1.nValue = 0;
1520         if (!GetTransaction(stakeSource.GetHash(), stakeSource, srcBlock))
1521             return 0;
1522         
1523         BlockMap::const_iterator it = mapBlockIndex.find(srcBlock);
1524         if (it == mapBlockIndex.end() || (pSrcIndex = it->second) == 0)
1525             return 0;
1526
1527         // !! DISABLE THIS FOR RELEASE: THIS MAKES A CHEAT TRANSACTION FOR EVERY STAKE FOR TESTING
1528         //CMutableTransaction cheat;
1529         //cheat = CMutableTransaction(txNew);
1530         //printf("TESTING ONLY: THIS SHOULD NOT BE ENABLED FOR RELEASE - MAKING CHEAT TRANSACTION FOR TESTING\n");
1531         //cheat.vout[1].scriptPubKey << OP_RETURN 
1532         //    << CStakeParams(pSrcIndex->GetHeight(), tipindex->GetHeight() + 1, pSrcIndex->GetBlockHash(), pk).AsVector();
1533         // !! DOWN TO HERE
1534
1535         txOut1.scriptPubKey << OP_RETURN 
1536             << CStakeParams(pSrcIndex->GetHeight(), tipindex->GetHeight() + 1, tipindex->GetBlockHash(), pk).AsVector();
1537
1538         // !! DISABLE THIS FOR RELEASE: REMOVE THIS TOO
1539         //nValue = cheat.vout[0].nValue = stakeSource.vout[voutNum].nValue - txfee;
1540         //cheat.nLockTime = 0;
1541         //CTransaction cheatConst(cheat);
1542         //SignatureData cheatSig;
1543         //if (!ProduceSignature(TransactionSignatureCreator(&keystore, &cheatConst, 0, nValue, SIGHASH_ALL), stakeSource.vout[voutNum].scriptPubKey, cheatSig, consensusBranchId))
1544         //    fprintf(stderr,"failed to create cheat test signature\n");
1545         //else
1546         //{
1547         //    uint8_t *ptr;
1548         //    UpdateTransaction(cheat,0,cheatSig);
1549         //    cheatList.Add(CTxHolder(CTransaction(cheat), tipindex->GetHeight() + 1));
1550         //}
1551         // !! DOWN TO HERE
1552     }
1553
1554     nValue = txNew.vout[0].nValue = stakeSource.vout[voutNum].nValue - txfee;
1555
1556     txNew.nLockTime = 0;
1557     CTransaction txNewConst(txNew);
1558     signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, nValue, SIGHASH_ALL), stakeSource.vout[voutNum].scriptPubKey, sigdata, consensusBranchId);
1559     if (!signSuccess)
1560         fprintf(stderr,"failed to create signature\n");
1561     else
1562     {
1563         uint8_t *ptr;
1564         UpdateTransaction(txNew,0,sigdata);
1565         ptr = (uint8_t *)&sigdata.scriptSig[0];
1566         siglen = sigdata.scriptSig.size();
1567         for (int i=0; i<siglen; i++)
1568             utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]);
1569     }
1570     return(siglen);
1571 }
1572
1573 void CWallet::MarkDirty()
1574 {
1575     {
1576         LOCK(cs_wallet);
1577         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1578             item.second.MarkDirty();
1579     }
1580 }
1581
1582 /**
1583  * Ensure that every note in the wallet (for which we possess a spending key)
1584  * has a cached nullifier.
1585  */
1586 bool CWallet::UpdateNullifierNoteMap()
1587 {
1588     {
1589         LOCK(cs_wallet);
1590
1591         if (IsLocked())
1592             return false;
1593
1594         ZCNoteDecryption dec;
1595         for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1596             for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) {
1597                 if (!item.second.nullifier) {
1598                     if (GetNoteDecryptor(item.second.address, dec)) {
1599                         auto i = item.first.js;
1600                         auto hSig = wtxItem.second.vjoinsplit[i].h_sig(
1601                             *pzcashParams, wtxItem.second.joinSplitPubKey);
1602                         item.second.nullifier = GetSproutNoteNullifier(
1603                             wtxItem.second.vjoinsplit[i],
1604                             item.second.address,
1605                             dec,
1606                             hSig,
1607                             item.first.n);
1608                     }
1609                 }
1610             }
1611
1612             // TODO: Sapling.  This method is only called from RPC walletpassphrase, which is currently unsupported
1613             // as RPC encryptwallet is hidden behind two flags: -developerencryptwallet -experimentalfeatures
1614
1615             UpdateNullifierNoteMapWithTx(wtxItem.second);
1616         }
1617     }
1618     return true;
1619 }
1620
1621 /**
1622  * Update mapSproutNullifiersToNotes and mapSaplingNullifiersToNotes
1623  * with the cached nullifiers in this tx.
1624  */
1625 void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx)
1626 {
1627     {
1628         LOCK(cs_wallet);
1629         for (const mapSproutNoteData_t::value_type& item : wtx.mapSproutNoteData) {
1630             if (item.second.nullifier) {
1631                 mapSproutNullifiersToNotes[*item.second.nullifier] = item.first;
1632             }
1633         }
1634
1635         for (const mapSaplingNoteData_t::value_type& item : wtx.mapSaplingNoteData) {
1636             if (item.second.nullifier) {
1637                 mapSaplingNullifiersToNotes[*item.second.nullifier] = item.first;
1638             }
1639         }
1640     }
1641 }
1642
1643 /**
1644  * Update mapSaplingNullifiersToNotes, computing the nullifier from a cached witness if necessary.
1645  */
1646 void CWallet::UpdateSaplingNullifierNoteMapWithTx(CWalletTx& wtx) {
1647     LOCK(cs_wallet);
1648
1649     for (mapSaplingNoteData_t::value_type &item : wtx.mapSaplingNoteData) {
1650         SaplingOutPoint op = item.first;
1651         SaplingNoteData nd = item.second;
1652
1653         if (nd.witnesses.empty()) {
1654             // If there are no witnesses, erase the nullifier and associated mapping.
1655             if (item.second.nullifier) {
1656                 mapSaplingNullifiersToNotes.erase(item.second.nullifier.get());
1657             }
1658             item.second.nullifier = boost::none;
1659         }
1660         else {
1661             uint64_t position = nd.witnesses.front().position();
1662             SaplingFullViewingKey fvk = mapSaplingFullViewingKeys.at(nd.ivk);
1663             OutputDescription output = wtx.vShieldedOutput[op.n];
1664             auto optPlaintext = SaplingNotePlaintext::decrypt(output.encCiphertext, nd.ivk, output.ephemeralKey, output.cm);
1665             if (!optPlaintext) {
1666                 // An item in mapSaplingNoteData must have already been successfully decrypted,
1667                 // otherwise the item would not exist in the first place.
1668                 assert(false);
1669             }
1670             auto optNote = optPlaintext.get().note(nd.ivk);
1671             if (!optNote) {
1672                 assert(false);
1673             }
1674             auto optNullifier = optNote.get().nullifier(fvk, position);
1675             if (!optNullifier) {
1676                 // This should not happen.  If it does, maybe the position has been corrupted or miscalculated?
1677                 assert(false);
1678             }
1679             uint256 nullifier = optNullifier.get();
1680             mapSaplingNullifiersToNotes[nullifier] = op;
1681             item.second.nullifier = nullifier;
1682         }
1683     }
1684 }
1685
1686 /**
1687  * Iterate over transactions in a block and update the cached Sapling nullifiers
1688  * for transactions which belong to the wallet.
1689  */
1690 void CWallet::UpdateSaplingNullifierNoteMapForBlock(const CBlock *pblock) {
1691     LOCK(cs_wallet);
1692
1693     for (const CTransaction& tx : pblock->vtx) {
1694         auto hash = tx.GetHash();
1695         bool txIsOurs = mapWallet.count(hash);
1696         if (txIsOurs) {
1697             UpdateSaplingNullifierNoteMapWithTx(mapWallet[hash]);
1698         }
1699     }
1700 }
1701
1702 bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
1703 {
1704     uint256 hash = wtxIn.GetHash();
1705
1706     if (fFromLoadWallet)
1707     {
1708         mapWallet[hash] = wtxIn;
1709         mapWallet[hash].BindWallet(this);
1710         UpdateNullifierNoteMapWithTx(mapWallet[hash]);
1711         AddToSpends(hash);
1712     }
1713     else
1714     {
1715         LOCK(cs_wallet);
1716         // Inserts only if not already there, returns tx inserted or tx found
1717         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
1718         CWalletTx& wtx = (*ret.first).second;
1719         wtx.BindWallet(this);
1720         UpdateNullifierNoteMapWithTx(wtx);
1721         bool fInsertedNew = ret.second;
1722         if (fInsertedNew)
1723         {
1724             wtx.nTimeReceived = GetAdjustedTime();
1725             wtx.nOrderPos = IncOrderPosNext(pwalletdb);
1726
1727             wtx.nTimeSmart = wtx.nTimeReceived;
1728             if (!wtxIn.hashBlock.IsNull())
1729             {
1730                 if (mapBlockIndex.count(wtxIn.hashBlock))
1731                 {
1732                     int64_t latestNow = wtx.nTimeReceived;
1733                     int64_t latestEntry = 0;
1734                     {
1735                         // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
1736                         int64_t latestTolerated = latestNow + 300;
1737                         std::list<CAccountingEntry> acentries;
1738                         TxItems txOrdered = OrderedTxItems(acentries);
1739                         for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1740                         {
1741                             CWalletTx *const pwtx = (*it).second.first;
1742                             if (pwtx == &wtx)
1743                                 continue;
1744                             CAccountingEntry *const pacentry = (*it).second.second;
1745                             int64_t nSmartTime;
1746                             if (pwtx)
1747                             {
1748                                 nSmartTime = pwtx->nTimeSmart;
1749                                 if (!nSmartTime)
1750                                     nSmartTime = pwtx->nTimeReceived;
1751                             }
1752                             else
1753                                 nSmartTime = pacentry->nTime;
1754                             if (nSmartTime <= latestTolerated)
1755                             {
1756                                 latestEntry = nSmartTime;
1757                                 if (nSmartTime > latestNow)
1758                                     latestNow = nSmartTime;
1759                                 break;
1760                             }
1761                         }
1762                     }
1763
1764                     int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
1765                     wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
1766                 }
1767                 else
1768                     LogPrintf("AddToWallet(): found %s in block %s not in index\n",
1769                              wtxIn.GetHash().ToString(),
1770                              wtxIn.hashBlock.ToString());
1771             }
1772             AddToSpends(hash);
1773         }
1774
1775         bool fUpdated = false;
1776         if (!fInsertedNew)
1777         {
1778             // Merge
1779             if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
1780             {
1781                 wtx.hashBlock = wtxIn.hashBlock;
1782                 fUpdated = true;
1783             }
1784             if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
1785             {
1786                 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
1787                 wtx.nIndex = wtxIn.nIndex;
1788                 fUpdated = true;
1789             }
1790             if (UpdatedNoteData(wtxIn, wtx)) {
1791                 fUpdated = true;
1792             }
1793             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
1794             {
1795                 wtx.fFromMe = wtxIn.fFromMe;
1796                 fUpdated = true;
1797             }
1798         }
1799
1800         //// debug print
1801         LogPrintf("AddToWallet %s  %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
1802
1803         // Write to disk
1804         if (fInsertedNew || fUpdated)
1805             if (!wtx.WriteToDisk(pwalletdb))
1806                 return false;
1807
1808         // Break debit/credit balance caches:
1809         wtx.MarkDirty();
1810
1811         // Notify UI of new or updated transaction
1812         NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
1813
1814         // notify an external script when a wallet transaction comes in or is updated
1815         std::string strCmd = GetArg("-walletnotify", "");
1816
1817         if ( !strCmd.empty())
1818         {
1819             boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
1820             boost::thread t(runCommand, strCmd); // thread runs free
1821         }
1822
1823     }
1824     return true;
1825 }
1826
1827 bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx)
1828 {
1829     bool unchangedSproutFlag = (wtxIn.mapSproutNoteData.empty() || wtxIn.mapSproutNoteData == wtx.mapSproutNoteData);
1830     if (!unchangedSproutFlag) {
1831         auto tmp = wtxIn.mapSproutNoteData;
1832         // Ensure we keep any cached witnesses we may already have
1833         for (const std::pair <JSOutPoint, SproutNoteData> nd : wtx.mapSproutNoteData) {
1834             if (tmp.count(nd.first) && nd.second.witnesses.size() > 0) {
1835                 tmp.at(nd.first).witnesses.assign(
1836                         nd.second.witnesses.cbegin(), nd.second.witnesses.cend());
1837             }
1838             tmp.at(nd.first).witnessHeight = nd.second.witnessHeight;
1839         }
1840         // Now copy over the updated note data
1841         wtx.mapSproutNoteData = tmp;
1842     }
1843
1844     bool unchangedSaplingFlag = (wtxIn.mapSaplingNoteData.empty() || wtxIn.mapSaplingNoteData == wtx.mapSaplingNoteData);
1845     if (!unchangedSaplingFlag) {
1846         auto tmp = wtxIn.mapSaplingNoteData;
1847         // Ensure we keep any cached witnesses we may already have
1848
1849         for (const std::pair <SaplingOutPoint, SaplingNoteData> nd : wtx.mapSaplingNoteData) {
1850             if (tmp.count(nd.first) && nd.second.witnesses.size() > 0) {
1851                 tmp.at(nd.first).witnesses.assign(
1852                         nd.second.witnesses.cbegin(), nd.second.witnesses.cend());
1853             }
1854             tmp.at(nd.first).witnessHeight = nd.second.witnessHeight;
1855         }
1856
1857         // Now copy over the updated note data
1858         wtx.mapSaplingNoteData = tmp;
1859     }
1860
1861     return !unchangedSproutFlag || !unchangedSaplingFlag;
1862 }
1863
1864 /**
1865  * Add a transaction to the wallet, or update it.
1866  * pblock is optional, but should be provided if the transaction is known to be in a block.
1867  * If fUpdate is true, existing transactions will be updated.
1868  */
1869 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
1870 {
1871     {
1872         AssertLockHeld(cs_wallet);
1873         bool fExisted = mapWallet.count(tx.GetHash()) != 0;
1874         if (fExisted && !fUpdate) return false;
1875         auto sproutNoteData = FindMySproutNotes(tx);
1876         auto saplingNoteDataAndAddressesToAdd = FindMySaplingNotes(tx);
1877         auto saplingNoteData = saplingNoteDataAndAddressesToAdd.first;
1878         auto addressesToAdd = saplingNoteDataAndAddressesToAdd.second;
1879         for (const auto &addressToAdd : addressesToAdd) {
1880             if (!AddSaplingIncomingViewingKey(addressToAdd.second, addressToAdd.first)) {
1881                 return false;
1882             }
1883         }
1884         if (fExisted || IsMine(tx) || IsFromMe(tx) || sproutNoteData.size() > 0 || saplingNoteData.size() > 0)
1885         {
1886             CWalletTx wtx(this,tx);
1887
1888             if (sproutNoteData.size() > 0) {
1889                 wtx.SetSproutNoteData(sproutNoteData);
1890             }
1891
1892             if (saplingNoteData.size() > 0) {
1893                 wtx.SetSaplingNoteData(saplingNoteData);
1894             }
1895
1896             // Get merkle branch if transaction was found in a block
1897             if (pblock)
1898                 wtx.SetMerkleBranch(*pblock);
1899
1900             // Do not flush the wallet here for performance reasons
1901             // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
1902             CWalletDB walletdb(strWalletFile, "r+", false);
1903
1904             return AddToWallet(wtx, false, &walletdb);
1905         }
1906     }
1907     return false;
1908 }
1909
1910 void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
1911 {
1912     LOCK2(cs_main, cs_wallet);
1913     if (!AddToWalletIfInvolvingMe(tx, pblock, true))
1914         return; // Not one of ours
1915
1916     MarkAffectedTransactionsDirty(tx);
1917 }
1918
1919 void CWallet::MarkAffectedTransactionsDirty(const CTransaction& tx)
1920 {
1921     // If a transaction changes 'conflicted' state, that changes the balance
1922     // available of the outputs it spends. So force those to be
1923     // recomputed, also:
1924     BOOST_FOREACH(const CTxIn& txin, tx.vin)
1925     {
1926         if (mapWallet.count(txin.prevout.hash))
1927             mapWallet[txin.prevout.hash].MarkDirty();
1928     }
1929     for (const JSDescription& jsdesc : tx.vjoinsplit) {
1930         for (const uint256& nullifier : jsdesc.nullifiers) {
1931             if (mapSproutNullifiersToNotes.count(nullifier) &&
1932                 mapWallet.count(mapSproutNullifiersToNotes[nullifier].hash)) {
1933                 mapWallet[mapSproutNullifiersToNotes[nullifier].hash].MarkDirty();
1934             }
1935         }
1936     }
1937
1938     for (const SpendDescription &spend : tx.vShieldedSpend) {
1939         uint256 nullifier = spend.nullifier;
1940         if (mapSaplingNullifiersToNotes.count(nullifier) &&
1941             mapWallet.count(mapSaplingNullifiersToNotes[nullifier].hash)) {
1942             mapWallet[mapSaplingNullifiersToNotes[nullifier].hash].MarkDirty();
1943         }
1944     }
1945 }
1946
1947 void CWallet::EraseFromWallet(const uint256 &hash)
1948 {
1949     if (!fFileBacked)
1950         return;
1951     {
1952         LOCK(cs_wallet);
1953         if (mapWallet.erase(hash))
1954             CWalletDB(strWalletFile).EraseTx(hash);
1955     }
1956     return;
1957 }
1958
1959 void CWallet::RescanWallet()
1960 {
1961     if (needsRescan)
1962     {
1963         CBlockIndex *start = chainActive.Height() > 0 ? chainActive[1] : NULL;
1964         if (start)
1965             ScanForWalletTransactions(start, true);
1966         needsRescan = false;
1967     }
1968 }
1969
1970
1971 /**
1972  * Returns a nullifier if the SpendingKey is available
1973  * Throws std::runtime_error if the decryptor doesn't match this note
1974  */
1975 boost::optional<uint256> CWallet::GetSproutNoteNullifier(const JSDescription &jsdesc,
1976                                                          const libzcash::SproutPaymentAddress &address,
1977                                                          const ZCNoteDecryption &dec,
1978                                                          const uint256 &hSig,
1979                                                          uint8_t n) const
1980 {
1981     boost::optional<uint256> ret;
1982     auto note_pt = libzcash::SproutNotePlaintext::decrypt(
1983         dec,
1984         jsdesc.ciphertexts[n],
1985         jsdesc.ephemeralKey,
1986         hSig,
1987         (unsigned char) n);
1988     auto note = note_pt.note(address);
1989     // SpendingKeys are only available if:
1990     // - We have them (this isn't a viewing key)
1991     // - The wallet is unlocked
1992     libzcash::SproutSpendingKey key;
1993     if (GetSproutSpendingKey(address, key)) {
1994         ret = note.nullifier(key);
1995     }
1996     return ret;
1997 }
1998
1999 /**
2000  * Finds all output notes in the given transaction that have been sent to
2001  * PaymentAddresses in this wallet.
2002  *
2003  * It should never be necessary to call this method with a CWalletTx, because
2004  * the result of FindMySproutNotes (for the addresses available at the time) will
2005  * already have been cached in CWalletTx.mapSproutNoteData.
2006  */
2007 mapSproutNoteData_t CWallet::FindMySproutNotes(const CTransaction &tx) const
2008 {
2009     LOCK(cs_SpendingKeyStore);
2010     uint256 hash = tx.GetHash();
2011
2012     mapSproutNoteData_t noteData;
2013     for (size_t i = 0; i < tx.vjoinsplit.size(); i++) {
2014         auto hSig = tx.vjoinsplit[i].h_sig(*pzcashParams, tx.joinSplitPubKey);
2015         for (uint8_t j = 0; j < tx.vjoinsplit[i].ciphertexts.size(); j++) {
2016             for (const NoteDecryptorMap::value_type& item : mapNoteDecryptors) {
2017                 try {
2018                     auto address = item.first;
2019                     JSOutPoint jsoutpt {hash, i, j};
2020                     auto nullifier = GetSproutNoteNullifier(
2021                         tx.vjoinsplit[i],
2022                         address,
2023                         item.second,
2024                         hSig, j);
2025                     if (nullifier) {
2026                         SproutNoteData nd {address, *nullifier};
2027                         noteData.insert(std::make_pair(jsoutpt, nd));
2028                     } else {
2029                         SproutNoteData nd {address};
2030                         noteData.insert(std::make_pair(jsoutpt, nd));
2031                     }
2032                     break;
2033                 } catch (const note_decryption_failed &err) {
2034                     // Couldn't decrypt with this decryptor
2035                 } catch (const std::exception &exc) {
2036                     // Unexpected failure
2037                     LogPrintf("FindMySproutNotes(): Unexpected error while testing decrypt:\n");
2038                     LogPrintf("%s\n", exc.what());
2039                 }
2040             }
2041         }
2042     }
2043     return noteData;
2044 }
2045
2046
2047 /**
2048  * Finds all output notes in the given transaction that have been sent to
2049  * SaplingPaymentAddresses in this wallet.
2050  *
2051  * It should never be necessary to call this method with a CWalletTx, because
2052  * the result of FindMySaplingNotes (for the addresses available at the time) will
2053  * already have been cached in CWalletTx.mapSaplingNoteData.
2054  */
2055 std::pair<mapSaplingNoteData_t, SaplingIncomingViewingKeyMap> CWallet::FindMySaplingNotes(const CTransaction &tx) const
2056 {
2057     LOCK(cs_SpendingKeyStore);
2058     uint256 hash = tx.GetHash();
2059
2060     mapSaplingNoteData_t noteData;
2061     SaplingIncomingViewingKeyMap viewingKeysToAdd;
2062
2063     // Protocol Spec: 4.19 Block Chain Scanning (Sapling)
2064     for (uint32_t i = 0; i < tx.vShieldedOutput.size(); ++i) {
2065         const OutputDescription output = tx.vShieldedOutput[i];
2066         for (auto it = mapSaplingFullViewingKeys.begin(); it != mapSaplingFullViewingKeys.end(); ++it) {
2067             SaplingIncomingViewingKey ivk = it->first;
2068             auto result = SaplingNotePlaintext::decrypt(output.encCiphertext, ivk, output.ephemeralKey, output.cm);
2069             if (!result) {
2070                 continue;
2071             }
2072             auto address = ivk.address(result.get().d);
2073             if (address && mapSaplingIncomingViewingKeys.count(address.get()) == 0) {
2074                 viewingKeysToAdd[address.get()] = ivk;
2075             }
2076             // We don't cache the nullifier here as computing it requires knowledge of the note position
2077             // in the commitment tree, which can only be determined when the transaction has been mined.
2078             SaplingOutPoint op {hash, i};
2079             SaplingNoteData nd;
2080             nd.ivk = ivk;
2081             noteData.insert(std::make_pair(op, nd));
2082             break;
2083         }
2084     }
2085
2086     return std::make_pair(noteData, viewingKeysToAdd);
2087 }
2088
2089 bool CWallet::IsSproutNullifierFromMe(const uint256& nullifier) const
2090 {
2091     {
2092         LOCK(cs_wallet);
2093         if (mapSproutNullifiersToNotes.count(nullifier) &&
2094                 mapWallet.count(mapSproutNullifiersToNotes.at(nullifier).hash)) {
2095             return true;
2096         }
2097     }
2098     return false;
2099 }
2100
2101 bool CWallet::IsSaplingNullifierFromMe(const uint256& nullifier) const
2102 {
2103     {
2104         LOCK(cs_wallet);
2105         if (mapSaplingNullifiersToNotes.count(nullifier) &&
2106                 mapWallet.count(mapSaplingNullifiersToNotes.at(nullifier).hash)) {
2107             return true;
2108         }
2109     }
2110     return false;
2111 }
2112
2113 void CWallet::GetSproutNoteWitnesses(std::vector<JSOutPoint> notes,
2114                                      std::vector<boost::optional<SproutWitness>>& witnesses,
2115                                      uint256 &final_anchor)
2116 {
2117     LOCK(cs_wallet);
2118     witnesses.resize(notes.size());
2119     boost::optional<uint256> rt;
2120     int i = 0;
2121     for (JSOutPoint note : notes) {
2122         if (mapWallet.count(note.hash) &&
2123                 mapWallet[note.hash].mapSproutNoteData.count(note) &&
2124                 mapWallet[note.hash].mapSproutNoteData[note].witnesses.size() > 0) {
2125             witnesses[i] = mapWallet[note.hash].mapSproutNoteData[note].witnesses.front();
2126             if (!rt) {
2127                 rt = witnesses[i]->root();
2128             } else {
2129                 assert(*rt == witnesses[i]->root());
2130             }
2131         }
2132         i++;
2133     }
2134     // All returned witnesses have the same anchor
2135     if (rt) {
2136         final_anchor = *rt;
2137     }
2138 }
2139
2140 void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint> notes,
2141                                       std::vector<boost::optional<SaplingWitness>>& witnesses,
2142                                       uint256 &final_anchor)
2143 {
2144     LOCK(cs_wallet);
2145     witnesses.resize(notes.size());
2146     boost::optional<uint256> rt;
2147     int i = 0;
2148     for (SaplingOutPoint note : notes) {
2149         if (mapWallet.count(note.hash) &&
2150                 mapWallet[note.hash].mapSaplingNoteData.count(note) &&
2151                 mapWallet[note.hash].mapSaplingNoteData[note].witnesses.size() > 0) {
2152             witnesses[i] = mapWallet[note.hash].mapSaplingNoteData[note].witnesses.front();
2153             if (!rt) {
2154                 rt = witnesses[i]->root();
2155             } else {
2156                 assert(*rt == witnesses[i]->root());
2157             }
2158         }
2159         i++;
2160     }
2161     // All returned witnesses have the same anchor
2162     if (rt) {
2163         final_anchor = *rt;
2164     }
2165 }
2166
2167 isminetype CWallet::IsMine(const CTxIn &txin) const
2168 {
2169     {
2170         LOCK(cs_wallet);
2171         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
2172         if (mi != mapWallet.end())
2173         {
2174             const CWalletTx& prev = (*mi).second;
2175             if (txin.prevout.n < prev.vout.size())
2176                 return (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey));
2177         }
2178     }
2179     return ISMINE_NO;
2180 }
2181
2182 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
2183 {
2184     {
2185         LOCK(cs_wallet);
2186         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
2187         if (mi != mapWallet.end())
2188         {
2189             const CWalletTx& prev = (*mi).second;
2190             if (txin.prevout.n < prev.vout.size())
2191                 if (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey) & filter)
2192                     return prev.vout[txin.prevout.n].nValue; // komodo_interest?
2193         }
2194     }
2195     return 0;
2196 }
2197
2198 isminetype CWallet::IsMine(const CTxOut& txout) const
2199 {
2200     return ::IsMine(*this, txout.scriptPubKey);
2201 }
2202
2203 CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
2204 {
2205     if (!MoneyRange(txout.nValue))
2206         throw std::runtime_error("CWallet::GetCredit(): value out of range");
2207     return ((IsMine(txout) & filter) ? txout.nValue : 0);
2208 }
2209
2210 bool CWallet::IsChange(const CTxOut& txout) const
2211 {
2212     // TODO: fix handling of 'change' outputs. The assumption is that any
2213     // payment to a script that is ours, but is not in the address book
2214     // is change. That assumption is likely to break when we implement multisignature
2215     // wallets that return change back into a multi-signature-protected address;
2216     // a better way of identifying which outputs are 'the send' and which are
2217     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
2218     // which output, if any, was change).
2219     if (::IsMine(*this, txout.scriptPubKey))
2220     {
2221         CTxDestination address;
2222         if (!ExtractDestination(txout.scriptPubKey, address))
2223             return true;
2224
2225         LOCK(cs_wallet);
2226         if (!mapAddressBook.count(address))
2227             return true;
2228     }
2229     return false;
2230 }
2231
2232 CAmount CWallet::GetChange(const CTxOut& txout) const
2233 {
2234     if (!MoneyRange(txout.nValue))
2235         throw std::runtime_error("CWallet::GetChange(): value out of range");
2236     return (IsChange(txout) ? txout.nValue : 0);
2237 }
2238
2239 typedef vector<unsigned char> valtype;
2240 unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore);
2241
2242 bool CWallet::IsMine(const CTransaction& tx)
2243 {
2244     for (int i = 0; i < tx.vout.size(); i++)
2245     {
2246         if (IsMine(tx, i))
2247             return true;
2248     }
2249     return false;
2250 }
2251
2252 // special case handling for non-standard/Verus OP_RETURN script outputs, which need the transaction
2253 // to determine ownership
2254 isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
2255 {
2256     vector<valtype> vSolutions;
2257     txnouttype whichType;
2258     const CScriptExt scriptPubKey = CScriptExt(tx.vout[voutNum].scriptPubKey);
2259
2260     if (!Solver(scriptPubKey, whichType, vSolutions)) {
2261         if (this->HaveWatchOnly(scriptPubKey))
2262             return ISMINE_WATCH_ONLY;
2263         return ISMINE_NO;
2264     }
2265
2266     CKeyID keyID;
2267     CScriptID scriptID;
2268     CScriptExt subscript;
2269     int voutNext = voutNum + 1;
2270
2271     switch (whichType)
2272     {
2273         case TX_NONSTANDARD:
2274         case TX_NULL_DATA:
2275             break;
2276
2277         case TX_CRYPTOCONDITION:
2278             // for now, default is that the first value returned will be the script, subsequent values will be
2279             // pubkeys. if we have the first pub key in our wallet, we consider this spendable
2280             if (vSolutions.size() > 1)
2281             {
2282                 keyID = CPubKey(vSolutions[1]).GetID();
2283                 if (this->HaveKey(keyID))
2284                     return ISMINE_SPENDABLE;
2285             }
2286             break;
2287
2288         case TX_PUBKEY:
2289             keyID = CPubKey(vSolutions[0]).GetID();
2290             if (this->HaveKey(keyID))
2291                 return ISMINE_SPENDABLE;
2292             break;
2293
2294         case TX_PUBKEYHASH:
2295             keyID = CKeyID(uint160(vSolutions[0]));
2296             if (this->HaveKey(keyID))
2297                 return ISMINE_SPENDABLE;
2298             break;
2299
2300         case TX_SCRIPTHASH:
2301             scriptID = CScriptID(uint160(vSolutions[0]));
2302             if (this->GetCScript(scriptID, subscript)) 
2303             {
2304                 // if this is a CLTV, handle it differently
2305                 if (subscript.IsCheckLockTimeVerify())
2306                 {
2307                     return (::IsMine(*this, subscript));
2308                 }
2309                 else
2310                 {
2311                     isminetype ret = ::IsMine(*this, subscript);
2312                     if (ret == ISMINE_SPENDABLE)
2313                         return ret;
2314                 }
2315             }
2316             else if (tx.vout.size() > (voutNum + 1) &&
2317                 tx.vout.back().scriptPubKey.size() > 7 &&
2318                 tx.vout.back().scriptPubKey[0] == OP_RETURN)
2319             {
2320                 // get the opret script from next vout, verify that the front is CLTV and hash matches
2321                 // if so, remove it and use the solver
2322                 opcodetype op;
2323                 std::vector<uint8_t> opretData;
2324                 CScript::const_iterator it = tx.vout.back().scriptPubKey.begin() + 1;
2325                 if (tx.vout.back().scriptPubKey.GetOp2(it, op, &opretData))
2326                 {
2327                     if (opretData.size() > 0 && opretData[0] == OPRETTYPE_TIMELOCK)
2328                     {
2329                         CScript opretScript = CScript(opretData.begin() + 1, opretData.end());
2330
2331                         if (CScriptID(opretScript) == scriptID &&
2332                             opretScript.IsCheckLockTimeVerify())
2333                         {
2334                             // if we find that this is ours, we need to add this script to the wallet,
2335                             // and we can then recognize this transaction
2336                             isminetype t = ::IsMine(*this, opretScript);
2337                             if (t != ISMINE_NO)
2338                             {
2339                                 this->AddCScript(opretScript);
2340                             }
2341                             return t;
2342                         }
2343                     }
2344                 }
2345             }
2346             break;
2347
2348         case TX_MULTISIG:
2349             // Only consider transactions "mine" if we own ALL the
2350             // keys involved. Multi-signature transactions that are
2351             // partially owned (somebody else has a key that can spend
2352             // them) enable spend-out-from-under-you attacks, especially
2353             // in shared-wallet situations.
2354             vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
2355             if (HaveKeys(keys, *this) == keys.size())
2356                 return ISMINE_SPENDABLE;
2357             break;
2358     }
2359
2360     if (this->HaveWatchOnly(scriptPubKey))
2361         return ISMINE_WATCH_ONLY;
2362
2363     return ISMINE_NO;
2364 }
2365
2366 bool CWallet::IsFromMe(const CTransaction& tx) const
2367 {
2368     if (GetDebit(tx, ISMINE_ALL) > 0) {
2369         return true;
2370     }
2371     for (const JSDescription& jsdesc : tx.vjoinsplit) {
2372         for (const uint256& nullifier : jsdesc.nullifiers) {
2373             if (IsSproutNullifierFromMe(nullifier)) {
2374                 return true;
2375             }
2376         }
2377     }
2378     for (const SpendDescription &spend : tx.vShieldedSpend) {
2379         if (IsSaplingNullifierFromMe(spend.nullifier)) {
2380             return true;
2381         }
2382     }
2383     return false;
2384 }
2385
2386 CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
2387 {
2388     CAmount nDebit = 0;
2389     BOOST_FOREACH(const CTxIn& txin, tx.vin)
2390     {
2391         nDebit += GetDebit(txin, filter);
2392         if (!MoneyRange(nDebit))
2393             throw std::runtime_error("CWallet::GetDebit(): value out of range");
2394     }
2395     return nDebit;
2396 }
2397
2398 CAmount CWallet::GetCredit(const CTransaction& tx, int32_t voutNum, const isminefilter& filter) const
2399 {
2400     if (voutNum >= tx.vout.size() || !MoneyRange(tx.vout[voutNum].nValue))
2401         throw std::runtime_error("CWallet::GetCredit(): value out of range");
2402     return ((IsMine(tx.vout[voutNum]) & filter) ? tx.vout[voutNum].nValue : 0);
2403 }
2404
2405 CAmount CWallet::GetReserveCredit(const CTransaction& tx, int32_t voutNum, const isminefilter& filter) const
2406 {
2407     return ((IsMine(tx.vout[voutNum]) & filter) ? tx.vout[voutNum].ReserveOutValue() : 0);
2408 }
2409
2410 CAmount CWallet::GetReserveCredit(const CTransaction& tx, const isminefilter& filter) const
2411 {
2412     CAmount nCredit = 0;
2413     for (int i = 0; i < tx.vout.size(); i++)
2414     {
2415         nCredit += GetReserveCredit(tx, i, filter);
2416     }
2417     return nCredit;
2418 }
2419
2420 CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
2421 {
2422     CAmount nCredit = 0;
2423     for (int i = 0; i < tx.vout.size(); i++)
2424     {
2425         nCredit += GetCredit(tx, i, filter);
2426     }
2427     return nCredit;
2428 }
2429
2430 CAmount CWallet::GetChange(const CTransaction& tx) const
2431 {
2432     CAmount nChange = 0;
2433     BOOST_FOREACH(const CTxOut& txout, tx.vout)
2434     {
2435         nChange += GetChange(txout);
2436         if (!MoneyRange(nChange))
2437             throw std::runtime_error("CWallet::GetChange(): value out of range");
2438     }
2439     return nChange;
2440 }
2441
2442 bool CWallet::IsHDFullyEnabled() const
2443 {
2444     // Only Sapling addresses are HD for now
2445     return false;
2446 }
2447
2448 void CWallet::GenerateNewSeed()
2449 {
2450     LOCK(cs_wallet);
2451
2452     auto seed = HDSeed::Random(HD_WALLET_SEED_LENGTH);
2453
2454     int64_t nCreationTime = GetTime();
2455
2456     // If the wallet is encrypted and locked, this will fail.
2457     if (!SetHDSeed(seed))
2458         throw std::runtime_error(std::string(__func__) + ": SetHDSeed failed");
2459
2460     // store the key creation time together with
2461     // the child index counter in the database
2462     // as a hdchain object
2463     CHDChain newHdChain;
2464     newHdChain.nVersion = CHDChain::VERSION_HD_BASE;
2465     newHdChain.seedFp = seed.Fingerprint();
2466     newHdChain.nCreateTime = nCreationTime;
2467     SetHDChain(newHdChain, false);
2468 }
2469
2470 bool CWallet::SetHDSeed(const HDSeed& seed)
2471 {
2472     if (!CCryptoKeyStore::SetHDSeed(seed)) {
2473         return false;
2474     }
2475
2476     if (!fFileBacked) {
2477         return true;
2478     }
2479
2480     {
2481         LOCK(cs_wallet);
2482         if (!IsCrypted()) {
2483             return CWalletDB(strWalletFile).WriteHDSeed(seed);
2484         }
2485     }
2486     return true;
2487 }
2488
2489 bool CWallet::SetCryptedHDSeed(const uint256& seedFp, const std::vector<unsigned char> &vchCryptedSecret)
2490 {
2491     if (!CCryptoKeyStore::SetCryptedHDSeed(seedFp, vchCryptedSecret)) {
2492         return false;
2493     }
2494
2495     if (!fFileBacked) {
2496         return true;
2497     }
2498
2499     {
2500         LOCK(cs_wallet);
2501         if (pwalletdbEncryption)
2502             return pwalletdbEncryption->WriteCryptedHDSeed(seedFp, vchCryptedSecret);
2503         else
2504             return CWalletDB(strWalletFile).WriteCryptedHDSeed(seedFp, vchCryptedSecret);
2505     }
2506     return false;
2507 }
2508
2509 void CWallet::SetHDChain(const CHDChain& chain, bool memonly)
2510 {
2511     LOCK(cs_wallet);
2512     if (!memonly && fFileBacked && !CWalletDB(strWalletFile).WriteHDChain(chain))
2513         throw std::runtime_error(std::string(__func__) + ": writing chain failed");
2514
2515     hdChain = chain;
2516 }
2517
2518 bool CWallet::LoadHDSeed(const HDSeed& seed)
2519 {
2520     return CBasicKeyStore::SetHDSeed(seed);
2521 }
2522
2523 bool CWallet::LoadCryptedHDSeed(const uint256& seedFp, const std::vector<unsigned char>& seed)
2524 {
2525     return CCryptoKeyStore::SetCryptedHDSeed(seedFp, seed);
2526 }
2527
2528 void CWalletTx::SetSproutNoteData(mapSproutNoteData_t &noteData)
2529 {
2530     mapSproutNoteData.clear();
2531     for (const std::pair<JSOutPoint, SproutNoteData> nd : noteData) {
2532         if (nd.first.js < vjoinsplit.size() &&
2533                 nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
2534             // Store the address and nullifier for the Note
2535             mapSproutNoteData[nd.first] = nd.second;
2536         } else {
2537             // If FindMySproutNotes() was used to obtain noteData,
2538             // this should never happen
2539             throw std::logic_error("CWalletTx::SetSproutNoteData(): Invalid note");
2540         }
2541     }
2542 }
2543
2544 void CWalletTx::SetSaplingNoteData(mapSaplingNoteData_t &noteData)
2545 {
2546     mapSaplingNoteData.clear();
2547     for (const std::pair<SaplingOutPoint, SaplingNoteData> nd : noteData) {
2548         if (nd.first.n < vShieldedOutput.size()) {
2549             mapSaplingNoteData[nd.first] = nd.second;
2550         } else {
2551             throw std::logic_error("CWalletTx::SetSaplingNoteData(): Invalid note");
2552         }
2553     }
2554 }
2555
2556 int64_t CWalletTx::GetTxTime() const
2557 {
2558     int64_t n = nTimeSmart;
2559     return n ? n : nTimeReceived;
2560 }
2561
2562 int CWalletTx::GetRequestCount() const
2563 {
2564     // Returns -1 if it wasn't being tracked
2565     int nRequests = -1;
2566     {
2567         LOCK(pwallet->cs_wallet);
2568         if (IsCoinBase())
2569         {
2570             // Generated block
2571             if (!hashBlock.IsNull())
2572             {
2573                 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
2574                 if (mi != pwallet->mapRequestCount.end())
2575                     nRequests = (*mi).second;
2576             }
2577         }
2578         else
2579         {
2580             // Did anyone request this transaction?
2581             map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
2582             if (mi != pwallet->mapRequestCount.end())
2583             {
2584                 nRequests = (*mi).second;
2585
2586                 // How about the block it's in?
2587                 if (nRequests == 0 && !hashBlock.IsNull())
2588                 {
2589                     map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
2590                     if (mi != pwallet->mapRequestCount.end())
2591                         nRequests = (*mi).second;
2592                     else
2593                         nRequests = 1; // If it's in someone else's block it must have got out
2594                 }
2595             }
2596         }
2597     }
2598     return nRequests;
2599 }
2600
2601 // GetAmounts will determine the transparent debits and credits for a given wallet tx.
2602 void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
2603                            list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
2604 {
2605     nFee = 0;
2606     listReceived.clear();
2607     listSent.clear();
2608     strSentAccount = strFromAccount;
2609
2610     // Is this tx sent/signed by me?
2611     CAmount nDebit = GetDebit(filter);
2612     bool isFromMyTaddr = nDebit > 0; // debit>0 means we signed/sent this transaction
2613
2614     // Compute fee if we sent this transaction.
2615     if (isFromMyTaddr) {
2616         CAmount nValueOut = GetValueOut();  // transparent outputs plus all Sprout vpub_old and negative Sapling valueBalance
2617         CAmount nValueIn = GetShieldedValueIn();
2618         nFee = nDebit - nValueOut + nValueIn;
2619     }
2620
2621     // Create output entry for vpub_old/new, if we sent utxos from this transaction
2622     if (isFromMyTaddr) {
2623         CAmount myVpubOld = 0;
2624         CAmount myVpubNew = 0;
2625         for (const JSDescription& js : vjoinsplit) {
2626             bool fMyJSDesc = false;
2627
2628             // Check input side
2629             for (const uint256& nullifier : js.nullifiers) {
2630                 if (pwallet->IsSproutNullifierFromMe(nullifier)) {
2631                     fMyJSDesc = true;
2632                     break;
2633                 }
2634             }
2635
2636             // Check output side
2637             if (!fMyJSDesc) {
2638                 for (const std::pair<JSOutPoint, SproutNoteData> nd : this->mapSproutNoteData) {
2639                     if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
2640                         fMyJSDesc = true;
2641                         break;
2642                     }
2643                 }
2644             }
2645
2646             if (fMyJSDesc) {
2647                 myVpubOld += js.vpub_old;
2648                 myVpubNew += js.vpub_new;
2649             }
2650
2651             if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) {
2652                  throw std::runtime_error("CWalletTx::GetAmounts: value out of range");
2653             }
2654         }
2655
2656         // Create an output for the value taken from or added to the transparent value pool by JoinSplits
2657         if (myVpubOld > myVpubNew) {
2658             COutputEntry output = {CNoDestination(), myVpubOld - myVpubNew, (int)vout.size()};
2659             listSent.push_back(output);
2660         } else if (myVpubNew > myVpubOld) {
2661             COutputEntry output = {CNoDestination(), myVpubNew - myVpubOld, (int)vout.size()};
2662             listReceived.push_back(output);
2663         }
2664     }
2665
2666     // If we sent utxos from this transaction, create output for value taken from (negative valueBalance)
2667     // or added (positive valueBalance) to the transparent value pool by Sapling shielding and unshielding.
2668     if (isFromMyTaddr) {
2669         if (valueBalance < 0) {
2670             COutputEntry output = {CNoDestination(), -valueBalance, (int) vout.size()};
2671             listSent.push_back(output);
2672         } else if (valueBalance > 0) {
2673             COutputEntry output = {CNoDestination(), valueBalance, (int) vout.size()};
2674             listReceived.push_back(output);
2675         }
2676     }
2677
2678     // Sent/received.
2679     for (unsigned int i = 0; i < vout.size(); ++i)
2680     {
2681         const CTxOut& txout = vout[i];
2682         isminetype fIsMine = pwallet->IsMine(txout);
2683         // Only need to handle txouts if AT LEAST one of these is true:
2684         //   1) they debit from us (sent)
2685         //   2) the output is to us (received)
2686         if (nDebit > 0)
2687         {
2688             // Don't report 'change' txouts
2689             if (!(filter & ISMINE_CHANGE) && pwallet->IsChange(txout))
2690                 continue;
2691         }
2692         else if (!(fIsMine & filter))
2693             continue;
2694
2695         // In either case, we need to get the destination address
2696         CTxDestination address;
2697         if (!ExtractDestination(txout.scriptPubKey, address))
2698         {
2699             //LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",this->GetHash().ToString()); complains on the opreturns
2700             address = CNoDestination();
2701         }
2702
2703         COutputEntry output = {address, txout.nValue, (int)i};
2704
2705         // If we are debited by the transaction, add the output as a "sent" entry
2706         if (nDebit > 0)
2707             listSent.push_back(output);
2708
2709         // If we are receiving the output, add it as a "received" entry
2710         if (fIsMine & filter)
2711             listReceived.push_back(output);
2712     }
2713
2714 }
2715
2716 void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
2717                                   CAmount& nSent, CAmount& nFee, const isminefilter& filter) const
2718 {
2719     nReceived = nSent = nFee = 0;
2720
2721     CAmount allFee;
2722     string strSentAccount;
2723     list<COutputEntry> listReceived;
2724     list<COutputEntry> listSent;
2725     GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
2726
2727     if (strAccount == strSentAccount)
2728     {
2729         BOOST_FOREACH(const COutputEntry& s, listSent)
2730             nSent += s.amount;
2731         nFee = allFee;
2732     }
2733     {
2734         LOCK(pwallet->cs_wallet);
2735         BOOST_FOREACH(const COutputEntry& r, listReceived)
2736         {
2737             if (pwallet->mapAddressBook.count(r.destination))
2738             {
2739                 map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
2740                 if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
2741                     nReceived += r.amount;
2742             }
2743             else if (strAccount.empty())
2744             {
2745                 nReceived += r.amount;
2746             }
2747         }
2748     }
2749 }
2750
2751
2752 bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
2753 {
2754     return pwalletdb->WriteTx(GetHash(), *this);
2755 }
2756
2757 void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
2758                                     std::vector<boost::optional<SproutWitness>>& witnesses,
2759                                     uint256 &final_anchor)
2760 {
2761     witnesses.resize(commitments.size());
2762     CBlockIndex* pindex = chainActive.Genesis();
2763     SproutMerkleTree tree;
2764
2765     while (pindex) {
2766         CBlock block;
2767         ReadBlockFromDisk(block, pindex,1);
2768
2769         BOOST_FOREACH(const CTransaction& tx, block.vtx)
2770         {
2771             BOOST_FOREACH(const JSDescription& jsdesc, tx.vjoinsplit)
2772             {
2773                 BOOST_FOREACH(const uint256 &note_commitment, jsdesc.commitments)
2774                 {
2775                     tree.append(note_commitment);
2776
2777                     BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) {
2778                         if (wit) {
2779                             wit->append(note_commitment);
2780                         }
2781                     }
2782
2783                     size_t i = 0;
2784                     BOOST_FOREACH(uint256& commitment, commitments) {
2785                         if (note_commitment == commitment) {
2786                             witnesses.at(i) = tree.witness();
2787                         }
2788                         i++;
2789                     }
2790                 }
2791             }
2792         }
2793
2794         uint256 current_anchor = tree.root();
2795
2796         // Consistency check: we should be able to find the current tree
2797         // in our CCoins view.
2798         SproutMerkleTree dummy_tree;
2799         assert(pcoinsTip->GetSproutAnchorAt(current_anchor, dummy_tree));
2800
2801         pindex = chainActive.Next(pindex);
2802     }
2803
2804     // TODO: #93; Select a root via some heuristic.
2805     final_anchor = tree.root();
2806
2807     BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) {
2808         if (wit) {
2809             assert(final_anchor == wit->root());
2810         }
2811     }
2812 }
2813
2814 /**
2815  * Scan the block chain (starting in pindexStart) for transactions
2816  * from or to us. If fUpdate is true, found transactions that already
2817  * exist in the wallet will be updated.
2818  */
2819 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
2820 {
2821     int ret = 0;
2822     int64_t nNow = GetTime();
2823     const CChainParams& chainParams = Params();
2824
2825     CBlockIndex* pindex = pindexStart;
2826
2827     std::vector<uint256> myTxHashes;
2828
2829     {
2830         LOCK2(cs_main, cs_wallet);
2831
2832         // no need to read and scan block, if block was created before
2833         // our wallet birthday (as adjusted for block time variability)
2834         while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
2835             pindex = chainActive.Next(pindex);
2836
2837         ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
2838         double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
2839         double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.LastTip(), false);
2840         while (pindex)
2841         {
2842             if (pindex->GetHeight() % 100 == 0 && dProgressTip - dProgressStart > 0.0)
2843                 ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
2844
2845             CBlock block;
2846             ReadBlockFromDisk(block, pindex,1);
2847             BOOST_FOREACH(CTransaction& tx, block.vtx)
2848             {
2849                 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) {
2850                     myTxHashes.push_back(tx.GetHash());
2851                     ret++;
2852                 }
2853             }
2854
2855             SproutMerkleTree sproutTree;
2856             SaplingMerkleTree saplingTree;
2857             // This should never fail: we should always be able to get the tree
2858             // state on the path to the tip of our chain
2859             assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, sproutTree));
2860             if (pindex->pprev) {
2861                 if (NetworkUpgradeActive(pindex->pprev->GetHeight(), Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2862                     assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, saplingTree));
2863                 }
2864             }
2865             // Increment note witness caches
2866             ChainTip(pindex, &block, sproutTree, saplingTree, true);
2867
2868             pindex = chainActive.Next(pindex);
2869             if (GetTime() >= nNow + 60) {
2870                 nNow = GetTime();
2871                 LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->GetHeight(), Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
2872             }
2873         }
2874
2875         // After rescanning, persist Sapling note data that might have changed, e.g. nullifiers.
2876         // Do not flush the wallet here for performance reasons.
2877         CWalletDB walletdb(strWalletFile, "r+", false);
2878         for (auto hash : myTxHashes) {
2879             CWalletTx wtx = mapWallet[hash];
2880             if (!wtx.mapSaplingNoteData.empty()) {
2881                 if (!wtx.WriteToDisk(&walletdb)) {
2882                     LogPrintf("Rescanning... WriteToDisk failed to update Sapling note data for: %s\n", hash.ToString());
2883                 }
2884             }
2885         }
2886
2887         ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
2888     }
2889     return ret;
2890 }
2891
2892 void CWallet::ReacceptWalletTransactions()
2893 {
2894     // If transactions aren't being broadcasted, don't let them into local mempool either
2895     if (!fBroadcastTransactions)
2896         return;
2897     LOCK2(cs_main, cs_wallet);
2898     std::map<int64_t, CWalletTx*> mapSorted;
2899
2900     // Sort pending wallet transactions based on their initial wallet insertion order
2901     BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
2902     {
2903         const uint256& wtxid = item.first;
2904         CWalletTx& wtx = item.second;
2905         assert(wtx.GetHash() == wtxid);
2906
2907         int nDepth = wtx.GetDepthInMainChain();
2908
2909         if (!wtx.IsCoinBase() && nDepth < 0) {
2910             mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
2911         }
2912     }
2913
2914     std::vector<uint256> vwtxh;
2915
2916     // Try to add wallet transactions to memory pool
2917     BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted)
2918     {
2919         CWalletTx& wtx = *(item.second);
2920
2921         LOCK(mempool.cs);
2922         CValidationState state;
2923         // attempt to add them, but don't set any DOS level
2924         if (!::AcceptToMemoryPool(mempool, state, wtx, false, NULL, true, 0))
2925         {
2926             int nDoS;
2927             bool invalid = state.IsInvalid(nDoS);
2928
2929             // log rejection and deletion
2930             // printf("ERROR reaccepting wallet transaction %s to mempool, reason: %s, DoS: %d\n", wtx.GetHash().ToString().c_str(), state.GetRejectReason().c_str(), nDoS);
2931
2932             if (!wtx.IsCoinBase() && invalid && nDoS > 0)
2933             {
2934                 LogPrintf("erasing transaction %s\n", wtx.GetHash().GetHex().c_str());
2935                 vwtxh.push_back(wtx.GetHash());
2936             }
2937         }
2938     }
2939     for (auto hash : vwtxh)
2940     {
2941         EraseFromWallet(hash);
2942     }
2943 }
2944
2945 bool CWalletTx::RelayWalletTransaction()
2946 {
2947     if ( pwallet == 0 )
2948     {
2949         fprintf(stderr,"unexpected null pwallet in RelayWalletTransaction\n");
2950         return(false);
2951     }
2952     assert(pwallet->GetBroadcastTransactions());
2953     if (!IsCoinBase())
2954     {
2955         if (GetDepthInMainChain() == 0)
2956         {
2957             // if tx is expired, dont relay
2958             LogPrintf("Relaying wtx %s\n", GetHash().ToString());
2959             RelayTransaction((CTransaction)*this);
2960             return true;
2961         }
2962     }
2963     return false;
2964 }
2965
2966 set<uint256> CWalletTx::GetConflicts() const
2967 {
2968     set<uint256> result;
2969     if (pwallet != NULL)
2970     {
2971         uint256 myHash = GetHash();
2972         result = pwallet->GetConflicts(myHash);
2973         result.erase(myHash);
2974     }
2975     return result;
2976 }
2977
2978 CAmount CWalletTx::GetDebit(const isminefilter& filter) const
2979 {
2980     if (vin.empty())
2981         return 0;
2982
2983     CAmount debit = 0;
2984     if(filter & ISMINE_SPENDABLE)
2985     {
2986         if (fDebitCached)
2987             debit += nDebitCached;
2988         else
2989         {
2990             nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
2991             fDebitCached = true;
2992             debit += nDebitCached;
2993         }
2994     }
2995     if(filter & ISMINE_WATCH_ONLY)
2996     {
2997         if(fWatchDebitCached)
2998             debit += nWatchDebitCached;
2999         else
3000         {
3001             nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
3002             fWatchDebitCached = true;
3003             debit += nWatchDebitCached;
3004         }
3005     }
3006     return debit;
3007 }
3008
3009 CAmount CWalletTx::GetReserveDebit(const isminefilter& filter) const
3010 {
3011     if (vin.empty())
3012         return 0;
3013
3014     CAmount debit = 0;
3015     if(filter & ISMINE_SPENDABLE)
3016     {
3017         if (fReserveDebitCached)
3018             debit += nReserveDebitCached;
3019         else
3020         {
3021             nReserveDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
3022             fReserveDebitCached = true;
3023             debit += nReserveDebitCached;
3024         }
3025     }
3026     if(filter & ISMINE_WATCH_ONLY)
3027     {
3028         if(fWatchReserveDebitCached)
3029             debit += nWatchReserveDebitCached;
3030         else
3031         {
3032             nWatchReserveDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
3033             fWatchReserveDebitCached = true;
3034             debit += nWatchReserveDebitCached;
3035         }
3036     }
3037     return debit;
3038 }
3039
3040 CAmount CWalletTx::GetCredit(const isminefilter& filter) const
3041 {
3042     // Must wait until coinbase is safely deep enough in the chain before valuing it
3043     if (IsCoinBase() && GetBlocksToMaturity() > 0)
3044         return 0;
3045
3046     int64_t credit = 0;
3047     if (filter & ISMINE_SPENDABLE)
3048     {
3049         // GetBalance can assume transactions in mapWallet won't change
3050         if (fCreditCached)
3051             credit += nCreditCached;
3052         else
3053         {
3054             nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
3055             fCreditCached = true;
3056             credit += nCreditCached;
3057         }
3058     }
3059     if (filter & ISMINE_WATCH_ONLY)
3060     {
3061         if (fWatchCreditCached)
3062             credit += nWatchCreditCached;
3063         else
3064         {
3065             nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
3066             fWatchCreditCached = true;
3067             credit += nWatchCreditCached;
3068         }
3069     }
3070     return credit;
3071 }
3072
3073 bool CWalletTx::HasMatureCoins() const
3074 {
3075     // Must wait until coinbase is safely deep enough in the chain before valuing it
3076     if (!(IsCoinBase() && GetBlocksToMaturity() > 0))
3077     {
3078         return true;
3079     }
3080     else
3081     {
3082         for (auto oneout : vout)
3083         {
3084             if (oneout.scriptPubKey.IsInstantSpend())
3085             {
3086                 return true;
3087             }
3088         }
3089         return false;
3090     }
3091 }
3092
3093 CAmount CWalletTx::GetReserveCredit(const isminefilter& filter) const
3094 {
3095     // Must wait until coinbase is safely deep enough in the chain before valuing it
3096     if (IsCoinBase() && GetBlocksToMaturity() > 0)
3097         return 0;
3098
3099     int64_t credit = 0;
3100     if (filter & ISMINE_SPENDABLE)
3101     {
3102         // GetBalance can assume transactions in mapWallet won't change
3103         if (fReserveCreditCached)
3104             credit += nReserveCreditCached;
3105         else
3106         {
3107             nReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_SPENDABLE);
3108             fReserveCreditCached = true;
3109             credit += nReserveCreditCached;
3110         }
3111     }
3112     if (filter & ISMINE_WATCH_ONLY)
3113     {
3114         if (fWatchReserveCreditCached)
3115             credit += nWatchReserveCreditCached;
3116         else
3117         {
3118             nWatchReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_WATCH_ONLY);
3119             fWatchReserveCreditCached = true;
3120             credit += nWatchReserveCreditCached;
3121         }
3122     }
3123     return credit;
3124 }
3125
3126 CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
3127 {
3128     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3129     {
3130         if (fUseCache && fImmatureCreditCached)
3131             return nImmatureCreditCached;
3132         nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
3133         fImmatureCreditCached = true;
3134         return nImmatureCreditCached;
3135     }
3136
3137     return 0;
3138 }
3139
3140 CAmount CWalletTx::GetImmatureReserveCredit(bool fUseCache) const
3141 {
3142     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3143     {
3144         if (fUseCache && fImmatureReserveCreditCached)
3145             return nImmatureReserveCreditCached;
3146         nImmatureReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_SPENDABLE);
3147         fImmatureReserveCreditCached = true;
3148         return nImmatureReserveCreditCached;
3149     }
3150
3151     return 0;
3152 }
3153
3154 CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
3155 {
3156     if (pwallet == 0)
3157         return 0;
3158
3159     // Must wait until coinbase is safely deep enough in the chain before valuing it
3160     if (IsCoinBase() && GetBlocksToMaturity() > 0)
3161         return 0;
3162
3163     if (fUseCache && fAvailableCreditCached)
3164         return nAvailableCreditCached;
3165
3166     CAmount nCredit = 0;
3167     uint256 hashTx = GetHash();
3168     for (unsigned int i = 0; i < vout.size(); i++)
3169     {
3170         if (!pwallet->IsSpent(hashTx, i))
3171         {
3172             nCredit += pwallet->GetCredit(*this, i, ISMINE_SPENDABLE);
3173             if (!MoneyRange(nCredit))
3174                 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
3175         }
3176     }
3177
3178     nAvailableCreditCached = nCredit;
3179     fAvailableCreditCached = true;
3180     return nCredit;
3181 }
3182
3183 CAmount CWalletTx::GetAvailableReserveCredit(bool fUseCache) const
3184 {
3185     if (pwallet == 0)
3186         return 0;
3187
3188     // Must wait until coinbase is safely deep enough in the chain before valuing it
3189     if (IsCoinBase() && GetBlocksToMaturity() > 0)
3190         return 0;
3191
3192     if (fUseCache && fAvailableReserveCreditCached)
3193         return nAvailableReserveCreditCached;
3194
3195     CAmount nCredit = 0;
3196     uint256 hashTx = GetHash();
3197     for (unsigned int i = 0; i < vout.size(); i++)
3198     {
3199         if (!pwallet->IsSpent(hashTx, i))
3200         {
3201             nCredit += pwallet->GetReserveCredit(*this, i, ISMINE_SPENDABLE);
3202         }
3203     }
3204
3205     nAvailableReserveCreditCached = nCredit;
3206     fAvailableReserveCreditCached = true;
3207     return nCredit;
3208 }
3209
3210 CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
3211 {
3212     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3213     {
3214         if (fUseCache && fImmatureWatchCreditCached)
3215             return nImmatureWatchCreditCached;
3216         nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
3217         fImmatureWatchCreditCached = true;
3218         return nImmatureWatchCreditCached;
3219     }
3220
3221     return 0;
3222 }
3223
3224 CAmount CWalletTx::GetImmatureWatchOnlyReserveCredit(const bool& fUseCache) const
3225 {
3226     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
3227     {
3228         if (fUseCache && fImmatureWatchReserveCreditCached)
3229             return nImmatureWatchReserveCreditCached;
3230         nImmatureWatchReserveCreditCached = pwallet->GetReserveCredit(*this, ISMINE_WATCH_ONLY);
3231         fImmatureWatchReserveCreditCached = true;
3232         return nImmatureWatchReserveCreditCached;
3233     }
3234
3235     return 0;
3236 }
3237
3238 CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
3239 {
3240     if (pwallet == 0)
3241         return 0;
3242
3243     // Must wait until coinbase is safely deep enough in the chain before valuing it
3244     if (IsCoinBase() && GetBlocksToMaturity() > 0)
3245         return 0;
3246
3247     if (fUseCache && fAvailableWatchCreditCached)
3248         return nAvailableWatchCreditCached;
3249
3250     CAmount nCredit = 0;
3251     for (unsigned int i = 0; i < vout.size(); i++)
3252     {
3253         if (!pwallet->IsSpent(GetHash(), i))
3254         {
3255             nCredit += pwallet->GetCredit(*this, i, ISMINE_WATCH_ONLY);
3256             if (!MoneyRange(nCredit))
3257                 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
3258         }
3259     }
3260
3261     nAvailableWatchCreditCached = nCredit;
3262     fAvailableWatchCreditCached = true;
3263     return nCredit;
3264 }
3265
3266 CAmount CWalletTx::GetAvailableWatchOnlyReserveCredit(const bool& fUseCache) const
3267 {
3268     if (pwallet == 0)
3269         return 0;
3270
3271     // Must wait until coinbase is safely deep enough in the chain before valuing it
3272     if (IsCoinBase() && GetBlocksToMaturity() > 0)
3273         return 0;
3274
3275     if (fUseCache && fAvailableWatchReserveCreditCached)
3276         return nAvailableWatchReserveCreditCached;
3277
3278     CAmount nCredit = 0;
3279     for (unsigned int i = 0; i < vout.size(); i++)
3280     {
3281         if (!pwallet->IsSpent(GetHash(), i))
3282         {
3283             nCredit += pwallet->GetReserveCredit(*this, i, ISMINE_WATCH_ONLY);
3284             if (!MoneyRange(nCredit))
3285                 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
3286         }
3287     }
3288
3289     nAvailableWatchReserveCreditCached = nCredit;
3290     fAvailableWatchReserveCreditCached = true;
3291     return nCredit;
3292 }
3293
3294 CAmount CWalletTx::GetChange() const
3295 {
3296     if (fChangeCached)
3297         return nChangeCached;
3298     nChangeCached = pwallet->GetChange(*this);
3299     fChangeCached = true;
3300     return nChangeCached;
3301 }
3302
3303 bool CWalletTx::IsTrusted() const
3304 {
3305     // Quick answer in most cases
3306     if (!CheckFinalTx(*this))
3307         return false;
3308     int nDepth = GetDepthInMainChain();
3309     if (nDepth >= 1)
3310         return true;
3311     if (nDepth < 0)
3312         return false;
3313     if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
3314         return false;
3315
3316     // Trusted if all inputs are from us and are in the mempool:
3317     BOOST_FOREACH(const CTxIn& txin, vin)
3318     {
3319         // Transactions not sent by us: not trusted
3320         const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
3321         if (parent == NULL)
3322             return false;
3323         const CTxOut& parentOut = parent->vout[txin.prevout.n];
3324         if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
3325             return false;
3326     }
3327     return true;
3328 }
3329
3330 std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
3331 {
3332     std::vector<uint256> result;
3333
3334     LOCK(cs_wallet);
3335     // Sort them in chronological order
3336     multimap<unsigned int, CWalletTx*> mapSorted;
3337     uint32_t now = (uint32_t)time(NULL);
3338     std::vector<uint256> vwtxh;
3339     BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
3340     {
3341         CWalletTx& wtx = item.second;
3342         // Don't rebroadcast if newer than nTime:
3343         if (wtx.nTimeReceived > nTime)
3344             continue;
3345         if ( (wtx.nLockTime >= LOCKTIME_THRESHOLD && wtx.nLockTime < now-KOMODO_MAXMEMPOOLTIME) || wtx.hashBlock.IsNull() )
3346         {
3347             //LogPrintf("skip Relaying wtx %s nLockTime %u vs now.%u\n", wtx.GetHash().ToString(),(uint32_t)wtx.nLockTime,now);
3348             //vwtxh.push_back(wtx.GetHash());
3349             continue;
3350         }
3351         mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
3352     }
3353     BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
3354     {
3355         if ( item.second != 0 )
3356         {
3357             CWalletTx &wtx = *item.second;
3358             if (wtx.RelayWalletTransaction())
3359                 result.push_back(wtx.GetHash());
3360         }
3361     }
3362     for (auto hash : vwtxh)
3363     {
3364         EraseFromWallets(hash);
3365     }
3366     return result;
3367 }
3368
3369 void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
3370 {
3371     // Do this infrequently and randomly to avoid giving away
3372     // that these are our transactions.
3373     if (GetTime() < nNextResend || !fBroadcastTransactions)
3374         return;
3375     bool fFirst = (nNextResend == 0);
3376     nNextResend = GetTime() + GetRand(30 * 60);
3377     if (fFirst)
3378         return;
3379
3380     // Only do it if there's been a new block since last time
3381     if (nBestBlockTime < nLastResend)
3382         return;
3383     nLastResend = GetTime();
3384
3385     // Rebroadcast unconfirmed txes older than 5 minutes before the last
3386     // block was found:
3387     std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
3388     if (!relayed.empty())
3389         LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
3390 }
3391
3392 /** @} */ // end of mapWallet
3393
3394
3395
3396
3397 /** @defgroup Actions
3398  *
3399  * @{
3400  */
3401
3402
3403 CAmount CWallet::GetBalance() const
3404 {
3405     CAmount nTotal = 0;
3406     {
3407         LOCK2(cs_main, cs_wallet);
3408         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3409         {
3410             const CWalletTx* pcoin = &(*it).second;
3411             if (pcoin->IsTrusted())
3412                 nTotal += pcoin->GetAvailableCredit();
3413         }
3414     }
3415
3416     return nTotal;
3417 }
3418
3419 CAmount CWallet::GetReserveBalance() const
3420 {
3421     CAmount nTotal = 0;
3422     {
3423         LOCK2(cs_main, cs_wallet);
3424         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3425         {
3426             const CWalletTx* pcoin = &(*it).second;
3427             if (pcoin->IsTrusted())
3428                 nTotal += pcoin->GetAvailableReserveCredit();
3429         }
3430     }
3431
3432     return nTotal;
3433 }
3434
3435 CAmount CWallet::GetUnconfirmedBalance() const
3436 {
3437     CAmount nTotal = 0;
3438     {
3439         LOCK2(cs_main, cs_wallet);
3440         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3441         {
3442             const CWalletTx* pcoin = &(*it).second;
3443             if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3444                 nTotal += pcoin->GetAvailableCredit();
3445         }
3446     }
3447     return nTotal;
3448 }
3449
3450 CAmount CWallet::GetUnconfirmedReserveBalance() const
3451 {
3452     CAmount nTotal = 0;
3453     {
3454         LOCK2(cs_main, cs_wallet);
3455         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3456         {
3457             const CWalletTx* pcoin = &(*it).second;
3458             if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3459                 nTotal += pcoin->GetAvailableReserveCredit();
3460         }
3461     }
3462     return nTotal;
3463 }
3464
3465 CAmount CWallet::GetImmatureBalance() const
3466 {
3467     CAmount nTotal = 0;
3468     {
3469         LOCK2(cs_main, cs_wallet);
3470         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3471         {
3472             const CWalletTx* pcoin = &(*it).second;
3473             nTotal += pcoin->GetImmatureCredit();
3474         }
3475     }
3476     return nTotal;
3477 }
3478
3479 CAmount CWallet::GetImmatureReserveBalance() const
3480 {
3481     CAmount nTotal = 0;
3482     {
3483         LOCK2(cs_main, cs_wallet);
3484         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3485         {
3486             const CWalletTx* pcoin = &(*it).second;
3487             nTotal += pcoin->GetImmatureReserveCredit();
3488         }
3489     }
3490     return nTotal;
3491 }
3492
3493 CAmount CWallet::GetWatchOnlyBalance() const
3494 {
3495     CAmount nTotal = 0;
3496     {
3497         LOCK2(cs_main, cs_wallet);
3498         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3499         {
3500             const CWalletTx* pcoin = &(*it).second;
3501             if (pcoin->IsTrusted())
3502                 nTotal += pcoin->GetAvailableWatchOnlyCredit();
3503         }
3504     }
3505
3506     return nTotal;
3507 }
3508
3509 CAmount CWallet::GetWatchOnlyReserveBalance() const
3510 {
3511     CAmount nTotal = 0;
3512     {
3513         LOCK2(cs_main, cs_wallet);
3514         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3515         {
3516             const CWalletTx* pcoin = &(*it).second;
3517             if (pcoin->IsTrusted())
3518                 nTotal += pcoin->GetAvailableWatchOnlyReserveCredit();
3519         }
3520     }
3521
3522     return nTotal;
3523 }
3524
3525 CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
3526 {
3527     CAmount nTotal = 0;
3528     {
3529         LOCK2(cs_main, cs_wallet);
3530         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3531         {
3532             const CWalletTx* pcoin = &(*it).second;
3533             if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3534                 nTotal += pcoin->GetAvailableWatchOnlyCredit();
3535         }
3536     }
3537     return nTotal;
3538 }
3539
3540 CAmount CWallet::GetUnconfirmedWatchOnlyReserveBalance() const
3541 {
3542     CAmount nTotal = 0;
3543     {
3544         LOCK2(cs_main, cs_wallet);
3545         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3546         {
3547             const CWalletTx* pcoin = &(*it).second;
3548             if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
3549                 nTotal += pcoin->GetAvailableWatchOnlyReserveCredit();
3550         }
3551     }
3552     return nTotal;
3553 }
3554
3555 CAmount CWallet::GetImmatureWatchOnlyBalance() const
3556 {
3557     CAmount nTotal = 0;
3558     {
3559         LOCK2(cs_main, cs_wallet);
3560         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3561         {
3562             const CWalletTx* pcoin = &(*it).second;
3563             nTotal += pcoin->GetImmatureWatchOnlyCredit();
3564         }
3565     }
3566     return nTotal;
3567 }
3568
3569 CAmount CWallet::GetImmatureWatchOnlyReserveBalance() const
3570 {
3571     CAmount nTotal = 0;
3572     {
3573         LOCK2(cs_main, cs_wallet);
3574         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3575         {
3576             const CWalletTx* pcoin = &(*it).second;
3577             nTotal += pcoin->GetImmatureWatchOnlyReserveCredit();
3578         }
3579     }
3580     return nTotal;
3581 }
3582
3583 /**
3584  * populate vCoins with vector of available COutputs.
3585  */
3586 uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
3587 uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight);
3588
3589 void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue, bool fIncludeCoinBase) const
3590 {
3591     uint64_t interest,*ptr;
3592     vCoins.clear();
3593
3594     {
3595         LOCK2(cs_main, cs_wallet);
3596         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3597         {
3598             const uint256& wtxid = it->first;
3599             const CWalletTx* pcoin = &(*it).second;
3600
3601             if (!CheckFinalTx(*pcoin))
3602                 continue;
3603
3604             if (fOnlyConfirmed && !pcoin->IsTrusted())
3605                 continue;
3606
3607             if (pcoin->IsCoinBase() && !fIncludeCoinBase)
3608                 continue;
3609
3610             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
3611                 continue;
3612
3613             int nDepth = pcoin->GetDepthInMainChain();
3614             if (nDepth < 0)
3615                 continue;
3616  
3617             for (int i = 0; i < pcoin->vout.size(); i++)
3618             {
3619                 isminetype mine = IsMine(pcoin->vout[i]);
3620                 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
3621                     !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
3622                     (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
3623                 {
3624                     if ( KOMODO_EXCHANGEWALLET == 0 )
3625                     {
3626                         uint32_t locktime; int32_t txheight; CBlockIndex *tipindex;
3627                         if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.LastTip() != 0 && chainActive.LastTip()->GetHeight() >= 60000 )
3628                         {
3629                             if ( pcoin->vout[i].nValue >= 10*COIN )
3630                             {
3631                                 if ( (tipindex= chainActive.LastTip()) != 0 )
3632                                 {
3633                                     komodo_accrued_interest(&txheight,&locktime,wtxid,i,0,pcoin->vout[i].nValue,(int32_t)tipindex->GetHeight());
3634                                     interest = komodo_interestnew(txheight,pcoin->vout[i].nValue,locktime,tipindex->nTime);
3635                                 } else interest = 0;
3636                                 //interest = komodo_interestnew(chainActive.LastTip()->GetHeight()+1,pcoin->vout[i].nValue,pcoin->nLockTime,chainActive.LastTip()->nTime);
3637                                 if ( interest != 0 )
3638                                 {
3639                                     //printf("wallet nValueRet %.8f += interest %.8f ht.%d lock.%u/%u tip.%u\n",(double)pcoin->vout[i].nValue/COIN,(double)interest/COIN,txheight,locktime,pcoin->nLockTime,tipindex->nTime);
3640                                     //fprintf(stderr,"wallet nValueRet %.8f += interest %.8f ht.%d lock.%u tip.%u\n",(double)pcoin->vout[i].nValue/COIN,(double)interest/COIN,chainActive.LastTip()->GetHeight()+1,pcoin->nLockTime,chainActive.LastTip()->nTime);
3641                                     //ptr = (uint64_t *)&pcoin->vout[i].nValue;
3642                                     //(*ptr) += interest;
3643                                     ptr = (uint64_t *)&pcoin->vout[i].interest;
3644                                     (*ptr) = interest;
3645                                     //pcoin->vout[i].nValue += interest;
3646                                 }
3647                                 else
3648                                 {
3649                                     ptr = (uint64_t *)&pcoin->vout[i].interest;
3650                                     (*ptr) = 0;
3651                                 }
3652                             }
3653                             else
3654                             {
3655                                 ptr = (uint64_t *)&pcoin->vout[i].interest;
3656                                 (*ptr) = 0;
3657                             }
3658                         }
3659                         else
3660                         {
3661                             ptr = (uint64_t *)&pcoin->vout[i].interest;
3662                             (*ptr) = 0;
3663                         }
3664                     }
3665                     vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
3666                 }
3667             }
3668         }
3669     }
3670 }
3671
3672 void CWallet::AvailableReserveCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeCoinBase) const
3673 {
3674     vCoins.clear();
3675
3676     {
3677         LOCK2(cs_main, cs_wallet);
3678         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3679         {
3680             const uint256& wtxid = it->first;
3681             const CWalletTx* pcoin = &(*it).second;
3682
3683             if (!CheckFinalTx(*pcoin))
3684                 continue;
3685
3686             if (fOnlyConfirmed && !pcoin->IsTrusted())
3687                 continue;
3688
3689             if (pcoin->IsCoinBase() && !fIncludeCoinBase)
3690                 continue;
3691
3692             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
3693                 continue;
3694
3695             int nDepth = pcoin->GetDepthInMainChain();
3696             if (nDepth < 0)
3697                 continue;
3698  
3699             for (int i = 0; i < pcoin->vout.size(); i++)
3700             {
3701                 // NOTE: we assume that only zero value outputs can be reserve outputs
3702                 isminetype mine = IsMine(pcoin->vout[i]);
3703                 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
3704                     !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue == 0 &&
3705                     (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
3706                 {
3707                     COptCCParams p;
3708                     if (::IsPayToCryptoCondition(pcoin->vout[i].scriptPubKey, p) && p.IsValid() && p.evalCode == EVAL_RESERVE_OUTPUT)
3709                     {
3710                         vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
3711                     }
3712                 }
3713             }
3714         }
3715     }
3716 }
3717
3718 static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
3719 {
3720     vector<char> vfIncluded;
3721
3722     vfBest.assign(vValue.size(), true);
3723     nBest = nTotalLower;
3724
3725     seed_insecure_rand();
3726
3727     for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
3728     {
3729         vfIncluded.assign(vValue.size(), false);
3730         CAmount nTotal = 0;
3731         bool fReachedTarget = false;
3732         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
3733         {
3734             for (unsigned int i = 0; i < vValue.size(); i++)
3735             {
3736                 //The solver here uses a randomized algorithm,
3737                 //the randomness serves no real security purpose but is just
3738                 //needed to prevent degenerate behavior and it is important
3739                 //that the rng is fast. We do not use a constant random sequence,
3740                 //because there may be some privacy improvement by making
3741                 //the selection random.
3742                 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
3743                 {
3744                     nTotal += vValue[i].first;
3745                     vfIncluded[i] = true;
3746                     if (nTotal >= nTargetValue)
3747                     {
3748                         fReachedTarget = true;
3749                         if (nTotal < nBest)
3750                         {
3751                             nBest = nTotal;
3752                             vfBest = vfIncluded;
3753                         }
3754                         nTotal -= vValue[i].first;
3755                         vfIncluded[i] = false;
3756                     }
3757                 }
3758             }
3759         }
3760     }
3761 }
3762
3763 bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
3764 {
3765     int32_t count = 0; //uint64_t lowest_interest = 0;
3766     setCoinsRet.clear();
3767     //memset(interests,0,sizeof(interests));
3768     nValueRet = 0;
3769     // List of values less than target
3770     pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
3771     coinLowestLarger.first = std::numeric_limits<CAmount>::max();
3772     coinLowestLarger.second.first = NULL;
3773     vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
3774     CAmount nTotalLower = 0;
3775
3776     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
3777
3778     BOOST_FOREACH(const COutput &output, vCoins)
3779     {
3780         if (!output.fSpendable)
3781             continue;
3782
3783         const CWalletTx *pcoin = output.tx;
3784
3785         if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
3786             continue;
3787
3788         int i = output.i;
3789         CAmount n = pcoin->vout[i].nValue;
3790
3791         pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
3792
3793         if (n == nTargetValue)
3794         {
3795             setCoinsRet.insert(coin.second);
3796             nValueRet += coin.first;
3797             //if ( KOMODO_EXCHANGEWALLET == 0 )
3798             //    *interestp += pcoin->vout[i].interest;
3799             return true;
3800         }
3801         else if (n < nTargetValue + CENT)
3802         {
3803             vValue.push_back(coin);
3804             nTotalLower += n;
3805             //if ( KOMODO_EXCHANGEWALLET == 0 && count < sizeof(interests)/sizeof(*interests) )
3806             //{
3807                 //fprintf(stderr,"count.%d %.8f\n",count,(double)pcoin->vout[i].interest/COIN);
3808                 //interests[count++] = pcoin->vout[i].interest;
3809             //}
3810             if ( nTotalLower > 4*nTargetValue + CENT )
3811             {
3812                 //fprintf(stderr,"why bother with all the utxo if we have double what is needed?\n");
3813                 break;
3814             }
3815         }
3816         else if (n < coinLowestLarger.first)
3817         {
3818             coinLowestLarger = coin;
3819             //if ( KOMODO_EXCHANGEWALLET == 0 )
3820             //    lowest_interest = pcoin->vout[i].interest;
3821         }
3822     }
3823
3824     if (nTotalLower == nTargetValue)
3825     {
3826         for (unsigned int i = 0; i < vValue.size(); ++i)
3827         {
3828             setCoinsRet.insert(vValue[i].second);
3829             nValueRet += vValue[i].first;
3830             //if ( KOMODO_EXCHANGEWALLET == 0 && i < count )
3831             //    *interestp += interests[i];
3832         }
3833         return true;
3834     }
3835
3836     if (nTotalLower < nTargetValue)
3837     {
3838         if (coinLowestLarger.second.first == NULL)
3839             return false;
3840         setCoinsRet.insert(coinLowestLarger.second);
3841         nValueRet += coinLowestLarger.first;
3842         //if ( KOMODO_EXCHANGEWALLET == 0 )
3843         //    *interestp += lowest_interest;
3844         return true;
3845     }
3846
3847     // Solve subset sum by stochastic approximation
3848     sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
3849     vector<char> vfBest;
3850     CAmount nBest;
3851
3852     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
3853     if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
3854         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
3855
3856     // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
3857     //                                   or the next bigger coin is closer), return the bigger coin
3858     if (coinLowestLarger.second.first &&
3859         ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
3860     {
3861         setCoinsRet.insert(coinLowestLarger.second);
3862         nValueRet += coinLowestLarger.first;
3863         //if ( KOMODO_EXCHANGEWALLET == 0 )
3864         //    *interestp += lowest_interest;
3865     }
3866     else {
3867         for (unsigned int i = 0; i < vValue.size(); i++)
3868             if (vfBest[i])
3869             {
3870                 setCoinsRet.insert(vValue[i].second);
3871                 nValueRet += vValue[i].first;
3872                 //if ( KOMODO_EXCHANGEWALLET == 0 && i < count )
3873                 //    *interestp += interests[i];
3874             }
3875
3876         LogPrint("selectcoins", "SelectCoins() best subset: ");
3877         for (unsigned int i = 0; i < vValue.size(); i++)
3878             if (vfBest[i])
3879                 LogPrint("selectcoins", "%s", FormatMoney(vValue[i].first));
3880         LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
3881     }
3882
3883     return true;
3884 }
3885
3886 bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet,  bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl) const
3887 {
3888     // Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
3889     uint64_t tmp; int32_t retval;
3890     //if ( interestp == 0 )
3891     //{
3892     //    interestp = &tmp;
3893     //    *interestp = 0;
3894     //}
3895     vector<COutput> vCoinsNoCoinbase, vCoinsWithCoinbase;
3896     AvailableCoins(vCoinsNoCoinbase, true, coinControl, false, false);
3897     AvailableCoins(vCoinsWithCoinbase, true, coinControl, false, true);
3898     fOnlyCoinbaseCoinsRet = vCoinsNoCoinbase.size() == 0 && vCoinsWithCoinbase.size() > 0;
3899
3900     // If coinbase utxos can only be sent to zaddrs, exclude any coinbase utxos from coin selection.
3901     bool fProtectCoinbase = Params().GetConsensus().fCoinbaseMustBeProtected;
3902     vector<COutput> vCoins = (fProtectCoinbase) ? vCoinsNoCoinbase : vCoinsWithCoinbase;
3903
3904     // Output parameter fNeedCoinbaseCoinsRet is set to true if coinbase utxos need to be spent to meet target amount
3905     if (fProtectCoinbase && vCoinsWithCoinbase.size() > vCoinsNoCoinbase.size()) {
3906         CAmount value = 0;
3907         for (const COutput& out : vCoinsNoCoinbase) {
3908             if (!out.fSpendable) {
3909                 continue;
3910             }
3911             value += out.tx->vout[out.i].nValue;
3912             if ( KOMODO_EXCHANGEWALLET == 0 )
3913                 value += out.tx->vout[out.i].interest;
3914         }
3915         if (value <= nTargetValue) {
3916             CAmount valueWithCoinbase = 0;
3917             for (const COutput& out : vCoinsWithCoinbase) {
3918                 if (!out.fSpendable) {
3919                     continue;
3920                 }
3921                 valueWithCoinbase += out.tx->vout[out.i].nValue;
3922                 if ( KOMODO_EXCHANGEWALLET == 0 )
3923                     valueWithCoinbase += out.tx->vout[out.i].interest;
3924             }
3925             fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
3926         }
3927     }
3928     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
3929     if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
3930     {
3931         BOOST_FOREACH(const COutput& out, vCoins)
3932         {
3933             if (!out.fSpendable)
3934                  continue;
3935             nValueRet += out.tx->vout[out.i].nValue;
3936             //if ( KOMODO_EXCHANGEWALLET == 0 )
3937             //    *interestp += out.tx->vout[out.i].interest;
3938             setCoinsRet.insert(make_pair(out.tx, out.i));
3939         }
3940         return (nValueRet >= nTargetValue);
3941     }
3942     // calculate value from preset inputs and store them
3943     set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
3944     CAmount nValueFromPresetInputs = 0;
3945
3946     std::vector<COutPoint> vPresetInputs;
3947     if (coinControl)
3948         coinControl->ListSelected(vPresetInputs);
3949     BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
3950     {
3951         map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
3952         if (it != mapWallet.end())
3953         {
3954             const CWalletTx* pcoin = &it->second;
3955             // Clearly invalid input, fail
3956             if (pcoin->vout.size() <= outpoint.n)
3957                 return false;
3958             nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
3959             if ( KOMODO_EXCHANGEWALLET == 0 )
3960                 nValueFromPresetInputs += pcoin->vout[outpoint.n].interest;
3961             setPresetCoins.insert(make_pair(pcoin, outpoint.n));
3962         } else
3963             return false; // TODO: Allow non-wallet inputs
3964     }
3965
3966     // remove preset inputs from vCoins
3967     for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
3968     {
3969         if (setPresetCoins.count(make_pair(it->tx, it->i)))
3970             it = vCoins.erase(it);
3971         else
3972             ++it;
3973     }
3974     retval = false;
3975     if ( nTargetValue <= nValueFromPresetInputs )
3976         retval = true;
3977     else if ( SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) != 0 )
3978         retval = true;
3979     else if ( SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) != 0 )
3980         retval = true;
3981     else if ( bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet) != 0 )
3982         retval = true;
3983     // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
3984     setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
3985     // add preset inputs to the total value selected
3986     nValueRet += nValueFromPresetInputs;
3987     return retval;
3988 }
3989
3990 bool CWallet::SelectReserveCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
3991 {
3992     int32_t count = 0; //uint64_t lowest_interest = 0;
3993     setCoinsRet.clear();
3994     //memset(interests,0,sizeof(interests));
3995     nValueRet = 0;
3996     // List of values less than target
3997     pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
3998     coinLowestLarger.first = std::numeric_limits<CAmount>::max();
3999     coinLowestLarger.second.first = NULL;
4000     vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
4001     CAmount nTotalLower = 0;
4002
4003     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
4004
4005     BOOST_FOREACH(const COutput &output, vCoins)
4006     {
4007         if (!output.fSpendable)
4008             continue;
4009
4010         const CWalletTx *pcoin = output.tx;
4011
4012         if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
4013             continue;
4014
4015         int i = output.i;
4016         CAmount n = pcoin->vout[i].scriptPubKey.ReserveOutValue();
4017
4018         pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
4019
4020         if (n == nTargetValue)
4021         {
4022             setCoinsRet.insert(coin.second);
4023             nValueRet += coin.first;
4024             //if ( KOMODO_EXCHANGEWALLET == 0 )
4025             //    *interestp += pcoin->vout[i].interest;
4026             return true;
4027         }
4028         else if (n < nTargetValue + CENT)
4029         {
4030             vValue.push_back(coin);
4031             nTotalLower += n;
4032  
4033             if ( nTotalLower > 4*nTargetValue + CENT )
4034             {
4035                 //fprintf(stderr,"why bother with all the utxo if we have double what is needed?\n");
4036                 break;
4037             }
4038         }
4039         else if (n < coinLowestLarger.first)
4040         {
4041             coinLowestLarger = coin;
4042         }
4043     }
4044
4045     if (nTotalLower == nTargetValue)
4046     {
4047         for (unsigned int i = 0; i < vValue.size(); ++i)
4048         {
4049             setCoinsRet.insert(vValue[i].second);
4050             nValueRet += vValue[i].first;
4051         }
4052         return true;
4053     }
4054
4055     if (nTotalLower < nTargetValue)
4056     {
4057         if (coinLowestLarger.second.first == NULL)
4058             return false;
4059         setCoinsRet.insert(coinLowestLarger.second);
4060         nValueRet += coinLowestLarger.first;
4061         return true;
4062     }
4063
4064     // Solve subset sum by stochastic approximation
4065     sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
4066     vector<char> vfBest;
4067     CAmount nBest;
4068
4069     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
4070     if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
4071         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
4072
4073     // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
4074     //                                   or the next bigger coin is closer), return the bigger coin
4075     if (coinLowestLarger.second.first &&
4076         ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
4077     {
4078         setCoinsRet.insert(coinLowestLarger.second);
4079         nValueRet += coinLowestLarger.first;
4080     }
4081     else {
4082         for (unsigned int i = 0; i < vValue.size(); i++)
4083             if (vfBest[i])
4084             {
4085                 setCoinsRet.insert(vValue[i].second);
4086                 nValueRet += vValue[i].first;
4087             }
4088
4089         LogPrint("selectcoins", "SelectCoins() best subset: ");
4090         for (unsigned int i = 0; i < vValue.size(); i++)
4091             if (vfBest[i])
4092                 LogPrint("selectcoins", "%s", FormatMoney(vValue[i].first));
4093         LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
4094     }
4095
4096     return true;
4097 }
4098
4099 bool CWallet::SelectReserveCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet,  bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl) const
4100 {
4101     // Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
4102     uint64_t tmp; int32_t retval;
4103     //if ( interestp == 0 )
4104     //{
4105     //    interestp = &tmp;
4106     //    *interestp = 0;
4107     //}
4108     vector<COutput> vCoinsNoCoinbase, vCoinsWithCoinbase;
4109     AvailableReserveCoins(vCoinsNoCoinbase, true, coinControl, false);
4110     AvailableReserveCoins(vCoinsWithCoinbase, true, coinControl, true);
4111     fOnlyCoinbaseCoinsRet = vCoinsNoCoinbase.size() == 0 && vCoinsWithCoinbase.size() > 0;
4112
4113     // If coinbase utxos can only be sent to zaddrs, exclude any coinbase utxos from coin selection.
4114     bool fProtectCoinbase = Params().GetConsensus().fCoinbaseMustBeProtected;
4115     vector<COutput> vCoins = (fProtectCoinbase) ? vCoinsNoCoinbase : vCoinsWithCoinbase;
4116
4117     // Output parameter fNeedCoinbaseCoinsRet is set to true if coinbase utxos need to be spent to meet target amount
4118     if (fProtectCoinbase && vCoinsWithCoinbase.size() > vCoinsNoCoinbase.size()) {
4119         CAmount value = 0;
4120         for (const COutput& out : vCoinsNoCoinbase) {
4121             if (!out.fSpendable) {
4122                 continue;
4123             }
4124             value += out.tx->vout[out.i].ReserveOutValue();
4125         }
4126         if (value <= nTargetValue) {
4127             CAmount valueWithCoinbase = 0;
4128             for (const COutput& out : vCoinsWithCoinbase) {
4129                 if (!out.fSpendable) {
4130                     continue;
4131                 }
4132                 valueWithCoinbase += out.tx->vout[out.i].ReserveOutValue();
4133             }
4134             fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
4135         }
4136     }
4137     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
4138     if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
4139     {
4140         BOOST_FOREACH(const COutput& out, vCoins)
4141         {
4142             if (!out.fSpendable)
4143                  continue;
4144             nValueRet += out.tx->vout[out.i].ReserveOutValue();
4145             setCoinsRet.insert(make_pair(out.tx, out.i));
4146         }
4147         return (nValueRet >= nTargetValue);
4148     }
4149     // calculate value from preset inputs and store them
4150     set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
4151     CAmount nValueFromPresetInputs = 0;
4152
4153     std::vector<COutPoint> vPresetInputs;
4154     if (coinControl)
4155         coinControl->ListSelected(vPresetInputs);
4156     BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
4157     {
4158         map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
4159         if (it != mapWallet.end())
4160         {
4161             const CWalletTx* pcoin = &it->second;
4162             // Clearly invalid input, fail
4163             if (pcoin->vout.size() <= outpoint.n)
4164                 return false;
4165             nValueFromPresetInputs += pcoin->vout[outpoint.n].ReserveOutValue();
4166             setPresetCoins.insert(make_pair(pcoin, outpoint.n));
4167         } else
4168             return false; // TODO: Allow non-wallet inputs
4169     }
4170
4171     // remove preset inputs from vCoins
4172     for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
4173     {
4174         if (setPresetCoins.count(make_pair(it->tx, it->i)))
4175             it = vCoins.erase(it);
4176         else
4177             ++it;
4178     }
4179     retval = false;
4180     if ( nTargetValue <= nValueFromPresetInputs )
4181         retval = true;
4182     else if ( SelectReserveCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) != 0 )
4183         retval = true;
4184     else if ( SelectReserveCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) != 0 )
4185         retval = true;
4186     else if ( bSpendZeroConfChange && SelectReserveCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet) != 0 )
4187         retval = true;
4188     // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
4189     setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
4190     // add preset inputs to the total value selected
4191     nValueRet += nValueFromPresetInputs;
4192     return retval;
4193 }
4194
4195 bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason)
4196 {
4197     vector<CRecipient> vecSend;
4198
4199     // Turn the txout set into a CRecipient vector
4200     BOOST_FOREACH(const CTxOut& txOut, tx.vout)
4201     {
4202         CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
4203         vecSend.push_back(recipient);
4204     }
4205
4206     CCoinControl coinControl;
4207     coinControl.fAllowOtherInputs = true;
4208     BOOST_FOREACH(const CTxIn& txin, tx.vin)
4209         coinControl.Select(txin.prevout);
4210
4211     CReserveKey reservekey(this);
4212     CWalletTx wtx;
4213
4214     if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
4215         return false;
4216
4217     if (nChangePosRet != -1)
4218         tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
4219
4220     // Add new txins (keeping original txin scriptSig/order)
4221     BOOST_FOREACH(const CTxIn& txin, wtx.vin)
4222     {
4223         bool found = false;
4224         BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
4225         {
4226             if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
4227             {
4228                 found = true;
4229                 break;
4230             }
4231         }
4232         if (!found)
4233             tx.vin.push_back(txin);
4234     }
4235
4236     return true;
4237 }
4238
4239 bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
4240                                 int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
4241 {
4242     uint64_t interest2 = 0; CAmount nValue = 0; unsigned int nSubtractFeeFromAmount = 0;
4243     BOOST_FOREACH (const CRecipient& recipient, vecSend)
4244     {
4245         if (nValue < 0 || recipient.nAmount < 0)
4246         {
4247             strFailReason = _("Transaction amounts must be positive");
4248             return false;
4249         }
4250         nValue += recipient.nAmount;
4251
4252         if (recipient.fSubtractFeeFromAmount)
4253             nSubtractFeeFromAmount++;
4254     }
4255     if (vecSend.empty() || nValue < 0)
4256     {
4257         strFailReason = _("Transaction amounts must be positive");
4258         return false;
4259     }
4260
4261     wtxNew.fTimeReceivedIsTxTime = true;
4262     wtxNew.BindWallet(this);
4263     int nextBlockHeight = chainActive.Height() + 1;
4264
4265     CMutableTransaction txNew = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight);
4266     txNew.nLockTime = (uint32_t)chainActive.LastTip()->nTime + 1; // set to a time close to now
4267
4268     // Activates after Overwinter network upgrade
4269     if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
4270         if (txNew.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){
4271             strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD.");
4272             return false;
4273         }
4274     }
4275
4276     unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
4277     if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
4278         max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
4279     }
4280
4281     // Discourage fee sniping.
4282     //
4283     // However because of a off-by-one-error in previous versions we need to
4284     // neuter it by setting nLockTime to at least one less than nBestHeight.
4285     // Secondly currently propagation of transactions created for block heights
4286     // corresponding to blocks that were just mined may be iffy - transactions
4287     // aren't re-accepted into the mempool - we additionally neuter the code by
4288     // going ten blocks back. Doesn't yet do anything for sniping, but does act
4289     // to shake out wallet bugs like not showing nLockTime'd transactions at
4290     // all.
4291     txNew.nLockTime = std::max(0, chainActive.Height() - 10);
4292
4293     // Secondly occasionally randomly pick a nLockTime even further back, so
4294     // that transactions that are delayed after signing for whatever reason,
4295     // e.g. high-latency mix networks and some CoinJoin implementations, have
4296     // better privacy.
4297     if (GetRandInt(10) == 0)
4298         txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
4299
4300     assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
4301     assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
4302
4303     {
4304         LOCK2(cs_main, cs_wallet);
4305         {
4306             nFeeRet = 0;
4307             while (true)
4308             {
4309                 //interest = 0;
4310                 txNew.vin.clear();
4311                 txNew.vout.clear();
4312                 wtxNew.fFromMe = true;
4313                 nChangePosRet = -1;
4314                 bool fFirst = true;
4315
4316                 CAmount nTotalValue = nValue;
4317                 if (nSubtractFeeFromAmount == 0)
4318                     nTotalValue += nFeeRet;
4319                 double dPriority = 0;
4320                 // vouts to the payees
4321                 BOOST_FOREACH (const CRecipient& recipient, vecSend)
4322                 {
4323                     CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
4324
4325                     if (recipient.fSubtractFeeFromAmount)
4326                     {
4327                         txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
4328
4329                         if (fFirst) // first receiver pays the remainder not divisible by output count
4330                         {
4331                             fFirst = false;
4332                             txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
4333                         }
4334                     }
4335
4336                     if (txout.IsDust(::minRelayTxFee))
4337                     {
4338                         if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
4339                         {
4340                             if (txout.nValue < 0)
4341                                 strFailReason = _("The transaction amount is too small to pay the fee");
4342                             else
4343                                 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4344                         }
4345                         else
4346                             strFailReason = _("Transaction amount too small");
4347                         return false;
4348                     }
4349                     txNew.vout.push_back(txout);
4350                 }
4351
4352                 // Choose coins to use
4353                 set<pair<const CWalletTx*,unsigned int> > setCoins;
4354                 CAmount nValueIn = 0;
4355                 bool fOnlyCoinbaseCoins = false;
4356                 bool fNeedCoinbaseCoins = false;
4357                 interest2 = 0;
4358                 if (!SelectCoins(nTotalValue, setCoins, nValueIn, fOnlyCoinbaseCoins, fNeedCoinbaseCoins, coinControl))
4359                 {
4360                     if (fOnlyCoinbaseCoins && Params().GetConsensus().fCoinbaseMustBeProtected) {
4361                         strFailReason = _("Coinbase funds can only be sent to a zaddr");
4362                     } else if (fNeedCoinbaseCoins) {
4363                         strFailReason = _("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr");
4364                     } else {
4365                         strFailReason = _("Insufficient funds");
4366                     }
4367                     return false;
4368                 }
4369                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
4370                 {
4371                     CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
4372                     //The coin age after the next block (depth+1) is used instead of the current,
4373                     //reflecting an assumption the user would accept a bit more delay for
4374                     //a chance at a free transaction.
4375                     //But mempool inputs might still be in the mempool, so their age stays 0
4376                     //fprintf(stderr,"nCredit %.8f interest %.8f\n",(double)nCredit/COIN,(double)pcoin.first->vout[pcoin.second].interest/COIN);
4377                     if ( KOMODO_EXCHANGEWALLET == 0 && ASSETCHAINS_SYMBOL[0] == 0 )
4378                     {
4379                         interest2 += pcoin.first->vout[pcoin.second].interest;
4380                         //fprintf(stderr,"%.8f ",(double)pcoin.first->vout[pcoin.second].interest/COIN);
4381                     }
4382                     int age = pcoin.first->GetDepthInMainChain();
4383                     if (age != 0)
4384                         age += 1;
4385                     dPriority += (double)nCredit * age;
4386                 }
4387                 //if ( KOMODO_EXCHANGEWALLET != 0 )
4388                 //{
4389                     //fprintf(stderr,"KOMODO_EXCHANGEWALLET disable interest sum %.8f, interest2 %.8f\n",(double)interest/COIN,(double)interest2/COIN);
4390                     //interest = 0; // interest2 also
4391                 //}
4392                 if ( ASSETCHAINS_SYMBOL[0] == 0 && DONATION_PUBKEY.size() == 66 && interest2 > 5000 )
4393                 {
4394                     CScript scriptDonation = CScript() << ParseHex(DONATION_PUBKEY) << OP_CHECKSIG;
4395                     CTxOut newTxOut(interest2,scriptDonation);
4396                     int32_t nDonationPosRet = txNew.vout.size() - 1; // dont change first or last
4397                     vector<CTxOut>::iterator position = txNew.vout.begin()+nDonationPosRet;
4398                     txNew.vout.insert(position, newTxOut);
4399                     interest2 = 0;
4400                 }
4401                 CAmount nChange = (nValueIn - nValue + interest2);
4402 //fprintf(stderr,"wallet change %.8f (%.8f - %.8f) interest2 %.8f total %.8f\n",(double)nChange/COIN,(double)nValueIn/COIN,(double)nValue/COIN,(double)interest2/COIN,(double)nTotalValue/COIN);
4403                 if (nSubtractFeeFromAmount == 0)
4404                     nChange -= nFeeRet;
4405
4406                 if (nChange > 0)
4407                 {
4408                     // Fill a vout to ourself
4409                     // TODO: pass in scriptChange instead of reservekey so
4410                     // change transaction isn't always pay-to-bitcoin-address
4411                     CScript scriptChange;
4412
4413                     // coin control: send change to custom address
4414                     if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
4415                         scriptChange = GetScriptForDestination(coinControl->destChange);
4416
4417                     // no coin control: send change to newly generated address
4418                     else
4419                     {
4420                         // Note: We use a new key here to keep it from being obvious which side is the change.
4421                         //  The drawback is that by not reusing a previous key, the change may be lost if a
4422                         //  backup is restored, if the backup doesn't have the new private key for the change.
4423                         //  If we reused the old key, it would be possible to add code to look for and
4424                         //  rediscover unknown transactions that were written with keys of ours to recover
4425                         //  post-backup change.
4426
4427                         // Reserve a new key pair from key pool
4428                         CPubKey vchPubKey;
4429                         extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY;
4430                         if ( USE_EXTERNAL_PUBKEY == 0 )
4431                         {
4432                             bool ret;
4433                             ret = reservekey.GetReservedKey(vchPubKey);
4434                             assert(ret); // should never fail, as we just unlocked
4435                             scriptChange = GetScriptForDestination(vchPubKey.GetID());
4436                         }
4437                         else
4438                         {
4439                             //fprintf(stderr,"use notary pubkey\n");
4440                             scriptChange = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
4441                         }
4442                     }
4443
4444                     CTxOut newTxOut(nChange, scriptChange);
4445
4446                     // We do not move dust-change to fees, because the sender would end up paying more than requested.
4447                     // This would be against the purpose of the all-inclusive feature.
4448                     // So instead we raise the change and deduct from the recipient.
4449                     if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
4450                     {
4451                         CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
4452                         newTxOut.nValue += nDust; // raise change until no more dust
4453                         for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
4454                         {
4455                             if (vecSend[i].fSubtractFeeFromAmount)
4456                             {
4457                                 txNew.vout[i].nValue -= nDust;
4458                                 if (txNew.vout[i].IsDust(::minRelayTxFee))
4459                                 {
4460                                     strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4461                                     return false;
4462                                 }
4463                                 break;
4464                             }
4465                         }
4466                     }
4467
4468                     // Never create dust outputs; if we would, just
4469                     // add the dust to the fee.
4470                     if (newTxOut.IsDust(::minRelayTxFee))
4471                     {
4472                         nFeeRet += nChange;
4473                         reservekey.ReturnKey();
4474                     }
4475                     else
4476                     {
4477                         nChangePosRet = txNew.vout.size() - 1; // dont change first or last
4478                         vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
4479                         txNew.vout.insert(position, newTxOut);
4480                     }
4481                 } else reservekey.ReturnKey();
4482
4483                 // Fill vin
4484                 //
4485                 // Note how the sequence number is set to max()-1 so that the
4486                 // nLockTime set above actually works.
4487                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
4488                     txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
4489                                               std::numeric_limits<unsigned int>::max()-1));
4490
4491                 // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
4492                 size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
4493                 {
4494                     LOCK(cs_main);
4495                     if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
4496                         limit = 0;
4497                     }
4498                 }
4499                 if (limit > 0) {
4500                     size_t n = txNew.vin.size();
4501                     if (n > limit) {
4502                         strFailReason = _(strprintf("Too many transparent inputs %zu > limit %zu", n, limit).c_str());
4503                         return false;
4504                     }
4505                 }
4506
4507                 // Grab the current consensus branch ID
4508                 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
4509
4510                 // Sign
4511                 int nIn = 0;
4512                 CTransaction txNewConst(txNew);
4513                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
4514                 {
4515                     bool signSuccess;
4516                     const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
4517                     SignatureData sigdata;
4518                     if (sign)
4519                         signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
4520                     else
4521                         signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
4522
4523                     if (!signSuccess)
4524                     {
4525                         strFailReason = _("Signing transaction failed");
4526                         return false;
4527                     } else {
4528                         UpdateTransaction(txNew, nIn, sigdata);
4529                     }
4530
4531                     nIn++;
4532                 }
4533
4534                 unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
4535
4536                 // Remove scriptSigs if we used dummy signatures for fee calculation
4537                 if (!sign) {
4538                     BOOST_FOREACH (CTxIn& vin, txNew.vin)
4539                         vin.scriptSig = CScript();
4540                 }
4541
4542                 // Embed the constructed transaction data in wtxNew.
4543                 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
4544
4545                 // Limit size
4546                 if (nBytes >= max_tx_size)
4547                 {
4548                     strFailReason = _("Transaction too large");
4549                     return false;
4550                 }
4551
4552                 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
4553
4554                 // Can we complete this as a free transaction?
4555                 if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
4556                 {
4557                     // Not enough fee: enough priority?
4558                     double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
4559                     // Not enough mempool history to estimate: use hard-coded AllowFree.
4560                     if (dPriorityNeeded <= 0 && AllowFree(dPriority))
4561                         break;
4562
4563                     // Small enough, and priority high enough, to send for free
4564                     if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
4565                         break;
4566                 }
4567
4568                 CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
4569                 if ( nFeeNeeded < 5000 )
4570                     nFeeNeeded = 5000;
4571
4572                 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
4573                 // because we must be at the maximum allowed fee.
4574                 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
4575                 {
4576                     strFailReason = _("Transaction too large for fee policy");
4577                     return false;
4578                 }
4579
4580                 if (nFeeRet >= nFeeNeeded)
4581                     break; // Done, enough fee included.
4582
4583                 // Include more fee and try again.
4584                 nFeeRet = nFeeNeeded;
4585                 continue;
4586             }
4587         }
4588     }
4589
4590     return true;
4591 }
4592
4593 CAmount ConvertReserveAmount(CAmount inAmount, CAmount reservePrice)
4594 {
4595     arith_uint256 satoshiden(100000000);
4596     arith_uint256 bigAmount(inAmount);
4597     arith_uint256 bigPrice(reservePrice);
4598     return ((bigAmount * bigPrice) / satoshiden).GetLow64();
4599 }
4600
4601 // almost the same as CreateTransaction with the difference being that input and output are assumed to be the
4602 // reserve currency of this chain, represented as reserve outputs for both input and output. That means that all
4603 // outputs must be reserve consuming outputs. Fee converted from reserve, which is the difference between reserve
4604 // input and reserve output, is calculated based on the current reserve conversion price.
4605 bool CWallet::CreateReserveTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
4606                                        int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
4607 {
4608     CAmount nValue = 0; 
4609     unsigned int nSubtractFeeFromAmount = 0;
4610
4611     // reserve transactions can only be created on fractional reserve currency blockchains
4612     if (IsVerusActive())
4613     {
4614         strFailReason = _("Transactions that accept reserve currency input can only be created on PBaaS blockchains");
4615         return false;
4616     }
4617
4618     // make sure that there are recipients, all recipients expect reserve inputs, and amounts are all non-negative
4619     BOOST_FOREACH (const CRecipient& recipient, vecSend)
4620     {
4621         COptCCParams p;
4622         CReserveOutput ro;
4623         if (recipient.scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid() && p.vData.size() > 0)
4624         {
4625             switch (p.evalCode)
4626             {
4627                 case EVAL_RESERVE_OUTPUT:
4628                 {
4629                     ro = CReserveOutput(p.vData[0]);
4630                     if (!ro.IsValid())
4631                     {
4632                         strFailReason = _("Invalid reserve output");
4633                         return false;
4634                     }
4635                     break;
4636                 }
4637                 case EVAL_RESERVE_TRANSFER:
4638                 {
4639                     CReserveTransfer rt(p.vData[0]);
4640                     if (!rt.IsValid())
4641                     {
4642                         strFailReason = _("Invalid reserve transfer");
4643                         return false;
4644                     }
4645                     // conversion on a PBaaS reserve chain implies native input
4646                     if (rt.flags & CReserveTransfer::CONVERT)
4647                     {
4648                         strFailReason = _(("Reserve transaction outputs created using " + std::string( __func__) + " must have no native output value").c_str());
4649                         return false;
4650                     }
4651                     ro = static_cast<CReserveOutput>(rt);
4652                     break;
4653                 }
4654                 case EVAL_RESERVE_EXCHANGE:
4655                 {
4656                     CReserveExchange re(p.vData[0]);
4657                     if (!re.IsValid())
4658                     {
4659                         strFailReason = _("Invalid reserve exchange");
4660                         return false;
4661                     }
4662                     // conversion to reserve implies native input
4663                     if (re.flags & CReserveExchange::TO_RESERVE)
4664                     {
4665                         strFailReason = _(("Reserve transaction outputs created using " + std::string( __func__) + " must have no native output value").c_str());
4666                         return false;
4667                     }
4668                     ro = static_cast<CReserveOutput>(re);
4669                     break;
4670                 }
4671                 default:
4672                 {
4673                     strFailReason = _("All reserve transaction outputs must accommodate reserve currency input");
4674                     return false;
4675                 }
4676             }
4677         }
4678         else if (!recipient.scriptPubKey.IsOpReturn() || recipient.nAmount != 0)
4679         {
4680             strFailReason = _(("Reserve transaction outputs created using " + std::string( __func__) + " must have no native output value").c_str());
4681             return false;
4682         }
4683
4684         if (ro.IsValid())
4685         {
4686             nValue += ro.nValue;
4687         }
4688
4689         if (ro.nValue < 0 || nValue < 0 || recipient.nAmount < 0)
4690         {
4691             strFailReason = _("Transaction amounts must not be negative");
4692             return false;
4693         }
4694
4695         if (recipient.fSubtractFeeFromAmount)
4696             nSubtractFeeFromAmount++;
4697     }
4698
4699     if (vecSend.empty() || nValue < 0)
4700     {
4701         strFailReason = _("Transaction amounts must not be negative");
4702         return false;
4703     }
4704
4705     wtxNew.fTimeReceivedIsTxTime = true;
4706     wtxNew.BindWallet(this);
4707     int nextBlockHeight = chainActive.Height() + 1;
4708     CMutableTransaction txNew = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight);
4709     txNew.nLockTime = (uint32_t)chainActive.LastTip()->nTime + 1; // set to a time close to now
4710
4711     if (txNew.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){
4712         strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD.");
4713         return false;
4714     }
4715
4716     unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
4717
4718     // Discourage fee sniping.
4719     //
4720     // However because of a off-by-one-error in previous versions we need to
4721     // neuter it by setting nLockTime to at least one less than nBestHeight.
4722     // Secondly currently propagation of transactions created for block heights
4723     // corresponding to blocks that were just mined may be iffy - transactions
4724     // aren't re-accepted into the mempool - we additionally neuter the code by
4725     // going ten blocks back. Doesn't yet do anything for sniping, but does act
4726     // to shake out wallet bugs like not showing nLockTime'd transactions at
4727     // all.
4728     txNew.nLockTime = std::max(0, chainActive.Height() - 10);
4729
4730     // Secondly occasionally randomly pick a nLockTime even further back, so
4731     // that transactions that are delayed after signing for whatever reason,
4732     // e.g. high-latency mix networks and some CoinJoin implementations, have
4733     // better privacy.
4734     if (GetRandInt(10) == 0)
4735         txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
4736
4737     assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
4738     assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
4739
4740     {
4741         LOCK2(cs_main, cs_wallet);
4742         {
4743             nFeeRet = 0;
4744             while (true)
4745             {
4746                 //interest = 0;
4747                 txNew.vin.clear();
4748                 txNew.vout.clear();
4749                 wtxNew.fFromMe = true;
4750                 nChangePosRet = -1;
4751                 bool fFirst = true;
4752
4753                 // TODO: keep this up to date with connect block and coinbase transaction rule
4754                 CCurrencyState curReserveState;
4755
4756                 cpp_dec_float_50 priceInReserve = curReserveState.GetPriceInReserve();
4757                 CAmount reservePrice;
4758                 if (!CCurrencyState::to_int64(priceInReserve, reservePrice))
4759                 {
4760                     strFailReason = _("Invalid fractional reserve price");
4761                     return false;
4762                 }
4763
4764                 // dust threshold of reserve is different than native coin, convert
4765                 CAmount dustThreshold;
4766
4767                 CAmount nTotalValue = nValue;
4768                 if (nSubtractFeeFromAmount == 0)
4769                     nTotalValue += nFeeRet;
4770                 double dPriority = 0;
4771                 // vouts to the payees
4772                 BOOST_FOREACH (const CRecipient& recipient, vecSend)
4773                 {
4774                     // native output value for a reserve output is generally 0. fees are paid by converting from
4775                     // reserve token and the difference between input and output in reserve is the fee
4776                     // the actual reserve token output value is in the scriptPubKey as extended CC information
4777                     CTxOut txout(0, recipient.scriptPubKey);
4778
4779                     // here, if we know that it isn't an opret, it will have an output that expects reserve input
4780                     if (!recipient.scriptPubKey.IsOpReturn())
4781                     {
4782                         COptCCParams p;
4783
4784                         // already validated above
4785                         txout.scriptPubKey.IsPayToCryptoCondition(p);
4786
4787                         CAmount newVal = 0;
4788                         CReserveOutput ro;
4789                         CReserveTransfer rt;
4790                         CReserveExchange re;
4791
4792                         switch (p.evalCode)
4793                         {
4794                             case EVAL_RESERVE_OUTPUT:
4795                             {
4796                                 ro = CReserveOutput(p.vData[0]);
4797                                 newVal = ro.nValue;
4798                                 break;
4799                             }
4800                             case EVAL_RESERVE_TRANSFER:
4801                             {
4802                                 rt = CReserveTransfer(p.vData[0]);
4803                                 newVal = rt.nValue;
4804                                 break;
4805                             }
4806                             case EVAL_RESERVE_EXCHANGE:
4807                             {
4808                                 re = CReserveExchange(p.vData[0]);
4809                                 newVal = re.nValue;
4810                                 break;
4811                             }
4812                             default:
4813                                 strFailReason = _("Bad reserve output");
4814                                 return false;
4815                         }
4816
4817                         if (recipient.fSubtractFeeFromAmount)
4818                         {
4819                             CAmount subFee = nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
4820
4821                             if (fFirst) // first receiver pays the remainder not divisible by output count
4822                             {
4823                                 fFirst = false;
4824                                 subFee += nFeeRet % nSubtractFeeFromAmount;
4825                             }
4826
4827                             switch (p.evalCode)
4828                             {
4829                                 case EVAL_RESERVE_OUTPUT:
4830                                 {
4831                                     ro.nValue -= subFee;
4832                                     newVal = ro.nValue;
4833                                     p.vData[0] = ro.AsVector();
4834                                     break;
4835                                 }
4836                                 case EVAL_RESERVE_TRANSFER:
4837                                 {
4838                                     rt.nValue -= subFee;
4839                                     newVal = rt.nValue;
4840                                     p.vData[0] = rt.AsVector();
4841                                     break;
4842                                 }
4843                                 case EVAL_RESERVE_EXCHANGE:
4844                                 {
4845                                     re.nValue -= subFee;
4846                                     newVal = re.nValue;
4847                                     p.vData[0] = re.AsVector();
4848                                     break;
4849                                 }
4850                                 default:
4851                                     strFailReason = _("Bad reserve output");
4852                                     return false;
4853                             }
4854
4855                             txout.scriptPubKey = txout.scriptPubKey.ReplaceCCParams(p);
4856                         }
4857
4858                         dustThreshold = txout.GetDustThreshold(::minRelayTxFee);
4859
4860                         if (newVal < dustThreshold)
4861                         {
4862                             if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
4863                             {
4864                                 if (newVal < 0)
4865                                     strFailReason = _("The transaction amount is too small to pay the fee");
4866                                 else
4867                                     strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4868                             }
4869                             else
4870                                 strFailReason = _("Transaction amount too small");
4871                             return false;
4872                         }
4873                     }
4874
4875                     txNew.vout.push_back(txout);
4876                 }
4877
4878                 // Choose coins to use
4879                 set<pair<const CWalletTx*,unsigned int> > setCoins;
4880                 CAmount nValueIn = 0;
4881                 bool fOnlyCoinbaseCoins = false;
4882                 bool fNeedCoinbaseCoins = false;
4883
4884                 if (!SelectReserveCoins(nTotalValue, setCoins, nValueIn, fOnlyCoinbaseCoins, fNeedCoinbaseCoins, coinControl))
4885                 {
4886                     if (fOnlyCoinbaseCoins && Params().GetConsensus().fCoinbaseMustBeProtected) {
4887                         strFailReason = _("Coinbase funds can only be sent to a zaddr");
4888                     } else if (fNeedCoinbaseCoins) {
4889                         strFailReason = _("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr");
4890                     } else {
4891                         strFailReason = _("Insufficient funds");
4892                     }
4893                     return false;
4894                 }
4895                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
4896                 {
4897                     CAmount nCredit = pcoin.first->vout[pcoin.second].ReserveOutValue();
4898                     //The coin age after the next block (depth+1) is used instead of the current,
4899                     //reflecting an assumption the user would accept a bit more delay for
4900                     //a chance at a free transaction.
4901                     //But mempool inputs might still be in the mempool, so their age stays 0
4902                     int age = pcoin.first->GetDepthInMainChain();
4903                     if (age != 0)
4904                         age += 1;
4905                     dPriority += (double)nCredit * age;
4906                 }
4907
4908                 CAmount nChange = (nValueIn - nValue);
4909
4910                 if (nSubtractFeeFromAmount == 0)
4911                     nChange -= nFeeRet;
4912
4913                 if (nChange > 0)
4914                 {
4915                     // Fill a vout to ourself
4916                     CPubKey vchPubKey;
4917
4918                     // coin control: send change to custom address
4919
4920                     // reserve tokens can currently only be sent to public keys or addresses that are in the current wallet
4921                     // since reserve token outputs are CCs by definition
4922                     if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
4923                     {
4924                         if (!boost::get<CPubKey>(&coinControl->destChange))
4925                         {
4926                             strFailReason = _("Change address must be public key");
4927                             return false;
4928                         }
4929                         vchPubKey = *(boost::get<CPubKey>(&coinControl->destChange));
4930                     }
4931                     else
4932                     {
4933                         // no coin control: send change to newly generated address
4934
4935                         // Note: We use a new key here to keep it from being obvious which side is the change.
4936                         //  The drawback is that by not reusing a previous key, the change may be lost if a
4937                         //  backup is restored, if the backup doesn't have the new private key for the change.
4938                         //  If we reused the old key, it would be possible to add code to look for and
4939                         //  rediscover unknown transactions that were written with keys of ours to recover
4940                         //  post-backup change.
4941
4942                         // Reserve a new key pair from key pool
4943                         extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY;
4944                         if ( USE_EXTERNAL_PUBKEY == 0 )
4945                         {
4946                             bool ret;
4947                             ret = reservekey.GetReservedKey(vchPubKey);
4948                             assert(ret); // should never fail, as we just unlocked
4949                         }
4950                         else
4951                         {
4952                             //fprintf(stderr,"use notary pubkey\n");
4953                             vchPubKey = CPubKey(ParseHex(NOTARY_PUBKEY));
4954                         }
4955                     }
4956
4957                     // we will send using a reserve output, fee will be paid by converting from reserve
4958                     CCcontract_info CC;
4959                     CCcontract_info *cp;
4960                     cp = CCinit(&CC, EVAL_RESERVE_OUTPUT);
4961
4962                     std::vector<CTxDestination> dests = std::vector<CTxDestination>({vchPubKey.GetID()});
4963
4964                     // create the transfer object
4965                     CReserveOutput ro(CReserveOutput::VALID, nChange);
4966
4967                     // We do not move dust-change to fees, because the sender would end up paying more than requested.
4968                     // This would be against the purpose of the all-inclusive feature.
4969                     // So instead we raise the change and deduct from the recipient.
4970
4971                     // adjust the output amount if possible
4972                     if (nSubtractFeeFromAmount > 0 && ro.nValue < dustThreshold)
4973                     {
4974                         CAmount nDust = dustThreshold - ro.nValue;
4975
4976                         ro.nValue += nDust; // raise change until no more dust
4977
4978                         for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
4979                         {
4980                             if (vecSend[i].fSubtractFeeFromAmount)
4981                             {
4982                                 CAmount nValue = txNew.vout[i].ReserveOutValue() - nDust;
4983                                 if (nValue < dustThreshold)
4984                                 {
4985                                     strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
4986                                     return false;
4987                                 }
4988                                 txNew.vout[i].SetReserveOutValue(nValue);
4989                                 break;
4990                             }
4991                         }
4992                     }
4993
4994                     // native amount in the output should be 0
4995                     CTxOut newTxOut = MakeCC1of1Vout(EVAL_RESERVE_OUTPUT, 0, vchPubKey, dests, ro);
4996
4997                     // Never create reserve dust outputs; if we would, just
4998                     // add the dust to the fee.
4999                     if (ro.nValue < newTxOut.GetDustThreshold(::minRelayTxFee))
5000                     {
5001                         nFeeRet += nChange;
5002                         reservekey.ReturnKey();
5003                     }
5004                     else
5005                     {
5006                         nChangePosRet = txNew.vout.size() - 1; // dont change first or last
5007                         vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
5008                         txNew.vout.insert(position, newTxOut);
5009                     }
5010                 } else reservekey.ReturnKey();
5011
5012                 // Fill vin
5013                 //
5014                 // Note how the sequence number is set to max()-1 so that the
5015                 // nLockTime set above actually works.
5016                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
5017                     txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
5018                                               std::numeric_limits<unsigned int>::max()-1));
5019
5020                 // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
5021                 size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
5022                 {
5023                     LOCK(cs_main);
5024                     if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
5025                         limit = 0;
5026                     }
5027                 }
5028                 if (limit > 0) {
5029                     size_t n = txNew.vin.size();
5030                     if (n > limit) {
5031                         strFailReason = _(strprintf("Too many transparent inputs %zu > limit %zu", n, limit).c_str());
5032                         return false;
5033                     }
5034                 }
5035
5036                 // Grab the current consensus branch ID
5037                 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
5038
5039                 // Sign
5040                 int nIn = 0;
5041                 CTransaction txNewConst(txNew);
5042                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
5043                 {
5044                     bool signSuccess;
5045                     const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
5046                     SignatureData sigdata;
5047                     if (sign)
5048                         signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
5049                     else
5050                         signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
5051
5052                     if (!signSuccess)
5053                     {
5054                         strFailReason = _("Signing transaction failed");
5055                         return false;
5056                     } else {
5057                         UpdateTransaction(txNew, nIn, sigdata);
5058                     }
5059
5060                     nIn++;
5061                 }
5062
5063                 unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
5064
5065                 // Remove scriptSigs if we used dummy signatures for fee calculation
5066                 if (!sign) {
5067                     BOOST_FOREACH (CTxIn& vin, txNew.vin)
5068                         vin.scriptSig = CScript();
5069                 }
5070
5071                 // Embed the constructed transaction data in wtxNew.
5072                 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
5073
5074                 // Limit size
5075                 if (nBytes >= max_tx_size)
5076                 {
5077                     strFailReason = _("Transaction too large");
5078                     return false;
5079                 }
5080
5081                 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
5082
5083                 // Can we complete this as a free transaction?
5084                 if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
5085                 {
5086                     // Not enough fee: enough priority?
5087                     double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
5088                     // Not enough mempool history to estimate: use hard-coded AllowFree.
5089                     if (dPriorityNeeded <= 0 && AllowFree(dPriority))
5090                         break;
5091
5092                     // Small enough, and priority high enough, to send for free
5093                     if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
5094                         break;
5095                 }
5096
5097                 CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
5098                 if ( nFeeNeeded < 5000 )
5099                     nFeeNeeded = 5000;
5100
5101                 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
5102                 // because we must be at the maximum allowed fee.
5103                 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
5104                 {
5105                     strFailReason = _("Transaction too large for fee policy");
5106                     return false;
5107                 }
5108
5109                 if (nFeeRet >= nFeeNeeded)
5110                     break; // Done, enough fee included.
5111
5112                 // Include more fee and try again.
5113                 nFeeRet = nFeeNeeded;
5114                 continue;
5115             }
5116         }
5117     }
5118
5119     return true;
5120 }
5121
5122 /**
5123  * Call after CreateTransaction unless you want to abort
5124  */
5125 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
5126 {
5127     {
5128         LOCK2(cs_main, cs_wallet);
5129         LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
5130         {
5131             // This is only to keep the database open to defeat the auto-flush for the
5132             // duration of this scope.  This is the only place where this optimization
5133             // maybe makes sense; please don't do it anywhere else.
5134             CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
5135
5136             // Take key pair from key pool so it won't be used again
5137             reservekey.KeepKey();
5138
5139             // Add tx to wallet, because if it has change it's also ours,
5140             // otherwise just for transaction history.
5141             AddToWallet(wtxNew, false, pwalletdb);
5142
5143             // Notify that old coins are spent
5144             set<CWalletTx*> setCoins;
5145             BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
5146             {
5147                 CWalletTx &coin = mapWallet[txin.prevout.hash];
5148                 coin.BindWallet(this);
5149                 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
5150             }
5151
5152             if (fFileBacked)
5153                 delete pwalletdb;
5154         }
5155
5156         // Track how many getdata requests our transaction gets
5157         mapRequestCount[wtxNew.GetHash()] = 0;
5158
5159         if (fBroadcastTransactions)
5160         {
5161             // Broadcast
5162             if (!wtxNew.AcceptToMemoryPool(false))
5163             {
5164                 fprintf(stderr,"commit failed\n");
5165                 // This must not fail. The transaction has already been signed and recorded.
5166                 LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
5167                 return false;
5168             }
5169             wtxNew.RelayWalletTransaction();
5170         }
5171     }
5172     return true;
5173 }
5174
5175 CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
5176 {
5177     // payTxFee is user-set "I want to pay this much"
5178     CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
5179     // user selected total at least (default=true)
5180     if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
5181         nFeeNeeded = payTxFee.GetFeePerK();
5182     // User didn't set: use -txconfirmtarget to estimate...
5183     if (nFeeNeeded == 0)
5184         nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
5185     // ... unless we don't have enough mempool data, in which case fall
5186     // back to a hard-coded fee
5187     if (nFeeNeeded == 0)
5188         nFeeNeeded = minTxFee.GetFee(nTxBytes);
5189     // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
5190     if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
5191         nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
5192     // But always obey the maximum
5193     if (nFeeNeeded > maxTxFee)
5194         nFeeNeeded = maxTxFee;
5195     return nFeeNeeded;
5196 }
5197
5198
5199 void komodo_prefetch(FILE *fp);
5200
5201 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
5202 {
5203     if (!fFileBacked)
5204         return DB_LOAD_OK;
5205     fFirstRunRet = false;
5206     if ( 0 ) // doesnt help
5207     {
5208         fprintf(stderr,"loading wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
5209         FILE *fp;
5210         if ( (fp= fopen(strWalletFile.c_str(),"rb")) != 0 )
5211         {
5212             komodo_prefetch(fp);
5213             fclose(fp);
5214         }
5215     }
5216     //fprintf(stderr,"prefetched wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
5217     DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
5218     //fprintf(stderr,"loaded wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
5219     if (nLoadWalletRet == DB_NEED_REWRITE)
5220     {
5221         if (CDB::Rewrite(strWalletFile, "\x04pool"))
5222         {
5223             LOCK(cs_wallet);
5224             setKeyPool.clear();
5225             // Note: can't top-up keypool here, because wallet is locked.
5226             // User will be prompted to unlock wallet the next operation
5227             // that requires a new key.
5228         }
5229     }
5230
5231     if (nLoadWalletRet != DB_LOAD_OK)
5232         return nLoadWalletRet;
5233     fFirstRunRet = !vchDefaultKey.IsValid();
5234
5235     uiInterface.LoadWallet(this);
5236
5237     return DB_LOAD_OK;
5238 }
5239
5240
5241 DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
5242 {
5243     if (!fFileBacked)
5244         return DB_LOAD_OK;
5245     DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
5246     if (nZapWalletTxRet == DB_NEED_REWRITE)
5247     {
5248         if (CDB::Rewrite(strWalletFile, "\x04pool"))
5249         {
5250             LOCK(cs_wallet);
5251             setKeyPool.clear();
5252             // Note: can't top-up keypool here, because wallet is locked.
5253             // User will be prompted to unlock wallet the next operation
5254             // that requires a new key.
5255         }
5256     }
5257
5258     if (nZapWalletTxRet != DB_LOAD_OK)
5259         return nZapWalletTxRet;
5260
5261     return DB_LOAD_OK;
5262 }
5263
5264
5265 bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
5266 {
5267     bool fUpdated = false;
5268     {
5269         LOCK(cs_wallet); // mapAddressBook
5270         std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
5271         fUpdated = mi != mapAddressBook.end();
5272         mapAddressBook[address].name = strName;
5273         if (!strPurpose.empty()) /* update purpose only if requested */
5274             mapAddressBook[address].purpose = strPurpose;
5275     }
5276     NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
5277                              strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
5278     if (!fFileBacked)
5279         return false;
5280     if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(EncodeDestination(address), strPurpose))
5281         return false;
5282     return CWalletDB(strWalletFile).WriteName(EncodeDestination(address), strName);
5283 }
5284
5285 bool CWallet::DelAddressBook(const CTxDestination& address)
5286 {
5287     {
5288         LOCK(cs_wallet); // mapAddressBook
5289
5290         if(fFileBacked)
5291         {
5292             // Delete destdata tuples associated with address
5293             std::string strAddress = EncodeDestination(address);
5294             BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
5295             {
5296                 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
5297             }
5298         }
5299         mapAddressBook.erase(address);
5300     }
5301
5302     NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
5303
5304     if (!fFileBacked)
5305         return false;
5306     CWalletDB(strWalletFile).ErasePurpose(EncodeDestination(address));
5307     return CWalletDB(strWalletFile).EraseName(EncodeDestination(address));
5308 }
5309
5310 bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
5311 {
5312     if (fFileBacked)
5313     {
5314         if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
5315             return false;
5316     }
5317     vchDefaultKey = vchPubKey;
5318     return true;
5319 }
5320
5321 /**
5322  * Mark old keypool keys as used,
5323  * and generate all new keys
5324  */
5325 bool CWallet::NewKeyPool()
5326 {
5327     {
5328         LOCK(cs_wallet);
5329         CWalletDB walletdb(strWalletFile);
5330         BOOST_FOREACH(int64_t nIndex, setKeyPool)
5331             walletdb.ErasePool(nIndex);
5332         setKeyPool.clear();
5333
5334         if (IsLocked())
5335             return false;
5336
5337         int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
5338         for (int i = 0; i < nKeys; i++)
5339         {
5340             int64_t nIndex = i+1;
5341             walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
5342             setKeyPool.insert(nIndex);
5343         }
5344         LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
5345     }
5346     return true;
5347 }
5348
5349 bool CWallet::TopUpKeyPool(unsigned int kpSize)
5350 {
5351     {
5352         LOCK(cs_wallet);
5353
5354         if (IsLocked())
5355             return false;
5356
5357         CWalletDB walletdb(strWalletFile);
5358
5359         // Top up key pool
5360         unsigned int nTargetSize;
5361         if (kpSize > 0)
5362             nTargetSize = kpSize;
5363         else
5364             nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
5365
5366         while (setKeyPool.size() < (nTargetSize + 1))
5367         {
5368             int64_t nEnd = 1;
5369             if (!setKeyPool.empty())
5370                 nEnd = *(--setKeyPool.end()) + 1;
5371             if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
5372                 throw runtime_error("TopUpKeyPool(): writing generated key failed");
5373             setKeyPool.insert(nEnd);
5374             LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
5375         }
5376     }
5377     return true;
5378 }
5379
5380 void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
5381 {
5382     nIndex = -1;
5383     keypool.vchPubKey = CPubKey();
5384     {
5385         LOCK(cs_wallet);
5386
5387         if (!IsLocked())
5388             TopUpKeyPool();
5389
5390         // Get the oldest key
5391         if(setKeyPool.empty())
5392             return;
5393
5394         CWalletDB walletdb(strWalletFile);
5395
5396         nIndex = *(setKeyPool.begin());
5397         setKeyPool.erase(setKeyPool.begin());
5398         if (!walletdb.ReadPool(nIndex, keypool))
5399             throw runtime_error("ReserveKeyFromKeyPool(): read failed");
5400         if (!HaveKey(keypool.vchPubKey.GetID()))
5401             throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
5402         assert(keypool.vchPubKey.IsValid());
5403         //LogPrintf("keypool reserve %d\n", nIndex);
5404     }
5405 }
5406
5407 void CWallet::KeepKey(int64_t nIndex)
5408 {
5409     // Remove from key pool
5410     if (fFileBacked)
5411     {
5412         CWalletDB walletdb(strWalletFile);
5413         walletdb.ErasePool(nIndex);
5414     }
5415     LogPrintf("keypool keep %d\n", nIndex);
5416 }
5417
5418 void CWallet::ReturnKey(int64_t nIndex)
5419 {
5420     // Return to key pool
5421     {
5422         LOCK(cs_wallet);
5423         setKeyPool.insert(nIndex);
5424     }
5425     //LogPrintf("keypool return %d\n", nIndex);
5426 }
5427
5428 bool CWallet::GetKeyFromPool(CPubKey& result)
5429 {
5430     int64_t nIndex = 0;
5431     CKeyPool keypool;
5432     {
5433         LOCK(cs_wallet);
5434         ReserveKeyFromKeyPool(nIndex, keypool);
5435         if (nIndex == -1)
5436         {
5437             if (IsLocked()) return false;
5438             result = GenerateNewKey();
5439             return true;
5440         }
5441         KeepKey(nIndex);
5442         result = keypool.vchPubKey;
5443     }
5444     return true;
5445 }
5446
5447 int64_t CWallet::GetOldestKeyPoolTime()
5448 {
5449     int64_t nIndex = 0;
5450     CKeyPool keypool;
5451     ReserveKeyFromKeyPool(nIndex, keypool);
5452     if (nIndex == -1)
5453         return GetTime();
5454     ReturnKey(nIndex);
5455     return keypool.nTime;
5456 }
5457
5458 std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
5459 {
5460     map<CTxDestination, CAmount> balances;
5461
5462     {
5463         LOCK(cs_wallet);
5464         BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
5465         {
5466             CWalletTx *pcoin = &walletEntry.second;
5467
5468             if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted())
5469                 continue;
5470
5471             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
5472                 continue;
5473
5474             int nDepth = pcoin->GetDepthInMainChain();
5475             if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
5476                 continue;
5477
5478             for (unsigned int i = 0; i < pcoin->vout.size(); i++)
5479             {
5480                 CTxDestination addr;
5481                 if (!IsMine(pcoin->vout[i]))
5482                     continue;
5483                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
5484                     continue;
5485
5486                 CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
5487
5488                 if (!balances.count(addr))
5489                     balances[addr] = 0;
5490                 balances[addr] += n;
5491             }
5492         }
5493     }
5494
5495     return balances;
5496 }
5497
5498 set< set<CTxDestination> > CWallet::GetAddressGroupings()
5499 {
5500     AssertLockHeld(cs_wallet); // mapWallet
5501     set< set<CTxDestination> > groupings;
5502     set<CTxDestination> grouping;
5503
5504     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
5505     {
5506         CWalletTx *pcoin = &walletEntry.second;
5507
5508         if (pcoin->vin.size() > 0)
5509         {
5510             bool any_mine = false;
5511             // group all input addresses with each other
5512             BOOST_FOREACH(CTxIn txin, pcoin->vin)
5513             {
5514                 CTxDestination address;
5515                 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
5516                     continue;
5517                 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
5518                     continue;
5519                 grouping.insert(address);
5520                 any_mine = true;
5521             }
5522
5523             // group change with input addresses
5524             if (any_mine)
5525             {
5526                BOOST_FOREACH(CTxOut txout, pcoin->vout)
5527                    if (IsChange(txout))
5528                    {
5529                        CTxDestination txoutAddr;
5530                        if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
5531                            continue;
5532                        grouping.insert(txoutAddr);
5533                    }
5534             }
5535             if (grouping.size() > 0)
5536             {
5537                 groupings.insert(grouping);
5538                 grouping.clear();
5539             }
5540         }
5541
5542         // group lone addrs by themselves
5543         for (unsigned int i = 0; i < pcoin->vout.size(); i++)
5544             if (IsMine(pcoin->vout[i]))
5545             {
5546                 CTxDestination address;
5547                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
5548                     continue;
5549                 grouping.insert(address);
5550                 groupings.insert(grouping);
5551                 grouping.clear();
5552             }
5553     }
5554
5555     set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
5556     map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
5557     BOOST_FOREACH(set<CTxDestination> grouping, groupings)
5558     {
5559         // make a set of all the groups hit by this new group
5560         set< set<CTxDestination>* > hits;
5561         map< CTxDestination, set<CTxDestination>* >::iterator it;
5562         BOOST_FOREACH(CTxDestination address, grouping)
5563             if ((it = setmap.find(address)) != setmap.end())
5564                 hits.insert((*it).second);
5565
5566         // merge all hit groups into a new single group and delete old groups
5567         set<CTxDestination>* merged = new set<CTxDestination>(grouping);
5568         BOOST_FOREACH(set<CTxDestination>* hit, hits)
5569         {
5570             merged->insert(hit->begin(), hit->end());
5571             uniqueGroupings.erase(hit);
5572             delete hit;
5573         }
5574         uniqueGroupings.insert(merged);
5575
5576         // update setmap
5577         BOOST_FOREACH(CTxDestination element, *merged)
5578             setmap[element] = merged;
5579     }
5580
5581     set< set<CTxDestination> > ret;
5582     BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
5583     {
5584         ret.insert(*uniqueGrouping);
5585         delete uniqueGrouping;
5586     }
5587
5588     return ret;
5589 }
5590
5591 std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
5592 {
5593     LOCK(cs_wallet);
5594     set<CTxDestination> result;
5595     BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
5596     {
5597         const CTxDestination& address = item.first;
5598         const string& strName = item.second.name;
5599         if (strName == strAccount)
5600             result.insert(address);
5601     }
5602     return result;
5603 }
5604
5605 bool CReserveKey::GetReservedKey(CPubKey& pubkey)
5606 {
5607     if (nIndex == -1)
5608     {
5609         CKeyPool keypool;
5610         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
5611         if (nIndex != -1)
5612             vchPubKey = keypool.vchPubKey;
5613         else {
5614             return false;
5615         }
5616     }
5617     assert(vchPubKey.IsValid());
5618     pubkey = vchPubKey;
5619     return true;
5620 }
5621
5622 void CReserveKey::KeepKey()
5623 {
5624     if (nIndex != -1)
5625         pwallet->KeepKey(nIndex);
5626     nIndex = -1;
5627     vchPubKey = CPubKey();
5628 }
5629
5630 void CReserveKey::ReturnKey()
5631 {
5632     if (nIndex != -1)
5633         pwallet->ReturnKey(nIndex);
5634     nIndex = -1;
5635     vchPubKey = CPubKey();
5636 }
5637
5638 void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
5639 {
5640     setAddress.clear();
5641
5642     CWalletDB walletdb(strWalletFile);
5643
5644     LOCK2(cs_main, cs_wallet);
5645     BOOST_FOREACH(const int64_t& id, setKeyPool)
5646     {
5647         CKeyPool keypool;
5648         if (!walletdb.ReadPool(id, keypool))
5649             throw runtime_error("GetAllReserveKeyHashes(): read failed");
5650         assert(keypool.vchPubKey.IsValid());
5651         CKeyID keyID = keypool.vchPubKey.GetID();
5652         if (!HaveKey(keyID))
5653             throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
5654         setAddress.insert(keyID);
5655     }
5656 }
5657
5658 void CWallet::UpdatedTransaction(const uint256 &hashTx)
5659 {
5660     {
5661         LOCK(cs_wallet);
5662         // Only notify UI if this transaction is in this wallet
5663         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
5664         if (mi != mapWallet.end())
5665             NotifyTransactionChanged(this, hashTx, CT_UPDATED);
5666     }
5667 }
5668
5669 void CWallet::LockCoin(COutPoint& output)
5670 {
5671     AssertLockHeld(cs_wallet); // setLockedCoins
5672     setLockedCoins.insert(output);
5673 }
5674
5675 void CWallet::UnlockCoin(COutPoint& output)
5676 {
5677     AssertLockHeld(cs_wallet); // setLockedCoins
5678     setLockedCoins.erase(output);
5679 }
5680
5681 void CWallet::UnlockAllCoins()
5682 {
5683     AssertLockHeld(cs_wallet); // setLockedCoins
5684     setLockedCoins.clear();
5685 }
5686
5687 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
5688 {
5689     AssertLockHeld(cs_wallet); // setLockedCoins
5690     COutPoint outpt(hash, n);
5691
5692     return (setLockedCoins.count(outpt) > 0);
5693 }
5694
5695 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
5696 {
5697     AssertLockHeld(cs_wallet); // setLockedCoins
5698     for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
5699          it != setLockedCoins.end(); it++) {
5700         COutPoint outpt = (*it);
5701         vOutpts.push_back(outpt);
5702     }
5703 }
5704
5705
5706 // Note Locking Operations
5707
5708 void CWallet::LockNote(const JSOutPoint& output)
5709 {
5710     AssertLockHeld(cs_wallet); // setLockedSproutNotes
5711     setLockedSproutNotes.insert(output);
5712 }
5713
5714 void CWallet::UnlockNote(const JSOutPoint& output)
5715 {
5716     AssertLockHeld(cs_wallet); // setLockedSproutNotes
5717     setLockedSproutNotes.erase(output);
5718 }
5719
5720 void CWallet::UnlockAllSproutNotes()
5721 {
5722     AssertLockHeld(cs_wallet); // setLockedSproutNotes
5723     setLockedSproutNotes.clear();
5724 }
5725
5726 bool CWallet::IsLockedNote(const JSOutPoint& outpt) const
5727 {
5728     AssertLockHeld(cs_wallet); // setLockedSproutNotes
5729
5730     return (setLockedSproutNotes.count(outpt) > 0);
5731 }
5732
5733 std::vector<JSOutPoint> CWallet::ListLockedSproutNotes()
5734 {
5735     AssertLockHeld(cs_wallet); // setLockedSproutNotes
5736     std::vector<JSOutPoint> vOutpts(setLockedSproutNotes.begin(), setLockedSproutNotes.end());
5737     return vOutpts;
5738 }
5739
5740 void CWallet::LockNote(const SaplingOutPoint& output)
5741 {
5742     AssertLockHeld(cs_wallet);
5743     setLockedSaplingNotes.insert(output);
5744 }
5745
5746 void CWallet::UnlockNote(const SaplingOutPoint& output)
5747 {
5748     AssertLockHeld(cs_wallet);
5749     setLockedSaplingNotes.erase(output);
5750 }
5751
5752 void CWallet::UnlockAllSaplingNotes()
5753 {
5754     AssertLockHeld(cs_wallet);
5755     setLockedSaplingNotes.clear();
5756 }
5757
5758 bool CWallet::IsLockedNote(const SaplingOutPoint& output) const
5759 {
5760     AssertLockHeld(cs_wallet);
5761     return (setLockedSaplingNotes.count(output) > 0);
5762 }
5763
5764 std::vector<SaplingOutPoint> CWallet::ListLockedSaplingNotes()
5765 {
5766     AssertLockHeld(cs_wallet);
5767     std::vector<SaplingOutPoint> vOutputs(setLockedSaplingNotes.begin(), setLockedSaplingNotes.end());
5768     return vOutputs;
5769 }
5770
5771 /** @} */ // end of Actions
5772
5773 class CAffectedKeysVisitor : public boost::static_visitor<void> {
5774 private:
5775     const CKeyStore &keystore;
5776     std::vector<CKeyID> &vKeys;
5777
5778 public:
5779     CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
5780
5781     void Process(const CScript &script) {
5782         txnouttype type;
5783         std::vector<CTxDestination> vDest;
5784         int nRequired;
5785         if (ExtractDestinations(script, type, vDest, nRequired)) {
5786             BOOST_FOREACH(const CTxDestination &dest, vDest)
5787                 boost::apply_visitor(*this, dest);
5788         }
5789     }
5790
5791     void operator()(const CKeyID &keyId) {
5792         if (keystore.HaveKey(keyId))
5793             vKeys.push_back(keyId);
5794     }
5795
5796     void operator()(const CPubKey &key) {
5797         CKeyID keyId = key.GetID();
5798         if (keystore.HaveKey(keyId))
5799             vKeys.push_back(keyId);
5800     }
5801
5802     void operator()(const CScriptID &scriptId) {
5803         CScript script;
5804         if (keystore.GetCScript(scriptId, script))
5805             Process(script);
5806     }
5807
5808     void operator()(const CNoDestination &none) {}
5809 };
5810
5811 void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
5812     AssertLockHeld(cs_wallet); // mapKeyMetadata
5813     mapKeyBirth.clear();
5814
5815     // get birth times for keys with metadata
5816     for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
5817         if (it->second.nCreateTime)
5818             mapKeyBirth[it->first] = it->second.nCreateTime;
5819
5820     // map in which we'll infer heights of other keys
5821     CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
5822     std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
5823     std::set<CKeyID> setKeys;
5824     GetKeys(setKeys);
5825     BOOST_FOREACH(const CKeyID &keyid, setKeys) {
5826         if (mapKeyBirth.count(keyid) == 0)
5827             mapKeyFirstBlock[keyid] = pindexMax;
5828     }
5829     setKeys.clear();
5830
5831     // if there are no such keys, we're done
5832     if (mapKeyFirstBlock.empty())
5833         return;
5834
5835     // find first block that affects those keys, if there are any left
5836     std::vector<CKeyID> vAffected;
5837     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
5838         // iterate over all wallet transactions...
5839         const CWalletTx &wtx = (*it).second;
5840         BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
5841         if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
5842             // ... which are already in a block
5843             int nHeight = blit->second->GetHeight();
5844             BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
5845                 // iterate over all their outputs
5846                 CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
5847                 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
5848                     // ... and all their affected keys
5849                     std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
5850                     if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->GetHeight())
5851                         rit->second = blit->second;
5852                 }
5853                 vAffected.clear();
5854             }
5855         }
5856     }
5857
5858     // Extract block timestamps for those keys
5859     for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
5860         mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
5861 }
5862
5863 bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
5864 {
5865     if (boost::get<CNoDestination>(&dest))
5866         return false;
5867
5868     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
5869     if (!fFileBacked)
5870         return true;
5871     return CWalletDB(strWalletFile).WriteDestData(EncodeDestination(dest), key, value);
5872 }
5873
5874 bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
5875 {
5876     if (!mapAddressBook[dest].destdata.erase(key))
5877         return false;
5878     if (!fFileBacked)
5879         return true;
5880     return CWalletDB(strWalletFile).EraseDestData(EncodeDestination(dest), key);
5881 }
5882
5883 bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
5884 {
5885     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
5886     return true;
5887 }
5888
5889 bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
5890 {
5891     std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
5892     if(i != mapAddressBook.end())
5893     {
5894         CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
5895         if(j != i->second.destdata.end())
5896         {
5897             if(value)
5898                 *value = j->second;
5899             return true;
5900         }
5901     }
5902     return false;
5903 }
5904
5905 CKeyPool::CKeyPool()
5906 {
5907     nTime = GetTime();
5908 }
5909
5910 CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
5911 {
5912     nTime = GetTime();
5913     vchPubKey = vchPubKeyIn;
5914 }
5915
5916 CWalletKey::CWalletKey(int64_t nExpires)
5917 {
5918     nTimeCreated = (nExpires ? GetTime() : 0);
5919     nTimeExpires = nExpires;
5920 }
5921
5922 int CMerkleTx::SetMerkleBranch(const CBlock& block)
5923 {
5924     AssertLockHeld(cs_main);
5925     CBlock blockTmp;
5926
5927     // Update the tx's hashBlock
5928     hashBlock = block.GetHash();
5929
5930     // Locate the transaction
5931     for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++)
5932         if (block.vtx[nIndex] == *(CTransaction*)this)
5933             break;
5934     if (nIndex == (int)block.vtx.size())
5935     {
5936         vMerkleBranch.clear();
5937         nIndex = -1;
5938         LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
5939         return 0;
5940     }
5941
5942     // Fill in merkle branch
5943     vMerkleBranch = block.GetMerkleBranch(nIndex);
5944
5945     // Is the tx in a block that's in the main chain
5946     BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
5947     if (mi == mapBlockIndex.end())
5948         return 0;
5949     const CBlockIndex* pindex = (*mi).second;
5950     if (!pindex || !chainActive.Contains(pindex))
5951         return 0;
5952
5953     return chainActive.Height() - pindex->GetHeight() + 1;
5954 }
5955
5956 int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
5957 {
5958     if (hashBlock.IsNull() || nIndex == -1)
5959         return 0;
5960     AssertLockHeld(cs_main);
5961
5962     // Find the block it claims to be in
5963     BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
5964     if (mi == mapBlockIndex.end())
5965         return 0;
5966     CBlockIndex* pindex = (*mi).second;
5967     if (!pindex || !chainActive.Contains(pindex))
5968         return 0;
5969
5970     // Make sure the merkle branch connects to this block
5971     if (!fMerkleVerified)
5972     {
5973         if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
5974             return 0;
5975         fMerkleVerified = true;
5976     }
5977
5978     pindexRet = pindex;
5979     return chainActive.Height() - pindex->GetHeight() + 1;
5980 }
5981
5982 int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
5983 {
5984     AssertLockHeld(cs_main);
5985     int nResult = GetDepthInMainChainINTERNAL(pindexRet);
5986     if (nResult == 0 && !mempool.exists(GetHash()))
5987         return -1; // Not in chain, not in mempool
5988
5989     return nResult;
5990 }
5991
5992 int CMerkleTx::GetBlocksToMaturity() const
5993 {
5994     if ( ASSETCHAINS_SYMBOL[0] == 0 )
5995         COINBASE_MATURITY = _COINBASE_MATURITY;
5996     if (!IsCoinBase())
5997         return 0;
5998     int32_t depth = GetDepthInMainChain();
5999     int32_t ut = UnlockTime(0);
6000     int32_t toMaturity = (ut - chainActive.Height()) < 0 ? 0 : ut - chainActive.Height();
6001     //printf("depth.%i, unlockTime.%i, toMaturity.%i\n", depth, ut, toMaturity);
6002     ut = (COINBASE_MATURITY - depth) < 0 ? 0 : COINBASE_MATURITY - depth;
6003     return(ut < toMaturity ? toMaturity : ut);
6004 }
6005
6006 bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
6007 {
6008     CValidationState state;
6009     return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
6010 }
6011
6012 /**
6013  * Find notes in the wallet filtered by payment address, min depth and ability to spend.
6014  * These notes are decrypted and added to the output parameter vector, outEntries.
6015  */
6016 void CWallet::GetFilteredNotes(
6017     std::vector<CSproutNotePlaintextEntry>& sproutEntries,
6018     std::vector<SaplingNoteEntry>& saplingEntries,
6019     std::string address,
6020     int minDepth,
6021     bool ignoreSpent,
6022     bool requireSpendingKey)
6023 {
6024     std::set<PaymentAddress> filterAddresses;
6025
6026     if (address.length() > 0) {
6027         filterAddresses.insert(DecodePaymentAddress(address));
6028     }
6029
6030     GetFilteredNotes(sproutEntries, saplingEntries, filterAddresses, minDepth, INT_MAX, ignoreSpent, requireSpendingKey);
6031 }
6032
6033 /**
6034  * Find notes in the wallet filtered by payment addresses, min depth, max depth, 
6035  * if the note is spent, if a spending key is required, and if the notes are locked.
6036  * These notes are decrypted and added to the output parameter vector, outEntries.
6037  */
6038 void CWallet::GetFilteredNotes(
6039     std::vector<CSproutNotePlaintextEntry>& sproutEntries,
6040     std::vector<SaplingNoteEntry>& saplingEntries,
6041     std::set<PaymentAddress>& filterAddresses,
6042     int minDepth,
6043     int maxDepth,
6044     bool ignoreSpent,
6045     bool requireSpendingKey,
6046     bool ignoreLocked)
6047 {
6048     LOCK2(cs_main, cs_wallet);
6049
6050     for (auto & p : mapWallet) {
6051         CWalletTx wtx = p.second;
6052
6053         // Filter the transactions before checking for notes
6054         if (!CheckFinalTx(wtx) ||
6055             wtx.GetBlocksToMaturity() > 0 ||
6056             wtx.GetDepthInMainChain() < minDepth ||
6057             wtx.GetDepthInMainChain() > maxDepth) {
6058             continue;
6059         }
6060
6061         for (auto & pair : wtx.mapSproutNoteData) {
6062             JSOutPoint jsop = pair.first;
6063             SproutNoteData nd = pair.second;
6064             SproutPaymentAddress pa = nd.address;
6065
6066             // skip notes which belong to a different payment address in the wallet
6067             if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
6068                 continue;
6069             }
6070
6071             // skip note which has been spent
6072             if (ignoreSpent && nd.nullifier && IsSproutSpent(*nd.nullifier)) {
6073                 continue;
6074             }
6075
6076             // skip notes which cannot be spent
6077             if (requireSpendingKey && !HaveSproutSpendingKey(pa)) {
6078                 continue;
6079             }
6080
6081             // skip locked notes
6082             if (ignoreLocked && IsLockedNote(jsop)) {
6083                 continue;
6084             }
6085
6086             int i = jsop.js; // Index into CTransaction.vjoinsplit
6087             int j = jsop.n; // Index into JSDescription.ciphertexts
6088
6089             // Get cached decryptor
6090             ZCNoteDecryption decryptor;
6091             if (!GetNoteDecryptor(pa, decryptor)) {
6092                 // Note decryptors are created when the wallet is loaded, so it should always exist
6093                 throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", EncodePaymentAddress(pa)));
6094             }
6095
6096             // determine amount of funds in the note
6097             auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey);
6098             try {
6099                 SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt(
6100                         decryptor,
6101                         wtx.vjoinsplit[i].ciphertexts[j],
6102                         wtx.vjoinsplit[i].ephemeralKey,
6103                         hSig,
6104                         (unsigned char) j);
6105
6106                 sproutEntries.push_back(CSproutNotePlaintextEntry{jsop, pa, plaintext, wtx.GetDepthInMainChain()});
6107
6108             } catch (const note_decryption_failed &err) {
6109                 // Couldn't decrypt with this spending key
6110                 throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", EncodePaymentAddress(pa)));
6111             } catch (const std::exception &exc) {
6112                 // Unexpected failure
6113                 throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what()));
6114             }
6115         }
6116
6117         for (auto & pair : wtx.mapSaplingNoteData) {
6118             SaplingOutPoint op = pair.first;
6119             SaplingNoteData nd = pair.second;
6120
6121             auto maybe_pt = SaplingNotePlaintext::decrypt(
6122                 wtx.vShieldedOutput[op.n].encCiphertext,
6123                 nd.ivk,
6124                 wtx.vShieldedOutput[op.n].ephemeralKey,
6125                 wtx.vShieldedOutput[op.n].cm);
6126             assert(static_cast<bool>(maybe_pt));
6127             auto notePt = maybe_pt.get();
6128
6129             auto maybe_pa = nd.ivk.address(notePt.d);
6130             assert(static_cast<bool>(maybe_pa));
6131             auto pa = maybe_pa.get();
6132
6133             // skip notes which belong to a different payment address in the wallet
6134             if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
6135                 continue;
6136             }
6137
6138             if (ignoreSpent && nd.nullifier && IsSaplingSpent(*nd.nullifier)) {
6139                 continue;
6140             }
6141
6142             // skip notes which cannot be spent
6143             if (requireSpendingKey) {
6144                 libzcash::SaplingIncomingViewingKey ivk;
6145                 libzcash::SaplingFullViewingKey fvk;
6146                 if (!(GetSaplingIncomingViewingKey(pa, ivk) &&
6147                     GetSaplingFullViewingKey(ivk, fvk) &&
6148                     HaveSaplingSpendingKey(fvk))) {
6149                     continue;
6150                 }
6151             }
6152
6153             // skip locked notes
6154             // TODO: Add locking for Sapling notes
6155             // if (ignoreLocked && IsLockedNote(op)) {
6156             //     continue;
6157             // }
6158
6159             auto note = notePt.note(nd.ivk).get();
6160             saplingEntries.push_back(SaplingNoteEntry {
6161                 op, pa, note, notePt.memo(), wtx.GetDepthInMainChain() });
6162         }
6163     }
6164 }
6165
6166
6167 //
6168 // Shielded key and address generalizations
6169 //
6170
6171 bool PaymentAddressBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const
6172 {
6173     return m_wallet->HaveSproutSpendingKey(zaddr) || m_wallet->HaveSproutViewingKey(zaddr);
6174 }
6175
6176 bool PaymentAddressBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
6177 {
6178     libzcash::SaplingIncomingViewingKey ivk;
6179
6180     // If we have a SaplingExtendedSpendingKey in the wallet, then we will
6181     // also have the corresponding SaplingFullViewingKey.
6182     return m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) &&
6183         m_wallet->HaveSaplingFullViewingKey(ivk);
6184 }
6185
6186 bool PaymentAddressBelongsToWallet::operator()(const libzcash::InvalidEncoding& no) const
6187 {
6188     return false;
6189 }
6190
6191 bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const
6192 {
6193     return m_wallet->HaveSproutSpendingKey(zaddr);
6194 }
6195
6196 bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
6197 {
6198     libzcash::SaplingIncomingViewingKey ivk;
6199     libzcash::SaplingFullViewingKey fvk;
6200
6201     return m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) &&
6202         m_wallet->GetSaplingFullViewingKey(ivk, fvk) &&
6203         m_wallet->HaveSaplingSpendingKey(fvk);
6204 }
6205
6206 bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::InvalidEncoding& no) const
6207 {
6208     return false;
6209 }
6210
6211 boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
6212     const libzcash::SproutPaymentAddress &zaddr) const
6213 {
6214     libzcash::SproutSpendingKey k;
6215     if (m_wallet->GetSproutSpendingKey(zaddr, k)) {
6216         return libzcash::SpendingKey(k);
6217     } else {
6218         return boost::none;
6219     }
6220 }
6221
6222 boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
6223     const libzcash::SaplingPaymentAddress &zaddr) const
6224 {
6225     libzcash::SaplingExtendedSpendingKey extsk;
6226     if (m_wallet->GetSaplingExtendedSpendingKey(zaddr, extsk)) {
6227         return libzcash::SpendingKey(extsk);
6228     } else {
6229         return boost::none;
6230     }
6231 }
6232
6233 boost::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
6234     const libzcash::InvalidEncoding& no) const
6235 {
6236     // Defaults to InvalidEncoding
6237     return libzcash::SpendingKey();
6238 }
6239
6240 SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const {
6241     auto addr = sk.address();
6242     if (log){
6243         LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
6244     }
6245     if (m_wallet->HaveSproutSpendingKey(addr)) {
6246         return KeyAlreadyExists;
6247     } else if (m_wallet-> AddSproutZKey(sk)) {
6248         m_wallet->mapSproutZKeyMetadata[addr].nCreateTime = nTime;
6249         return KeyAdded;
6250     } else {
6251         return KeyNotAdded;
6252     }
6253 }
6254
6255 SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedSpendingKey &sk) const {
6256     auto fvk = sk.expsk.full_viewing_key();
6257     auto ivk = fvk.in_viewing_key();
6258     auto addr = sk.DefaultAddress();
6259     {
6260         if (log){
6261             LogPrint("zrpc", "Importing zaddr %s...\n", EncodePaymentAddress(addr));
6262         }
6263         // Don't throw error in case a key is already there
6264         if (m_wallet->HaveSaplingSpendingKey(fvk)) {
6265             return KeyAlreadyExists;
6266         } else {
6267             if (!m_wallet-> AddSaplingZKey(sk, addr)) {
6268                 return KeyNotAdded;
6269             }
6270
6271             // Sapling addresses can't have been used in transactions prior to activation.
6272             if (params.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight == Consensus::NetworkUpgrade::ALWAYS_ACTIVE) {
6273                 m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = nTime;
6274             } else {
6275                 // 154051200 seconds from epoch is Friday, 26 October 2018 00:00:00 GMT - definitely before Sapling activates
6276                 m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max((int64_t) 154051200, nTime);
6277             }
6278             if (hdKeypath) {
6279                 m_wallet->mapSaplingZKeyMetadata[ivk].hdKeypath = hdKeypath.get();
6280             }
6281             if (seedFpStr) {
6282                 uint256 seedFp;
6283                 seedFp.SetHex(seedFpStr.get());
6284                 m_wallet->mapSaplingZKeyMetadata[ivk].seedFp = seedFp;
6285             }
6286             return KeyAdded;
6287         }    
6288     }
6289 }
6290
6291 SpendingKeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::InvalidEncoding& no) const { 
6292     throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
6293 }
This page took 0.391042 seconds and 4 git commands to generate.