]> Git Repo - VerusCoin.git/blame - src/wallet/wallet.cpp
Differentiate raw POSHash from full one adjusted by vout value
[VerusCoin.git] / src / wallet / wallet.cpp
CommitLineData
b2120e22 1// Copyright (c) 2009-2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
5b40d886 3// Distributed under the MIT software license, see the accompanying
3a25a2b9 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
e8ef3da7 5
50c72f23 6#include "wallet/wallet.h"
51ed9ec9 7
10254401 8#include "base58.h"
3e1cf9b6 9#include "checkpoints.h"
6a86c24d 10#include "coincontrol.h"
be126699 11#include "consensus/upgrades.h"
da29ecbc 12#include "consensus/validation.h"
9bb37bf0 13#include "consensus/consensus.h"
02e67455 14#include "init.h"
8a893c94 15#include "main.h"
0689f46c 16#include "net.h"
e088d65a 17#include "script/script.h"
18#include "script/sign.h"
14f888ca 19#include "timedata.h"
ad49c256 20#include "utilmoneystr.h"
02e67455 21#include "zcash/Note.hpp"
73699cea 22#include "crypter.h"
4a4e912b 23#include "coins.h"
1fae37f6 24
d0c4197e
PK
25#include <assert.h>
26
cae686d3 27#include <boost/algorithm/string/replace.hpp>
2bb1c877 28#include <boost/filesystem.hpp>
ad49c256 29#include <boost/thread.hpp>
e8ef3da7
WL
30
31using namespace std;
c1c45943 32using namespace libzcash;
e8ef3da7 33
5b40d886
MF
34/**
35 * Settings
36 */
c6cb21d1 37CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
aa279d61 38CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
77ed59df 39unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
1bbca249 40bool bSpendZeroConfChange = true;
c1c9d5b4 41bool fSendFreeTransactions = false;
ed3e5e46 42bool fPayAtLeastCustomFee = true;
bdc72415 43#include "komodo_defs.h"
44
6ad13d7c 45extern int32_t KOMODO_EXCHANGEWALLET;
7c130297 46extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
1fae37f6 47extern int32_t VERUS_MIN_STAKEAGE;
1f722359 48CBlockIndex *komodo_chainactive(int32_t height);
e8ef3da7 49
7e6d23b1
CD
50/**
51 * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
5b40d886
MF
52 * Override with -mintxfee
53 */
9b1627d1 54CFeeRate CWallet::minTxFee = CFeeRate(1000);
13fc83c7 55
5b40d886
MF
56/** @defgroup mapWallet
57 *
58 * @{
59 */
e8ef3da7 60
d650f96d
CM
61struct CompareValueOnly
62{
a372168e
MF
63 bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1,
64 const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const
d650f96d
CM
65 {
66 return t1.first < t2.first;
67 }
68};
69
02e67455
JG
70std::string JSOutPoint::ToString() const
71{
72 return strprintf("JSOutPoint(%s, %d, %d)", hash.ToString().substr(0,10), js, n);
73}
74
ad49c256
WL
75std::string COutput::ToString() const
76{
805344dc 77 return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue));
ad49c256
WL
78}
79
93a18a36
GA
80const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
81{
82 LOCK(cs_wallet);
83 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
84 if (it == mapWallet.end())
85 return NULL;
86 return &(it->second);
87}
88
c1c45943
S
89// Generate a new spending key and return its public payment address
90CZCPaymentAddress CWallet::GenerateNewZKey()
91{
92 AssertLockHeld(cs_wallet); // mapZKeyMetadata
93 auto k = SpendingKey::random();
94 auto addr = k.address();
95
96 // Check for collision, even though it is unlikely to ever occur
97 if (CCryptoKeyStore::HaveSpendingKey(addr))
0feffd14 98 throw std::runtime_error("CWallet::GenerateNewZKey(): Collision detected");
c1c45943
S
99
100 // Create new metadata
101 int64_t nCreationTime = GetTime();
102 mapZKeyMetadata[addr] = CKeyMetadata(nCreationTime);
103
104 CZCPaymentAddress pubaddr(addr);
105 if (!AddZKey(k))
0feffd14 106 throw std::runtime_error("CWallet::GenerateNewZKey(): AddZKey failed");
c1c45943
S
107 return pubaddr;
108}
109
110// Add spending key to keystore and persist to disk
111bool CWallet::AddZKey(const libzcash::SpendingKey &key)
112{
113 AssertLockHeld(cs_wallet); // mapZKeyMetadata
114 auto addr = key.address();
115
116 if (!CCryptoKeyStore::AddSpendingKey(key))
117 return false;
118
167cd333
JG
119 // check if we need to remove from viewing keys
120 if (HaveViewingKey(addr))
121 RemoveViewingKey(key.viewing_key());
122
c1c45943
S
123 if (!fFileBacked)
124 return true;
125
126 if (!IsCrypted()) {
127 return CWalletDB(strWalletFile).WriteZKey(addr,
128 key,
129 mapZKeyMetadata[addr]);
130 }
131 return true;
132}
133
fd61d6f5 134CPubKey CWallet::GenerateNewKey()
9976cf07 135{
95691680 136 AssertLockHeld(cs_wallet); // mapKeyMetadata
439e1497 137 bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
38067c18 138
dfa23b94
PW
139 CKey secret;
140 secret.MakeNewKey(fCompressed);
38067c18
PW
141
142 // Compressed public keys were introduced in version 0.6.0
143 if (fCompressed)
439e1497 144 SetMinVersion(FEATURE_COMPRPUBKEY);
38067c18 145
dfa23b94 146 CPubKey pubkey = secret.GetPubKey();
d0c41a73 147 assert(secret.VerifyPubKey(pubkey));
4addb2c0
PW
148
149 // Create new metadata
51ed9ec9 150 int64_t nCreationTime = GetTime();
4addb2c0
PW
151 mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
152 if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
153 nTimeFirstKey = nCreationTime;
154
dfa23b94 155 if (!AddKeyPubKey(secret, pubkey))
5262fde0 156 throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
dfa23b94 157 return pubkey;
9976cf07 158}
e8ef3da7 159
4addb2c0 160bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
e8ef3da7 161{
95691680 162 AssertLockHeld(cs_wallet); // mapKeyMetadata
dfa23b94 163 if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
acd65016 164 return false;
ccca27a7
CL
165
166 // check if we need to remove from watch-only
167 CScript script;
168 script = GetScriptForDestination(pubkey.GetID());
169 if (HaveWatchOnly(script))
170 RemoveWatchOnly(script);
171
e8ef3da7
WL
172 if (!fFileBacked)
173 return true;
dfa23b94 174 if (!IsCrypted()) {
3869fb89
JG
175 return CWalletDB(strWalletFile).WriteKey(pubkey,
176 secret.GetPrivKey(),
4addb2c0 177 mapKeyMetadata[pubkey.GetID()]);
dfa23b94 178 }
84c3c2eb 179 return true;
4e87d341
MC
180}
181
3869fb89 182bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
4addb2c0 183 const vector<unsigned char> &vchCryptedSecret)
4e87d341 184{
73699cea 185
4e87d341
MC
186 if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
187 return false;
188 if (!fFileBacked)
189 return true;
96f34cd5 190 {
f8dcd5ca 191 LOCK(cs_wallet);
96f34cd5 192 if (pwalletdbEncryption)
3869fb89
JG
193 return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
194 vchCryptedSecret,
4addb2c0 195 mapKeyMetadata[vchPubKey.GetID()]);
96f34cd5 196 else
3869fb89
JG
197 return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
198 vchCryptedSecret,
4addb2c0 199 mapKeyMetadata[vchPubKey.GetID()]);
96f34cd5 200 }
0767e691 201 return false;
4e87d341
MC
202}
203
73699cea
S
204
205bool CWallet::AddCryptedSpendingKey(const libzcash::PaymentAddress &address,
642a1caf 206 const libzcash::ReceivingKey &rk,
73699cea
S
207 const std::vector<unsigned char> &vchCryptedSecret)
208{
642a1caf 209 if (!CCryptoKeyStore::AddCryptedSpendingKey(address, rk, vchCryptedSecret))
73699cea
S
210 return false;
211 if (!fFileBacked)
212 return true;
213 {
214 LOCK(cs_wallet);
82bd9ee8 215 if (pwalletdbEncryption) {
73699cea 216 return pwalletdbEncryption->WriteCryptedZKey(address,
642a1caf 217 rk,
73699cea
S
218 vchCryptedSecret,
219 mapZKeyMetadata[address]);
82bd9ee8 220 } else {
73699cea 221 return CWalletDB(strWalletFile).WriteCryptedZKey(address,
642a1caf 222 rk,
73699cea
S
223 vchCryptedSecret,
224 mapZKeyMetadata[address]);
82bd9ee8 225 }
73699cea
S
226 }
227 return false;
228}
229
4addb2c0
PW
230bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
231{
95691680 232 AssertLockHeld(cs_wallet); // mapKeyMetadata
4addb2c0
PW
233 if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
234 nTimeFirstKey = meta.nCreateTime;
235
236 mapKeyMetadata[pubkey.GetID()] = meta;
237 return true;
238}
239
c1c45943
S
240bool CWallet::LoadZKeyMetadata(const PaymentAddress &addr, const CKeyMetadata &meta)
241{
242 AssertLockHeld(cs_wallet); // mapZKeyMetadata
243 mapZKeyMetadata[addr] = meta;
244 return true;
245}
246
2f15e86a
GA
247bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
248{
249 return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
250}
251
642a1caf 252bool CWallet::LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
73699cea 253{
642a1caf 254 return CCryptoKeyStore::AddCryptedSpendingKey(addr, rk, vchCryptedSecret);
73699cea
S
255}
256
c1c45943
S
257bool CWallet::LoadZKey(const libzcash::SpendingKey &key)
258{
259 return CCryptoKeyStore::AddSpendingKey(key);
260}
261
167cd333
JG
262bool CWallet::AddViewingKey(const libzcash::ViewingKey &vk)
263{
bec22351 264 if (!CCryptoKeyStore::AddViewingKey(vk)) {
167cd333 265 return false;
bec22351 266 }
167cd333 267 nTimeFirstKey = 1; // No birthday information for viewing keys.
bec22351 268 if (!fFileBacked) {
167cd333 269 return true;
bec22351 270 }
167cd333
JG
271 return CWalletDB(strWalletFile).WriteViewingKey(vk);
272}
273
274bool CWallet::RemoveViewingKey(const libzcash::ViewingKey &vk)
275{
276 AssertLockHeld(cs_wallet);
bec22351 277 if (!CCryptoKeyStore::RemoveViewingKey(vk)) {
167cd333 278 return false;
bec22351
JG
279 }
280 if (fFileBacked) {
281 if (!CWalletDB(strWalletFile).EraseViewingKey(vk)) {
167cd333 282 return false;
bec22351
JG
283 }
284 }
167cd333
JG
285
286 return true;
287}
288
289bool CWallet::LoadViewingKey(const libzcash::ViewingKey &vk)
290{
291 return CCryptoKeyStore::AddViewingKey(vk);
292}
293
922e8e29 294bool CWallet::AddCScript(const CScript& redeemScript)
e679ec96 295{
922e8e29 296 if (!CCryptoKeyStore::AddCScript(redeemScript))
e679ec96
GA
297 return false;
298 if (!fFileBacked)
299 return true;
922e8e29 300 return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
e679ec96
GA
301}
302
18116b06
WL
303bool CWallet::LoadCScript(const CScript& redeemScript)
304{
305 /* A sanity check was added in pull #3843 to avoid adding redeemScripts
306 * that never can be redeemed. However, old wallets may still contain
307 * these. Do not add them to the wallet and warn. */
308 if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
309 {
066e2a14 310 std::string strAddr = CBitcoinAddress(CScriptID(redeemScript)).ToString();
18116b06
WL
311 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",
312 __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
313 return true;
314 }
315
316 return CCryptoKeyStore::AddCScript(redeemScript);
317}
318
d5087d1b 319bool CWallet::AddWatchOnly(const CScript &dest)
c8988460
PW
320{
321 if (!CCryptoKeyStore::AddWatchOnly(dest))
322 return false;
323 nTimeFirstKey = 1; // No birthday information for watch-only keys.
939ed973 324 NotifyWatchonlyChanged(true);
c8988460
PW
325 if (!fFileBacked)
326 return true;
327 return CWalletDB(strWalletFile).WriteWatchOnly(dest);
328}
329
ccca27a7
CL
330bool CWallet::RemoveWatchOnly(const CScript &dest)
331{
332 AssertLockHeld(cs_wallet);
333 if (!CCryptoKeyStore::RemoveWatchOnly(dest))
334 return false;
335 if (!HaveWatchOnly())
336 NotifyWatchonlyChanged(false);
337 if (fFileBacked)
338 if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
339 return false;
340
341 return true;
342}
343
d5087d1b 344bool CWallet::LoadWatchOnly(const CScript &dest)
c8988460 345{
c8988460
PW
346 return CCryptoKeyStore::AddWatchOnly(dest);
347}
348
94f778bd 349bool CWallet::Unlock(const SecureString& strWalletPassphrase)
4e87d341 350{
6cc4a62c
GA
351 CCrypter crypter;
352 CKeyingMaterial vMasterKey;
4e87d341 353
f8dcd5ca
PW
354 {
355 LOCK(cs_wallet);
4e87d341
MC
356 BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
357 {
358 if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
359 return false;
360 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
92f2c1fe 361 continue; // try another master key
4e87d341
MC
362 if (CCryptoKeyStore::Unlock(vMasterKey))
363 return true;
364 }
f8dcd5ca 365 }
4e87d341
MC
366 return false;
367}
368
94f778bd 369bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
4e87d341 370{
6cc4a62c 371 bool fWasLocked = IsLocked();
4e87d341 372
6cc4a62c 373 {
f8dcd5ca 374 LOCK(cs_wallet);
4e87d341
MC
375 Lock();
376
377 CCrypter crypter;
378 CKeyingMaterial vMasterKey;
379 BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
380 {
381 if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
382 return false;
6cc4a62c 383 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
4e87d341
MC
384 return false;
385 if (CCryptoKeyStore::Unlock(vMasterKey))
386 {
51ed9ec9 387 int64_t nStartTime = GetTimeMillis();
ddebdd9a
MC
388 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
389 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
390
391 nStartTime = GetTimeMillis();
392 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
393 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
394
395 if (pMasterKey.second.nDeriveIterations < 25000)
396 pMasterKey.second.nDeriveIterations = 25000;
397
881a85a2 398 LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
ddebdd9a 399
4e87d341
MC
400 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
401 return false;
402 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
403 return false;
404 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
405 if (fWasLocked)
406 Lock();
407 return true;
408 }
409 }
410 }
6cc4a62c 411
4e87d341
MC
412 return false;
413}
414
de42390f
JG
415void CWallet::ChainTip(const CBlockIndex *pindex, const CBlock *pblock,
416 ZCIncrementalMerkleTree tree, bool added)
769e031c
JG
417{
418 if (added) {
de42390f 419 IncrementNoteWitnesses(pindex, pblock, tree);
8eb43ab4 420 } else if ( nWitnessCacheSize > 1 ){ //ASSETCHAINS_SYMBOL[0] == 0 ||
40ef121e 421 DecrementNoteWitnesses(pindex);
ab49ccac 422 } else fprintf(stderr,"would have decremented %s nWitnessCacheSize.%d\n",ASSETCHAINS_SYMBOL,(int32_t)nWitnessCacheSize);
769e031c
JG
423}
424
ed6d0b5f
PW
425void CWallet::SetBestChain(const CBlockLocator& loc)
426{
427 CWalletDB walletdb(strWalletFile);
03f83b9b 428 SetBestChainINTERNAL(walletdb, loc);
ed6d0b5f 429}
7414733b 430
439e1497 431bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
0b807a41 432{
ca4cf5cf 433 LOCK(cs_wallet); // nWalletVersion
0b807a41
PW
434 if (nWalletVersion >= nVersion)
435 return true;
436
439e1497
PW
437 // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
438 if (fExplicit && nVersion > nWalletMaxVersion)
439 nVersion = FEATURE_LATEST;
440
0b807a41
PW
441 nWalletVersion = nVersion;
442
439e1497
PW
443 if (nVersion > nWalletMaxVersion)
444 nWalletMaxVersion = nVersion;
445
0b807a41
PW
446 if (fFileBacked)
447 {
448 CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
0b807a41
PW
449 if (nWalletVersion > 40000)
450 pwalletdb->WriteMinVersion(nWalletVersion);
451 if (!pwalletdbIn)
452 delete pwalletdb;
453 }
454
455 return true;
456}
457
439e1497
PW
458bool CWallet::SetMaxVersion(int nVersion)
459{
ca4cf5cf 460 LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
439e1497
PW
461 // cannot downgrade below current version
462 if (nWalletVersion > nVersion)
463 return false;
464
465 nWalletMaxVersion = nVersion;
466
467 return true;
468}
469
3015e0bc 470set<uint256> CWallet::GetConflicts(const uint256& txid) const
731b89b8
GA
471{
472 set<uint256> result;
473 AssertLockHeld(cs_wallet);
474
475 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
476 if (it == mapWallet.end())
477 return result;
478 const CWalletTx& wtx = it->second;
479
93a18a36 480 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
731b89b8
GA
481
482 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
483 {
93a18a36
GA
484 if (mapTxSpends.count(txin.prevout) <= 1)
485 continue; // No conflict if zero or one spends
486 range = mapTxSpends.equal_range(txin.prevout);
487 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
3015e0bc 488 result.insert(it->second);
731b89b8 489 }
0f106047
JG
490
491 std::pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range_n;
492
493 for (const JSDescription& jsdesc : wtx.vjoinsplit) {
494 for (const uint256& nullifier : jsdesc.nullifiers) {
495 if (mapTxNullifiers.count(nullifier) <= 1) {
496 continue; // No conflict if zero or one spends
497 }
498 range_n = mapTxNullifiers.equal_range(nullifier);
499 for (TxNullifiers::const_iterator it = range_n.first; it != range_n.second; ++it) {
500 result.insert(it->second);
501 }
502 }
503 }
731b89b8
GA
504 return result;
505}
506
2bb1c877
JS
507void CWallet::Flush(bool shutdown)
508{
509 bitdb.Flush(shutdown);
510}
511
341e2385 512bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString)
2bb1c877
JS
513{
514 if (!bitdb.Open(GetDataDir()))
515 {
516 // try moving the database env out of the way
517 boost::filesystem::path pathDatabase = GetDataDir() / "database";
518 boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
519 try {
520 boost::filesystem::rename(pathDatabase, pathDatabaseBak);
521 LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
522 } catch (const boost::filesystem::filesystem_error&) {
523 // failure is ok (well, not really, but it's not worse than what we started with)
524 }
525
526 // try again
527 if (!bitdb.Open(GetDataDir())) {
528 // if it still fails, it probably means we can't even create the database env
529 string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
530 errorString += msg;
531 return true;
532 }
533 }
534
535 if (GetBoolArg("-salvagewallet", false))
536 {
537 // Recover readable keypairs:
538 if (!CWalletDB::Recover(bitdb, walletFile, true))
539 return false;
540 }
541
542 if (boost::filesystem::exists(GetDataDir() / walletFile))
543 {
544 CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
545 if (r == CDBEnv::RECOVER_OK)
546 {
547 warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
548 " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
549 " your balance or transactions are incorrect you should"
550 " restore from a backup."), GetDataDir());
551 }
552 if (r == CDBEnv::RECOVER_FAIL)
553 errorString += _("wallet.dat corrupt, salvage failed");
554 }
555
556 return true;
557}
558
0f106047
JG
559template <class T>
560void CWallet::SyncMetaData(pair<typename TxSpendMap<T>::iterator, typename TxSpendMap<T>::iterator> range)
731b89b8
GA
561{
562 // We want all the wallet transactions in range to have the same metadata as
563 // the oldest (smallest nOrderPos).
564 // So: find smallest nOrderPos:
565
566 int nMinOrderPos = std::numeric_limits<int>::max();
567 const CWalletTx* copyFrom = NULL;
0f106047 568 for (typename TxSpendMap<T>::iterator it = range.first; it != range.second; ++it)
731b89b8
GA
569 {
570 const uint256& hash = it->second;
571 int n = mapWallet[hash].nOrderPos;
572 if (n < nMinOrderPos)
573 {
574 nMinOrderPos = n;
575 copyFrom = &mapWallet[hash];
576 }
577 }
578 // Now copy data from copyFrom to rest:
0f106047 579 for (typename TxSpendMap<T>::iterator it = range.first; it != range.second; ++it)
731b89b8
GA
580 {
581 const uint256& hash = it->second;
582 CWalletTx* copyTo = &mapWallet[hash];
583 if (copyFrom == copyTo) continue;
584 copyTo->mapValue = copyFrom->mapValue;
c3a7307a
JG
585 // mapNoteData not copied on purpose
586 // (it is always set correctly for each CWalletTx)
731b89b8
GA
587 copyTo->vOrderForm = copyFrom->vOrderForm;
588 // fTimeReceivedIsTxTime not copied on purpose
589 // nTimeReceived not copied on purpose
590 copyTo->nTimeSmart = copyFrom->nTimeSmart;
591 copyTo->fFromMe = copyFrom->fFromMe;
592 copyTo->strFromAccount = copyFrom->strFromAccount;
731b89b8
GA
593 // nOrderPos not copied on purpose
594 // cached members not copied on purpose
595 }
596}
597
5b40d886
MF
598/**
599 * Outpoint is spent if any non-conflicted transaction
600 * spends it:
601 */
93a18a36 602bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
731b89b8 603{
93a18a36
GA
604 const COutPoint outpoint(hash, n);
605 pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
606 range = mapTxSpends.equal_range(outpoint);
731b89b8 607
93a18a36 608 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
731b89b8 609 {
93a18a36
GA
610 const uint256& wtxid = it->second;
611 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
612 if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
613 return true; // Spent
731b89b8 614 }
93a18a36
GA
615 return false;
616}
617
0f106047
JG
618/**
619 * Note is spent if any non-conflicted transaction
620 * spends it:
621 */
622bool CWallet::IsSpent(const uint256& nullifier) const
623{
624 pair<TxNullifiers::const_iterator, TxNullifiers::const_iterator> range;
625 range = mapTxNullifiers.equal_range(nullifier);
626
627 for (TxNullifiers::const_iterator it = range.first; it != range.second; ++it) {
628 const uint256& wtxid = it->second;
629 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
630 if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) {
631 return true; // Spent
632 }
633 }
634 return false;
635}
636
93a18a36
GA
637void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
638{
639 mapTxSpends.insert(make_pair(outpoint, wtxid));
640
641 pair<TxSpends::iterator, TxSpends::iterator> range;
642 range = mapTxSpends.equal_range(outpoint);
0f106047 643 SyncMetaData<COutPoint>(range);
93a18a36
GA
644}
645
0f106047
JG
646void CWallet::AddToSpends(const uint256& nullifier, const uint256& wtxid)
647{
648 mapTxNullifiers.insert(make_pair(nullifier, wtxid));
649
650 pair<TxNullifiers::iterator, TxNullifiers::iterator> range;
651 range = mapTxNullifiers.equal_range(nullifier);
652 SyncMetaData<uint256>(range);
653}
93a18a36
GA
654
655void CWallet::AddToSpends(const uint256& wtxid)
656{
657 assert(mapWallet.count(wtxid));
658 CWalletTx& thisTx = mapWallet[wtxid];
659 if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
660 return;
661
0f106047 662 for (const CTxIn& txin : thisTx.vin) {
93a18a36 663 AddToSpends(txin.prevout, wtxid);
0f106047
JG
664 }
665 for (const JSDescription& jsdesc : thisTx.vjoinsplit) {
666 for (const uint256& nullifier : jsdesc.nullifiers) {
667 AddToSpends(nullifier, wtxid);
668 }
669 }
731b89b8
GA
670}
671
76b22658
JG
672void CWallet::ClearNoteWitnessCache()
673{
674 LOCK(cs_wallet);
675 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
676 for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
40600f50 677 item.second.witnesses.clear();
a4ef3aa9 678 item.second.witnessHeight = -1;
76b22658
JG
679 }
680 }
a4ef3aa9 681 nWitnessCacheSize = 0;
a7f86bc7 682 //fprintf(stderr,"Clear witness cache\n");
76b22658
JG
683}
684
be74c80d
JG
685void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
686 const CBlock* pblockIn,
b6961fc1 687 ZCIncrementalMerkleTree& tree)
be74c80d 688{
e0440cc3 689 //fprintf(stderr,"A increment witness cache -> %d\n",(int32_t)nWitnessCacheSize);
be74c80d
JG
690 {
691 LOCK(cs_wallet);
692 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
693 for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
694 CNoteData* nd = &(item.second);
b6961fc1
JG
695 // Only increment witnesses that are behind the current height
696 if (nd->witnessHeight < pindex->nHeight) {
6f78f4f4
JG
697 // Check the validity of the cache
698 // The only time a note witnessed above the current height
699 // would be invalid here is during a reindex when blocks
700 // have been decremented, and we are incrementing the blocks
701 // immediately after.
702 assert(nWitnessCacheSize >= nd->witnesses.size());
b6961fc1 703 // Witnesses being incremented should always be either -1
40ef121e 704 // (never incremented or decremented) or one below pindex
b6961fc1
JG
705 assert((nd->witnessHeight == -1) ||
706 (nd->witnessHeight == pindex->nHeight - 1));
707 // Copy the witness for the previous block if we have one
708 if (nd->witnesses.size() > 0) {
709 nd->witnesses.push_front(nd->witnesses.front());
710 }
711 if (nd->witnesses.size() > WITNESS_CACHE_SIZE) {
712 nd->witnesses.pop_back();
713 }
be74c80d
JG
714 }
715 }
716 }
8a7d37be 717 if (nWitnessCacheSize < WITNESS_CACHE_SIZE) {
8415ccaa 718 //fprintf(stderr,"increment nWitnesscache -> %d\n",(int32_t)nWitnessCacheSize);
8a7d37be
DH
719 nWitnessCacheSize += 1;
720 }
be74c80d
JG
721
722 const CBlock* pblock {pblockIn};
723 CBlock block;
724 if (!pblock) {
b8add6a4 725 ReadBlockFromDisk(block, pindex,1);
be74c80d
JG
726 pblock = &block;
727 }
728
be74c80d 729 for (const CTransaction& tx : pblock->vtx) {
fa511e10 730 auto hash = tx.GetHash();
be74c80d
JG
731 bool txIsOurs = mapWallet.count(hash);
732 for (size_t i = 0; i < tx.vjoinsplit.size(); i++) {
733 const JSDescription& jsdesc = tx.vjoinsplit[i];
734 for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) {
735 const uint256& note_commitment = jsdesc.commitments[j];
736 tree.append(note_commitment);
737
738 // Increment existing witnesses
739 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
740 for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
741 CNoteData* nd = &(item.second);
b6961fc1
JG
742 if (nd->witnessHeight < pindex->nHeight &&
743 nd->witnesses.size() > 0) {
6f78f4f4
JG
744 // Check the validity of the cache
745 // See earlier comment about validity.
746 assert(nWitnessCacheSize >= nd->witnesses.size());
be74c80d
JG
747 nd->witnesses.front().append(note_commitment);
748 }
749 }
750 }
751
752 // If this is our note, witness it
753 if (txIsOurs) {
754 JSOutPoint jsoutpt {hash, i, j};
c0ec0e75
JG
755 if (mapWallet[hash].mapNoteData.count(jsoutpt) &&
756 mapWallet[hash].mapNoteData[jsoutpt].witnessHeight < pindex->nHeight) {
8e41408a 757 CNoteData* nd = &(mapWallet[hash].mapNoteData[jsoutpt]);
878c4b1b
JG
758 if (nd->witnesses.size() > 0) {
759 // We think this can happen because we write out the
760 // witness cache state after every block increment or
761 // decrement, but the block index itself is written in
762 // batches. So if the node crashes in between these two
763 // operations, it is possible for IncrementNoteWitnesses
764 // to be called again on previously-cached blocks. This
765 // doesn't affect existing cached notes because of the
766 // CNoteData::witnessHeight checks. See #1378 for details.
1b407cba 767 LogPrintf("Inconsistent witness cache state found for %s\n- Cache size: %d\n- Top (height %d): %s\n- New (height %d): %s\n",
878c4b1b 768 jsoutpt.ToString(), nd->witnesses.size(),
1b407cba 769 nd->witnessHeight,
878c4b1b 770 nd->witnesses.front().root().GetHex(),
1b407cba 771 pindex->nHeight,
878c4b1b
JG
772 tree.witness().root().GetHex());
773 nd->witnesses.clear();
774 }
8e41408a 775 nd->witnesses.push_front(tree.witness());
b6961fc1
JG
776 // Set height to one less than pindex so it gets incremented
777 nd->witnessHeight = pindex->nHeight - 1;
8e41408a
DH
778 // Check the validity of the cache
779 assert(nWitnessCacheSize >= nd->witnesses.size());
be74c80d
JG
780 }
781 }
782 }
783 }
784 }
b6961fc1
JG
785
786 // Update witness heights
83d7b5b6
JG
787 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
788 for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
789 CNoteData* nd = &(item.second);
b6961fc1
JG
790 if (nd->witnessHeight < pindex->nHeight) {
791 nd->witnessHeight = pindex->nHeight;
6f78f4f4
JG
792 // Check the validity of the cache
793 // See earlier comment about validity.
794 assert(nWitnessCacheSize >= nd->witnesses.size());
b6961fc1 795 }
83d7b5b6
JG
796 }
797 }
b6961fc1 798
03f83b9b
JG
799 // For performance reasons, we write out the witness cache in
800 // CWallet::SetBestChain() (which also ensures that overall consistency
801 // of the wallet.dat is maintained).
be74c80d
JG
802 }
803}
804
40ef121e 805void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex)
be74c80d 806{
8ba45413 807 extern int32_t KOMODO_REWIND;
be74c80d
JG
808 {
809 LOCK(cs_wallet);
810 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
811 for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
812 CNoteData* nd = &(item.second);
9d2cc3a7
JG
813 // Only increment witnesses that are not above the current height
814 if (nd->witnessHeight <= pindex->nHeight) {
6f78f4f4
JG
815 // Check the validity of the cache
816 // See comment below (this would be invalid if there was a
817 // prior decrement).
818 assert(nWitnessCacheSize >= nd->witnesses.size());
9d2cc3a7
JG
819 // Witnesses being decremented should always be either -1
820 // (never incremented or decremented) or equal to pindex
821 assert((nd->witnessHeight == -1) ||
822 (nd->witnessHeight == pindex->nHeight));
823 if (nd->witnesses.size() > 0) {
824 nd->witnesses.pop_front();
825 }
826 // pindex is the block being removed, so the new witness cache
827 // height is one below it.
828 nd->witnessHeight = pindex->nHeight - 1;
be74c80d
JG
829 }
830 }
831 }
e0440cc3 832 //fprintf(stderr,"decrement witness cache -> %d\n",(int32_t)nWitnessCacheSize);
1066247f 833 if ( nWitnessCacheSize > 1 )
4c73b58b 834 nWitnessCacheSize -= 1;
835 else
836 {
4c73b58b 837 fprintf(stderr,"%s nWitnessCacheSize.%d\n",ASSETCHAINS_SYMBOL,(int32_t)nWitnessCacheSize);
838 }
83d7b5b6
JG
839 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
840 for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
841 CNoteData* nd = &(item.second);
842 // Check the validity of the cache
6f78f4f4
JG
843 // Technically if there are notes witnessed above the current
844 // height, their cache will now be invalid (relative to the new
845 // value of nWitnessCacheSize). However, this would only occur
846 // during a reindex, and by the time the reindex reaches the tip
847 // of the chain again, the existing witness caches will be valid
848 // again.
849 // We don't set nWitnessCacheSize to zero at the start of the
850 // reindex because the on-disk blocks had already resulted in a
851 // chain that didn't trigger the assertion below.
852 if (nd->witnessHeight < pindex->nHeight) {
853 assert(nWitnessCacheSize >= nd->witnesses.size());
854 }
83d7b5b6
JG
855 }
856 }
d8be8b2e 857 if ( KOMODO_REWIND == 0 )
8432a64f 858 assert(nWitnessCacheSize > 0);
c7ede30f 859 //if (fFileBacked) {
860 // CWalletDB walletdb(strWalletFile);
861 // WriteWitnessCache(walletdb);
862 //}
03f83b9b
JG
863 // For performance reasons, we write out the witness cache in
864 // CWallet::SetBestChain() (which also ensures that overall consistency
865 // of the wallet.dat is maintained).
be74c80d
JG
866 }
867}
868
94f778bd 869bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
4e87d341 870{
6cc4a62c
GA
871 if (IsCrypted())
872 return false;
4e87d341 873
6cc4a62c 874 CKeyingMaterial vMasterKey;
4e87d341 875
6cc4a62c 876 vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
65e3a1e7 877 GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
4e87d341 878
6cc4a62c 879 CMasterKey kMasterKey;
001a53d7 880
6cc4a62c 881 kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
65e3a1e7 882 GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
4e87d341 883
6cc4a62c 884 CCrypter crypter;
51ed9ec9 885 int64_t nStartTime = GetTimeMillis();
6cc4a62c
GA
886 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
887 kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
ddebdd9a 888
6cc4a62c
GA
889 nStartTime = GetTimeMillis();
890 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
891 kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
ddebdd9a 892
6cc4a62c
GA
893 if (kMasterKey.nDeriveIterations < 25000)
894 kMasterKey.nDeriveIterations = 25000;
ddebdd9a 895
881a85a2 896 LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
ddebdd9a 897
6cc4a62c
GA
898 if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
899 return false;
900 if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
901 return false;
4e87d341 902
6cc4a62c 903 {
f8dcd5ca 904 LOCK(cs_wallet);
4e87d341
MC
905 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
906 if (fFileBacked)
907 {
870da77d 908 assert(!pwalletdbEncryption);
96f34cd5 909 pwalletdbEncryption = new CWalletDB(strWalletFile);
870da77d
PK
910 if (!pwalletdbEncryption->TxnBegin()) {
911 delete pwalletdbEncryption;
912 pwalletdbEncryption = NULL;
0fb78eae 913 return false;
870da77d 914 }
96f34cd5 915 pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
4e87d341
MC
916 }
917
918 if (!EncryptKeys(vMasterKey))
96f34cd5 919 {
870da77d 920 if (fFileBacked) {
96f34cd5 921 pwalletdbEncryption->TxnAbort();
870da77d
PK
922 delete pwalletdbEncryption;
923 }
924 // We now probably have half of our keys encrypted in memory, and half not...
7e6d23b1 925 // die and let the user reload the unencrypted wallet.
d0c4197e 926 assert(false);
96f34cd5
MC
927 }
928
0b807a41 929 // Encryption was introduced in version 0.4.0
439e1497 930 SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
0b807a41 931
96f34cd5
MC
932 if (fFileBacked)
933 {
870da77d
PK
934 if (!pwalletdbEncryption->TxnCommit()) {
935 delete pwalletdbEncryption;
5b40d886 936 // We now have keys encrypted in memory, but not on disk...
7e6d23b1 937 // die to avoid confusion and let the user reload the unencrypted wallet.
d0c4197e 938 assert(false);
870da77d 939 }
96f34cd5 940
fcfd7ff8 941 delete pwalletdbEncryption;
96f34cd5
MC
942 pwalletdbEncryption = NULL;
943 }
4e87d341 944
37971fcc
GA
945 Lock();
946 Unlock(strWalletPassphrase);
947 NewKeyPool();
4e87d341 948 Lock();
6cc4a62c 949
d764d916
GA
950 // Need to completely rewrite the wallet file; if we don't, bdb might keep
951 // bits of the unencrypted private key in slack space in the database file.
b2d3b2d6 952 CDB::Rewrite(strWalletFile);
fe4a6550 953
d764d916 954 }
ab1b288f 955 NotifyStatusChanged(this);
9e9869d0 956
4e87d341 957 return true;
e8ef3da7
WL
958}
959
51ed9ec9 960int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
da7b8c12 961{
95691680 962 AssertLockHeld(cs_wallet); // nOrderPosNext
51ed9ec9 963 int64_t nRet = nOrderPosNext++;
4291e8fe
PW
964 if (pwalletdb) {
965 pwalletdb->WriteOrderPosNext(nOrderPosNext);
966 } else {
967 CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
968 }
da7b8c12
LD
969 return nRet;
970}
971
ddb709e9 972CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
c3f95ef1 973{
95691680 974 AssertLockHeld(cs_wallet); // mapWallet
c3f95ef1
LD
975 CWalletDB walletdb(strWalletFile);
976
977 // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
978 TxItems txOrdered;
979
980 // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
981 // would make this much faster for applications that do this a lot.
982 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
983 {
984 CWalletTx* wtx = &((*it).second);
985 txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
986 }
ddb709e9 987 acentries.clear();
c3f95ef1
LD
988 walletdb.ListAccountCreditDebit(strAccount, acentries);
989 BOOST_FOREACH(CAccountingEntry& entry, acentries)
990 {
991 txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
992 }
993
994 return txOrdered;
995}
996
1f722359
MT
997// 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
998// UTXO with the smallest coin age if there is more than one, as larger coin age will win more often and is worth saving
999// each attempt consists of taking a VerusHash of the following values:
1000// ASSETCHAINS_MAGIC, nHeight, txid, voutNum
c5325a32 1001bool CWallet::VerusSelectStakeOutput(CBlock *pBlock, arith_uint256 &hashResult, CTransaction &stakeSource, int32_t &voutNum, int32_t nHeight, uint32_t bnTarget) const
1f722359 1002{
c5325a32 1003 arith_uint256 target;
1f722359
MT
1004 arith_uint256 curHash;
1005 vector<COutput> vecOutputs;
1006 COutput *pwinner = NULL;
1007 CBlockIndex *pastBlockIndex;
1fae37f6
MT
1008 txnouttype whichType;
1009 std:vector<std::vector<unsigned char>> vSolutions;
1f722359 1010
c5325a32
MT
1011 pBlock->nNonce.SetPOSTarget(bnTarget);
1012 target.SetCompact(bnTarget);
1013
1f722359
MT
1014 pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false);
1015
c5325a32 1016 if (pastBlockIndex = komodo_chainactive(nHeight - 100))
1f722359 1017 {
c5325a32
MT
1018 CBlockHeader bh = pastBlockIndex->GetBlockHeader();
1019 uint256 pastHash = bh.GetVerusEntropyHash(nHeight);
1f722359
MT
1020
1021 BOOST_FOREACH(COutput &txout, vecOutputs)
1022 {
c5325a32 1023 if (txout.fSpendable && (UintToArith256(txout.tx->GetVerusPOSHash(&(pBlock->nNonce), txout.i, nHeight, pastHash)) <= target) && (txout.nDepth >= VERUS_MIN_STAKEAGE))
1f722359
MT
1024 {
1025 // get the smallest winner
1fae37f6
MT
1026 if (Solver(txout.tx->vout[txout.i].scriptPubKey, whichType, vSolutions) && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH) &&
1027 (!pwinner || pwinner->tx->vout[pwinner->i].nValue > txout.tx->vout[txout.i].nValue))
1f722359
MT
1028 pwinner = &txout;
1029 }
1030 }
1031 if (pwinner)
1032 {
1033 stakeSource = *(pwinner->tx);
1034 voutNum = pwinner->i;
1035 return true;
1036 }
1037 }
1038 return false;
1039}
1040
c5325a32 1041int32_t CWallet::VerusStakeTransaction(CBlock *pBlock, CMutableTransaction &txNew, uint32_t bnTarget, arith_uint256 &hashResult, uint8_t *utxosig) const
1f722359 1042{
1f722359
MT
1043 CTransaction stakeSource;
1044 int32_t voutNum, siglen = 0;
1045 int64_t nValue;
1fae37f6
MT
1046 txnouttype whichType;
1047 std::vector<std::vector<unsigned char>> vSolutions;
1f722359 1048
31bbe234
MT
1049 CBlockIndex *tipindex;
1050 {
1051 LOCK(cs_main);
1052 tipindex = chainActive.Tip();
1053 }
1f722359 1054 bnTarget = lwmaGetNextPOSRequired(tipindex, Params().GetConsensus());
1f722359 1055
c5325a32 1056 if (!VerusSelectStakeOutput(pBlock, hashResult, stakeSource, voutNum, tipindex->nHeight + 1, bnTarget) ||
1fae37f6 1057 !Solver(stakeSource.vout[voutNum].scriptPubKey, whichType, vSolutions))
1f722359 1058 {
c5325a32 1059 LogPrintf("Searched for eligible staking transactions, no winners found\n");
1f722359
MT
1060 return 0;
1061 }
1062
1f722359
MT
1063 bool signSuccess;
1064 SignatureData sigdata;
1065 uint64_t txfee;
1066 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
1067
1068 const CKeyStore& keystore = *pwalletMain;
1069 txNew.vin.resize(1);
1070 txNew.vout.resize(1);
1071 txfee = 0;
1072 txNew.vin[0].prevout.hash = stakeSource.GetHash();
1073 txNew.vin[0].prevout.n = voutNum;
1074
1fae37f6
MT
1075 if (whichType == TX_PUBKEY)
1076 {
1077 txNew.vout[0].scriptPubKey << ToByteVector(vSolutions[0]) << OP_CHECKSIG;
1078 }
1079 else if (whichType == TX_PUBKEYHASH)
1080 {
1081 txNew.vout[0].scriptPubKey << OP_DUP << OP_HASH160 << ToByteVector(vSolutions[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
1082 }
1083 else
1084 return 0;
1f722359 1085
31bbe234 1086 nValue = txNew.vout[0].nValue = stakeSource.vout[voutNum].nValue - txfee;
1f722359
MT
1087 txNew.nLockTime = 0;
1088 CTransaction txNewConst(txNew);
1089 signSuccess = ProduceSignature(TransactionSignatureCreator(&keystore, &txNewConst, 0, nValue, SIGHASH_ALL), stakeSource.vout[voutNum].scriptPubKey, sigdata, consensusBranchId);
1090 if (!signSuccess)
1091 fprintf(stderr,"failed to create signature\n");
1092 else
1093 {
1094 uint8_t *ptr;
1095 UpdateTransaction(txNew,0,sigdata);
1096 ptr = (uint8_t *)sigdata.scriptSig.data();
1097 siglen = sigdata.scriptSig.size();
1098 for (int i=0; i<siglen; i++)
1099 utxosig[i] = ptr[i];//, fprintf(stderr,"%02x",ptr[i]);
1100 }
1101 return(siglen);
1102}
1103
95d888a6
PW
1104void CWallet::MarkDirty()
1105{
95d888a6 1106 {
f8dcd5ca 1107 LOCK(cs_wallet);
95d888a6
PW
1108 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1109 item.second.MarkDirty();
1110 }
1111}
1112
1a62587e 1113/**
9a2b8ae5
JG
1114 * Ensure that every note in the wallet (for which we possess a spending key)
1115 * has a cached nullifier.
1a62587e
JG
1116 */
1117bool CWallet::UpdateNullifierNoteMap()
1118{
1119 {
1120 LOCK(cs_wallet);
1121
1122 if (IsLocked())
1123 return false;
1124
1125 ZCNoteDecryption dec;
1126 for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
1127 for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
1128 if (!item.second.nullifier) {
9a2b8ae5
JG
1129 if (GetNoteDecryptor(item.second.address, dec)) {
1130 auto i = item.first.js;
1131 auto hSig = wtxItem.second.vjoinsplit[i].h_sig(
1132 *pzcashParams, wtxItem.second.joinSplitPubKey);
1133 item.second.nullifier = GetNoteNullifier(
1134 wtxItem.second.vjoinsplit[i],
1135 item.second.address,
1136 dec,
1137 hSig,
1138 item.first.n);
1139 }
1a62587e
JG
1140 }
1141 }
6e263a5f 1142 UpdateNullifierNoteMapWithTx(wtxItem.second);
1a62587e
JG
1143 }
1144 }
1145 return true;
1146}
1147
6e263a5f
JG
1148/**
1149 * Update mapNullifiersToNotes with the cached nullifiers in this tx.
1150 */
1151void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx)
8db7e25c
JG
1152{
1153 {
1154 LOCK(cs_wallet);
1155 for (const mapNoteData_t::value_type& item : wtx.mapNoteData) {
1a62587e
JG
1156 if (item.second.nullifier) {
1157 mapNullifiersToNotes[*item.second.nullifier] = item.first;
1158 }
8db7e25c
JG
1159 }
1160 }
1161}
1162
44bc988e 1163bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
e8ef3da7 1164{
805344dc 1165 uint256 hash = wtxIn.GetHash();
731b89b8
GA
1166
1167 if (fFromLoadWallet)
1168 {
1169 mapWallet[hash] = wtxIn;
09ec3af1 1170 mapWallet[hash].BindWallet(this);
6e263a5f 1171 UpdateNullifierNoteMapWithTx(mapWallet[hash]);
93a18a36 1172 AddToSpends(hash);
731b89b8
GA
1173 }
1174 else
e8ef3da7 1175 {
f8dcd5ca 1176 LOCK(cs_wallet);
e8ef3da7
WL
1177 // Inserts only if not already there, returns tx inserted or tx found
1178 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
1179 CWalletTx& wtx = (*ret.first).second;
4c6e2295 1180 wtx.BindWallet(this);
6e263a5f 1181 UpdateNullifierNoteMapWithTx(wtx);
e8ef3da7
WL
1182 bool fInsertedNew = ret.second;
1183 if (fInsertedNew)
9c7722b7 1184 {
e8ef3da7 1185 wtx.nTimeReceived = GetAdjustedTime();
44bc988e 1186 wtx.nOrderPos = IncOrderPosNext(pwalletdb);
c3f95ef1
LD
1187
1188 wtx.nTimeSmart = wtx.nTimeReceived;
4f152496 1189 if (!wtxIn.hashBlock.IsNull())
c3f95ef1
LD
1190 {
1191 if (mapBlockIndex.count(wtxIn.hashBlock))
1192 {
209377a7 1193 int64_t latestNow = wtx.nTimeReceived;
1194 int64_t latestEntry = 0;
c3f95ef1
LD
1195 {
1196 // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
51ed9ec9 1197 int64_t latestTolerated = latestNow + 300;
ddb709e9
LD
1198 std::list<CAccountingEntry> acentries;
1199 TxItems txOrdered = OrderedTxItems(acentries);
c3f95ef1
LD
1200 for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1201 {
1202 CWalletTx *const pwtx = (*it).second.first;
1203 if (pwtx == &wtx)
1204 continue;
1205 CAccountingEntry *const pacentry = (*it).second.second;
51ed9ec9 1206 int64_t nSmartTime;
c3f95ef1
LD
1207 if (pwtx)
1208 {
1209 nSmartTime = pwtx->nTimeSmart;
1210 if (!nSmartTime)
1211 nSmartTime = pwtx->nTimeReceived;
1212 }
1213 else
1214 nSmartTime = pacentry->nTime;
1215 if (nSmartTime <= latestTolerated)
1216 {
1217 latestEntry = nSmartTime;
1218 if (nSmartTime > latestNow)
1219 latestNow = nSmartTime;
1220 break;
1221 }
1222 }
1223 }
1224
209377a7 1225 int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
c3f95ef1
LD
1226 wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
1227 }
1228 else
5262fde0 1229 LogPrintf("AddToWallet(): found %s in block %s not in index\n",
805344dc 1230 wtxIn.GetHash().ToString(),
7d9d134b 1231 wtxIn.hashBlock.ToString());
c3f95ef1 1232 }
93a18a36 1233 AddToSpends(hash);
9c7722b7 1234 }
e8ef3da7
WL
1235
1236 bool fUpdated = false;
1237 if (!fInsertedNew)
1238 {
1239 // Merge
4f152496 1240 if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
e8ef3da7
WL
1241 {
1242 wtx.hashBlock = wtxIn.hashBlock;
1243 fUpdated = true;
1244 }
1245 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
1246 {
1247 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
1248 wtx.nIndex = wtxIn.nIndex;
1249 fUpdated = true;
1250 }
ac1c9435 1251 if (UpdatedNoteData(wtxIn, wtx)) {
c3a7307a
JG
1252 fUpdated = true;
1253 }
e8ef3da7
WL
1254 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
1255 {
1256 wtx.fFromMe = wtxIn.fFromMe;
1257 fUpdated = true;
1258 }
e8ef3da7
WL
1259 }
1260
1261 //// debug print
805344dc 1262 LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
e8ef3da7
WL
1263
1264 // Write to disk
1265 if (fInsertedNew || fUpdated)
44bc988e 1266 if (!wtx.WriteToDisk(pwalletdb))
e8ef3da7 1267 return false;
ee4b170c 1268
93a18a36
GA
1269 // Break debit/credit balance caches:
1270 wtx.MarkDirty();
e8ef3da7 1271
fe4a6550
WL
1272 // Notify UI of new or updated transaction
1273 NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
cae686d3 1274
1275 // notify an external script when a wallet transaction comes in or is updated
1276 std::string strCmd = GetArg("-walletnotify", "");
1277
1278 if ( !strCmd.empty())
1279 {
805344dc 1280 boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
cae686d3 1281 boost::thread t(runCommand, strCmd); // thread runs free
1282 }
1283
fe4a6550 1284 }
e8ef3da7
WL
1285 return true;
1286}
1287
ac1c9435
JG
1288bool CWallet::UpdatedNoteData(const CWalletTx& wtxIn, CWalletTx& wtx)
1289{
1290 if (wtxIn.mapNoteData.empty() || wtxIn.mapNoteData == wtx.mapNoteData) {
1291 return false;
1292 }
1293 auto tmp = wtxIn.mapNoteData;
1294 // Ensure we keep any cached witnesses we may already have
1295 for (const std::pair<JSOutPoint, CNoteData> nd : wtx.mapNoteData) {
1296 if (tmp.count(nd.first) && nd.second.witnesses.size() > 0) {
1297 tmp.at(nd.first).witnesses.assign(
1298 nd.second.witnesses.cbegin(), nd.second.witnesses.cend());
1299 }
4a6a4847 1300 tmp.at(nd.first).witnessHeight = nd.second.witnessHeight;
ac1c9435
JG
1301 }
1302 // Now copy over the updated note data
1303 wtx.mapNoteData = tmp;
1304 return true;
1305}
1306
5b40d886
MF
1307/**
1308 * Add a transaction to the wallet, or update it.
1309 * pblock is optional, but should be provided if the transaction is known to be in a block.
1310 * If fUpdate is true, existing transactions will be updated.
1311 */
d38da59b 1312bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
e8ef3da7 1313{
e8ef3da7 1314 {
53d56881 1315 AssertLockHeld(cs_wallet);
805344dc 1316 bool fExisted = mapWallet.count(tx.GetHash()) != 0;
6cc4a62c 1317 if (fExisted && !fUpdate) return false;
c3a7307a 1318 auto noteData = FindMyNotes(tx);
e980a26d 1319 if (fExisted || IsMine(tx) || IsFromMe(tx) || noteData.size() > 0)
6cc4a62c
GA
1320 {
1321 CWalletTx wtx(this,tx);
44bc988e 1322
be74c80d 1323 if (noteData.size() > 0) {
c3a7307a 1324 wtx.SetNoteData(noteData);
be74c80d 1325 }
c3a7307a 1326
6cc4a62c
GA
1327 // Get merkle branch if transaction was found in a block
1328 if (pblock)
4b0deb3b 1329 wtx.SetMerkleBranch(*pblock);
44bc988e
CL
1330
1331 // Do not flush the wallet here for performance reasons
1332 // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
1333 CWalletDB walletdb(strWalletFile, "r+", false);
1334
1335 return AddToWallet(wtx, false, &walletdb);
6cc4a62c 1336 }
e8ef3da7 1337 }
e8ef3da7
WL
1338 return false;
1339}
1340
d38da59b 1341void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
93a18a36 1342{
55a1db4f 1343 LOCK2(cs_main, cs_wallet);
d38da59b 1344 if (!AddToWalletIfInvolvingMe(tx, pblock, true))
93a18a36
GA
1345 return; // Not one of ours
1346
ac1c9435
JG
1347 MarkAffectedTransactionsDirty(tx);
1348}
1349
1350void CWallet::MarkAffectedTransactionsDirty(const CTransaction& tx)
1351{
93a18a36
GA
1352 // If a transaction changes 'conflicted' state, that changes the balance
1353 // available of the outputs it spends. So force those to be
1354 // recomputed, also:
1355 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1356 {
1357 if (mapWallet.count(txin.prevout.hash))
1358 mapWallet[txin.prevout.hash].MarkDirty();
1359 }
8db7e25c
JG
1360 for (const JSDescription& jsdesc : tx.vjoinsplit) {
1361 for (const uint256& nullifier : jsdesc.nullifiers) {
ad20f214
JG
1362 if (mapNullifiersToNotes.count(nullifier) &&
1363 mapWallet.count(mapNullifiersToNotes[nullifier].hash)) {
1364 mapWallet[mapNullifiersToNotes[nullifier].hash].MarkDirty();
8db7e25c
JG
1365 }
1366 }
1367 }
00588c3f
PW
1368}
1369
1370void CWallet::EraseFromWallet(const uint256 &hash)
e8ef3da7
WL
1371{
1372 if (!fFileBacked)
00588c3f 1373 return;
e8ef3da7 1374 {
f8dcd5ca 1375 LOCK(cs_wallet);
e8ef3da7
WL
1376 if (mapWallet.erase(hash))
1377 CWalletDB(strWalletFile).EraseTx(hash);
1378 }
00588c3f 1379 return;
e8ef3da7
WL
1380}
1381
1382
1a62587e
JG
1383/**
1384 * Returns a nullifier if the SpendingKey is available
1385 * Throws std::runtime_error if the decryptor doesn't match this note
1386 */
1387boost::optional<uint256> CWallet::GetNoteNullifier(const JSDescription& jsdesc,
1388 const libzcash::PaymentAddress& address,
1389 const ZCNoteDecryption& dec,
1390 const uint256& hSig,
1391 uint8_t n) const
1392{
1393 boost::optional<uint256> ret;
1394 auto note_pt = libzcash::NotePlaintext::decrypt(
1395 dec,
1396 jsdesc.ciphertexts[n],
1397 jsdesc.ephemeralKey,
1398 hSig,
1399 (unsigned char) n);
1400 auto note = note_pt.note(address);
9a2b8ae5
JG
1401 // SpendingKeys are only available if:
1402 // - We have them (this isn't a viewing key)
1403 // - The wallet is unlocked
1a62587e
JG
1404 libzcash::SpendingKey key;
1405 if (GetSpendingKey(address, key)) {
1406 ret = note.nullifier(key);
1407 }
1408 return ret;
1409}
1410
e492d986
JG
1411/**
1412 * Finds all output notes in the given transaction that have been sent to
1413 * PaymentAddresses in this wallet.
1414 *
1415 * It should never be necessary to call this method with a CWalletTx, because
1416 * the result of FindMyNotes (for the addresses available at the time) will
1417 * already have been cached in CWalletTx.mapNoteData.
1418 */
02e67455
JG
1419mapNoteData_t CWallet::FindMyNotes(const CTransaction& tx) const
1420{
3fac1020 1421 LOCK(cs_SpendingKeyStore);
fa511e10 1422 uint256 hash = tx.GetHash();
02e67455
JG
1423
1424 mapNoteData_t noteData;
02e67455
JG
1425 for (size_t i = 0; i < tx.vjoinsplit.size(); i++) {
1426 auto hSig = tx.vjoinsplit[i].h_sig(*pzcashParams, tx.joinSplitPubKey);
1427 for (uint8_t j = 0; j < tx.vjoinsplit[i].ciphertexts.size(); j++) {
3fac1020 1428 for (const NoteDecryptorMap::value_type& item : mapNoteDecryptors) {
02e67455 1429 try {
02e67455 1430 auto address = item.first;
02e67455 1431 JSOutPoint jsoutpt {hash, i, j};
1a62587e
JG
1432 auto nullifier = GetNoteNullifier(
1433 tx.vjoinsplit[i],
1434 address,
1435 item.second,
1436 hSig, j);
1437 if (nullifier) {
1438 CNoteData nd {address, *nullifier};
1439 noteData.insert(std::make_pair(jsoutpt, nd));
1440 } else {
1441 CNoteData nd {address};
1442 noteData.insert(std::make_pair(jsoutpt, nd));
1443 }
02e67455 1444 break;
51fde9ea 1445 } catch (const note_decryption_failed &err) {
1a62587e 1446 // Couldn't decrypt with this decryptor
32a103aa
JG
1447 } catch (const std::exception &exc) {
1448 // Unexpected failure
1449 LogPrintf("FindMyNotes(): Unexpected error while testing decrypt:\n");
1450 LogPrintf("%s\n", exc.what());
02e67455
JG
1451 }
1452 }
1453 }
1454 }
1455 return noteData;
1456}
1457
1551db87
JG
1458bool CWallet::IsFromMe(const uint256& nullifier) const
1459{
1460 {
1461 LOCK(cs_wallet);
1462 if (mapNullifiersToNotes.count(nullifier) &&
1463 mapWallet.count(mapNullifiersToNotes.at(nullifier).hash)) {
1464 return true;
1465 }
1466 }
1467 return false;
1468}
1469
be74c80d
JG
1470void CWallet::GetNoteWitnesses(std::vector<JSOutPoint> notes,
1471 std::vector<boost::optional<ZCIncrementalWitness>>& witnesses,
1472 uint256 &final_anchor)
1473{
1474 {
1475 LOCK(cs_wallet);
1476 witnesses.resize(notes.size());
4086e5ce 1477 boost::optional<uint256> rt;
be74c80d
JG
1478 int i = 0;
1479 for (JSOutPoint note : notes) {
1480 if (mapWallet.count(note.hash) &&
1481 mapWallet[note.hash].mapNoteData.count(note) &&
1482 mapWallet[note.hash].mapNoteData[note].witnesses.size() > 0) {
1483 witnesses[i] = mapWallet[note.hash].mapNoteData[note].witnesses.front();
4086e5ce
JG
1484 if (!rt) {
1485 rt = witnesses[i]->root();
1486 } else {
1487 assert(*rt == witnesses[i]->root());
1488 }
be74c80d
JG
1489 }
1490 i++;
1491 }
4086e5ce
JG
1492 // All returned witnesses have the same anchor
1493 if (rt) {
1494 final_anchor = *rt;
be74c80d
JG
1495 }
1496 }
1497}
1498
c8988460 1499isminetype CWallet::IsMine(const CTxIn &txin) const
e8ef3da7 1500{
e8ef3da7 1501 {
f8dcd5ca 1502 LOCK(cs_wallet);
e8ef3da7
WL
1503 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1504 if (mi != mapWallet.end())
1505 {
1506 const CWalletTx& prev = (*mi).second;
1507 if (txin.prevout.n < prev.vout.size())
ea340a14 1508 return (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey));
e8ef3da7
WL
1509 }
1510 }
a3e192a3 1511 return ISMINE_NO;
e8ef3da7
WL
1512}
1513
a372168e 1514CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
e8ef3da7 1515{
e8ef3da7 1516 {
f8dcd5ca 1517 LOCK(cs_wallet);
e8ef3da7
WL
1518 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1519 if (mi != mapWallet.end())
1520 {
1521 const CWalletTx& prev = (*mi).second;
1522 if (txin.prevout.n < prev.vout.size())
ea340a14 1523 if (::IsMine(*this, prev.vout[txin.prevout.n].scriptPubKey) & filter)
47658758 1524 return prev.vout[txin.prevout.n].nValue; // komodo_interest?
e8ef3da7
WL
1525 }
1526 }
1527 return 0;
1528}
1529
eca0b1ea
JT
1530isminetype CWallet::IsMine(const CTxOut& txout) const
1531{
1532 return ::IsMine(*this, txout.scriptPubKey);
1533}
1534
1535CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
1536{
1537 if (!MoneyRange(txout.nValue))
1538 throw std::runtime_error("CWallet::GetCredit(): value out of range");
1539 return ((IsMine(txout) & filter) ? txout.nValue : 0);
1540}
1541
e679ec96
GA
1542bool CWallet::IsChange(const CTxOut& txout) const
1543{
2a45a494 1544 // TODO: fix handling of 'change' outputs. The assumption is that any
d5087d1b 1545 // payment to a script that is ours, but is not in the address book
2a45a494
GA
1546 // is change. That assumption is likely to break when we implement multisignature
1547 // wallets that return change back into a multi-signature-protected address;
1548 // a better way of identifying which outputs are 'the send' and which are
1549 // 'the change' will need to be implemented (maybe extend CWalletTx to remember
1550 // which output, if any, was change).
d5087d1b 1551 if (::IsMine(*this, txout.scriptPubKey))
f8dcd5ca 1552 {
d5087d1b
PW
1553 CTxDestination address;
1554 if (!ExtractDestination(txout.scriptPubKey, address))
1555 return true;
1556
f8dcd5ca
PW
1557 LOCK(cs_wallet);
1558 if (!mapAddressBook.count(address))
1559 return true;
1560 }
e679ec96
GA
1561 return false;
1562}
1563
eca0b1ea
JT
1564CAmount CWallet::GetChange(const CTxOut& txout) const
1565{
1566 if (!MoneyRange(txout.nValue))
1567 throw std::runtime_error("CWallet::GetChange(): value out of range");
1568 return (IsChange(txout) ? txout.nValue : 0);
1569}
1570
ea340a14 1571typedef vector<unsigned char> valtype;
1572unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore);
1573
90e75021 1574bool CWallet::IsMine(const CTransaction& tx)
eca0b1ea 1575{
90e75021 1576 for (int i = 0; i < tx.vout.size(); i++)
1577 {
1a0fc308 1578 if (IsMine(tx, i))
eca0b1ea 1579 return true;
90e75021 1580 }
1581 return false;
1582}
1583
29bd53a1
MT
1584// special case handling for non-standard/Verus OP_RETURN script outputs, which need the transaction
1585// to determine ownership
ea340a14 1586isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
29bd53a1
MT
1587{
1588 vector<valtype> vSolutions;
1589 txnouttype whichType;
1590 const CScriptExt scriptPubKey = CScriptExt(tx.vout[voutNum].scriptPubKey);
1591
1592 if (!Solver(scriptPubKey, whichType, vSolutions)) {
1593 if (this->HaveWatchOnly(scriptPubKey))
1594 return ISMINE_WATCH_ONLY;
1595 return ISMINE_NO;
1596 }
1597
1598 CKeyID keyID;
90e75021 1599 CScriptID scriptID;
29bd53a1
MT
1600 CScriptExt subscript;
1601 int voutNext = voutNum + 1;
1602
1603 switch (whichType)
1604 {
1605 case TX_NONSTANDARD:
1606 case TX_NULL_DATA:
1607 break;
1608
1609 case TX_PUBKEY:
1610 keyID = CPubKey(vSolutions[0]).GetID();
1611 if (this->HaveKey(keyID))
1612 return ISMINE_SPENDABLE;
1613 break;
1614
1615 case TX_PUBKEYHASH:
1616 keyID = CKeyID(uint160(vSolutions[0]));
1617 if (this->HaveKey(keyID))
1618 return ISMINE_SPENDABLE;
1619 break;
1620
1621 case TX_SCRIPTHASH:
90e75021 1622 scriptID = CScriptID(uint160(vSolutions[0]));
29bd53a1
MT
1623 if (this->GetCScript(scriptID, subscript))
1624 {
1625 // if this is a CLTV, handle it differently
ef70c5b2 1626 if (subscript.IsCheckLockTimeVerify())
29bd53a1 1627 {
ea340a14 1628 return (::IsMine(*this, subscript));
29bd53a1
MT
1629 }
1630 else
1631 {
1632 isminetype ret = ::IsMine(*this, subscript);
1633 if (ret == ISMINE_SPENDABLE)
1634 return ret;
1635 }
1636 }
1637 else if (tx.vout.size() > (voutNext = voutNum + 1) &&
1638 tx.vout[voutNext].scriptPubKey.size() > 7 &&
1639 tx.vout[voutNext].scriptPubKey.data()[0] == OP_RETURN)
1640 {
1641 // get the opret script from next vout, verify that the front is CLTV and hash matches
1642 // if so, remove it and use the solver
1643 opcodetype op;
1644 std::vector<uint8_t> opretData;
1645 CScript::const_iterator it = tx.vout[voutNext].scriptPubKey.begin() + 1;
1646 if (tx.vout[voutNext].scriptPubKey.GetOp2(it, op, &opretData))
1647 {
1648 if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
1649 {
e980a26d 1650 CScript opretScript = CScriptExt(opretData.begin() + 1, opretData.end());
29bd53a1
MT
1651
1652 if (CScriptID(opretScript) == scriptID &&
ef70c5b2 1653 opretScript.IsCheckLockTimeVerify())
29bd53a1 1654 {
ea340a14 1655 // if we find that this is ours, we need to add this script to the wallet,
1656 // and we can then recognize this transaction
1657 isminetype t = ::IsMine(*this, opretScript);
1658 if (t != ISMINE_NO)
1659 {
1660 this->AddCScript(opretScript);
1661 }
1662 return t;
29bd53a1
MT
1663 }
1664 }
1665 }
1666 }
1667 break;
1668
1669 case TX_MULTISIG:
1670 // Only consider transactions "mine" if we own ALL the
1671 // keys involved. Multi-signature transactions that are
1672 // partially owned (somebody else has a key that can spend
1673 // them) enable spend-out-from-under-you attacks, especially
1674 // in shared-wallet situations.
1675 vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
1676 if (HaveKeys(keys, *this) == keys.size())
1677 return ISMINE_SPENDABLE;
1678 break;
1679 }
1680
1681 if (this->HaveWatchOnly(scriptPubKey))
1682 return ISMINE_WATCH_ONLY;
1683
1684 return ISMINE_NO;
1685}
1686
eca0b1ea
JT
1687bool CWallet::IsFromMe(const CTransaction& tx) const
1688{
1551db87
JG
1689 if (GetDebit(tx, ISMINE_ALL) > 0) {
1690 return true;
1691 }
1692 for (const JSDescription& jsdesc : tx.vjoinsplit) {
1693 for (const uint256& nullifier : jsdesc.nullifiers) {
1694 if (IsFromMe(nullifier)) {
1695 return true;
1696 }
1697 }
1698 }
1699 return false;
eca0b1ea
JT
1700}
1701
1702CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
1703{
1704 CAmount nDebit = 0;
1705 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1706 {
1707 nDebit += GetDebit(txin, filter);
1708 if (!MoneyRange(nDebit))
1709 throw std::runtime_error("CWallet::GetDebit(): value out of range");
1710 }
1711 return nDebit;
1712}
1713
fab1429d 1714CAmount CWallet::GetCredit(const CTransaction& tx, int32_t voutNum, const isminefilter& filter) const
1715{
1716 if (voutNum >= tx.vout.size() || !MoneyRange(tx.vout[voutNum].nValue))
1717 throw std::runtime_error("CWallet::GetCredit(): value out of range");
ea340a14 1718 return ((IsMine(tx.vout[voutNum]) & filter) ? tx.vout[voutNum].nValue : 0);
fab1429d 1719}
1720
eca0b1ea
JT
1721CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
1722{
1723 CAmount nCredit = 0;
fab1429d 1724 for (int i = 0; i < tx.vout.size(); i++)
eca0b1ea 1725 {
fab1429d 1726 nCredit += GetCredit(tx, i, filter);
eca0b1ea
JT
1727 }
1728 return nCredit;
1729}
1730
1731CAmount CWallet::GetChange(const CTransaction& tx) const
1732{
1733 CAmount nChange = 0;
1734 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1735 {
1736 nChange += GetChange(txout);
1737 if (!MoneyRange(nChange))
1738 throw std::runtime_error("CWallet::GetChange(): value out of range");
1739 }
1740 return nChange;
1741}
1742
c3a7307a
JG
1743void CWalletTx::SetNoteData(mapNoteData_t &noteData)
1744{
1745 mapNoteData.clear();
1746 for (const std::pair<JSOutPoint, CNoteData> nd : noteData) {
1747 if (nd.first.js < vjoinsplit.size() &&
1748 nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
1749 // Store the address and nullifier for the Note
1750 mapNoteData[nd.first] = nd.second;
1751 } else {
1752 // If FindMyNotes() was used to obtain noteData,
1753 // this should never happen
32a103aa 1754 throw std::logic_error("CWalletTx::SetNoteData(): Invalid note");
c3a7307a
JG
1755 }
1756 }
1757}
1758
51ed9ec9 1759int64_t CWalletTx::GetTxTime() const
e8ef3da7 1760{
51ed9ec9 1761 int64_t n = nTimeSmart;
c3f95ef1 1762 return n ? n : nTimeReceived;
e8ef3da7
WL
1763}
1764
1765int CWalletTx::GetRequestCount() const
1766{
1767 // Returns -1 if it wasn't being tracked
1768 int nRequests = -1;
e8ef3da7 1769 {
f8dcd5ca 1770 LOCK(pwallet->cs_wallet);
e8ef3da7
WL
1771 if (IsCoinBase())
1772 {
1773 // Generated block
4f152496 1774 if (!hashBlock.IsNull())
e8ef3da7
WL
1775 {
1776 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
1777 if (mi != pwallet->mapRequestCount.end())
1778 nRequests = (*mi).second;
1779 }
1780 }
1781 else
1782 {
1783 // Did anyone request this transaction?
805344dc 1784 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
e8ef3da7
WL
1785 if (mi != pwallet->mapRequestCount.end())
1786 {
1787 nRequests = (*mi).second;
1788
1789 // How about the block it's in?
4f152496 1790 if (nRequests == 0 && !hashBlock.IsNull())
e8ef3da7
WL
1791 {
1792 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
1793 if (mi != pwallet->mapRequestCount.end())
1794 nRequests = (*mi).second;
1795 else
1796 nRequests = 1; // If it's in someone else's block it must have got out
1797 }
1798 }
1799 }
1800 }
1801 return nRequests;
1802}
1803
86cf60b5 1804// GetAmounts will determine the transparent debits and credits for a given wallet tx.
1b4568cb 1805void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
a372168e 1806 list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
e8ef3da7 1807{
e07c8e91 1808 nFee = 0;
e8ef3da7
WL
1809 listReceived.clear();
1810 listSent.clear();
1811 strSentAccount = strFromAccount;
1812
86cf60b5 1813 // Is this tx sent/signed by me?
a372168e 1814 CAmount nDebit = GetDebit(filter);
86cf60b5
S
1815 bool isFromMyTaddr = nDebit > 0; // debit>0 means we signed/sent this transaction
1816
1817 // Does this tx spend my notes?
1818 bool isFromMyZaddr = false;
1819 for (const JSDescription& js : vjoinsplit) {
1820 for (const uint256& nullifier : js.nullifiers) {
1821 if (pwallet->IsFromMe(nullifier)) {
1822 isFromMyZaddr = true;
1823 break;
1824 }
1825 }
1826 if (isFromMyZaddr) {
1827 break;
1828 }
1829 }
1830
1831 // Compute fee if we sent this transaction.
1832 if (isFromMyTaddr) {
1833 CAmount nValueOut = GetValueOut(); // transparent outputs plus all vpub_old
1834 CAmount nValueIn = 0;
1835 for (const JSDescription & js : vjoinsplit) {
1836 nValueIn += js.vpub_new;
1837 }
1838 nFee = nDebit - nValueOut + nValueIn;
1839 }
1840
1841 // Create output entry for vpub_old/new, if we sent utxos from this transaction
1842 if (isFromMyTaddr) {
1843 CAmount myVpubOld = 0;
1844 CAmount myVpubNew = 0;
1845 for (const JSDescription& js : vjoinsplit) {
1846 bool fMyJSDesc = false;
1847
1848 // Check input side
1849 for (const uint256& nullifier : js.nullifiers) {
1850 if (pwallet->IsFromMe(nullifier)) {
1851 fMyJSDesc = true;
1852 break;
1853 }
1854 }
1855
1856 // Check output side
1857 if (!fMyJSDesc) {
1858 for (const std::pair<JSOutPoint, CNoteData> nd : this->mapNoteData) {
1859 if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
1860 fMyJSDesc = true;
1861 break;
1862 }
1863 }
1864 }
1865
1866 if (fMyJSDesc) {
1867 myVpubOld += js.vpub_old;
1868 myVpubNew += js.vpub_new;
1869 }
1870
1871 if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) {
1872 throw std::runtime_error("CWalletTx::GetAmounts: value out of range");
1873 }
1874 }
1875
1876 // Create an output for the value taken from or added to the transparent value pool by JoinSplits
1877 if (myVpubOld > myVpubNew) {
1878 COutputEntry output = {CNoDestination(), myVpubOld - myVpubNew, (int)vout.size()};
1879 listSent.push_back(output);
1880 } else if (myVpubNew > myVpubOld) {
1881 COutputEntry output = {CNoDestination(), myVpubNew - myVpubOld, (int)vout.size()};
1882 listReceived.push_back(output);
1883 }
e8ef3da7
WL
1884 }
1885
e679ec96 1886 // Sent/received.
5bb76550 1887 for (unsigned int i = 0; i < vout.size(); ++i)
e8ef3da7 1888 {
1b4568cb 1889 const CTxOut& txout = vout[i];
a5c6c5d6 1890 isminetype fIsMine = pwallet->IsMine(txout);
96ed6821
LD
1891 // Only need to handle txouts if AT LEAST one of these is true:
1892 // 1) they debit from us (sent)
1893 // 2) the output is to us (received)
1894 if (nDebit > 0)
1895 {
1896 // Don't report 'change' txouts
1897 if (pwallet->IsChange(txout))
1898 continue;
96ed6821 1899 }
a5c6c5d6 1900 else if (!(fIsMine & filter))
96ed6821
LD
1901 continue;
1902
1903 // In either case, we need to get the destination address
10254401 1904 CTxDestination address;
10254401 1905 if (!ExtractDestination(txout.scriptPubKey, address))
e8ef3da7 1906 {
7d306d64 1907 //LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",this->GetHash().ToString()); complains on the opreturns
96ed6821 1908 address = CNoDestination();
e8ef3da7
WL
1909 }
1910
5bb76550 1911 COutputEntry output = {address, txout.nValue, (int)i};
1b4568cb 1912
96ed6821 1913 // If we are debited by the transaction, add the output as a "sent" entry
e8ef3da7 1914 if (nDebit > 0)
1b4568cb 1915 listSent.push_back(output);
e8ef3da7 1916
96ed6821 1917 // If we are receiving the output, add it as a "received" entry
d512534c 1918 if (fIsMine & filter)
1b4568cb 1919 listReceived.push_back(output);
e8ef3da7
WL
1920 }
1921
1922}
1923
a372168e
MF
1924void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
1925 CAmount& nSent, CAmount& nFee, const isminefilter& filter) const
e8ef3da7 1926{
e07c8e91 1927 nReceived = nSent = nFee = 0;
e8ef3da7 1928
a372168e 1929 CAmount allFee;
e8ef3da7 1930 string strSentAccount;
1b4568cb
CL
1931 list<COutputEntry> listReceived;
1932 list<COutputEntry> listSent;
d4640d7d 1933 GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
e8ef3da7 1934
e8ef3da7
WL
1935 if (strAccount == strSentAccount)
1936 {
1b4568cb
CL
1937 BOOST_FOREACH(const COutputEntry& s, listSent)
1938 nSent += s.amount;
e8ef3da7
WL
1939 nFee = allFee;
1940 }
e8ef3da7 1941 {
f8dcd5ca 1942 LOCK(pwallet->cs_wallet);
1b4568cb 1943 BOOST_FOREACH(const COutputEntry& r, listReceived)
e8ef3da7 1944 {
1b4568cb 1945 if (pwallet->mapAddressBook.count(r.destination))
e8ef3da7 1946 {
1b4568cb 1947 map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
61885513 1948 if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
1b4568cb 1949 nReceived += r.amount;
e8ef3da7
WL
1950 }
1951 else if (strAccount.empty())
1952 {
1b4568cb 1953 nReceived += r.amount;
e8ef3da7
WL
1954 }
1955 }
1956 }
1957}
1958
722fa283 1959
44bc988e 1960bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
e8ef3da7 1961{
805344dc 1962 return pwalletdb->WriteTx(GetHash(), *this);
e8ef3da7
WL
1963}
1964
4bc00dc1
DH
1965void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
1966 std::vector<boost::optional<ZCIncrementalWitness>>& witnesses,
1967 uint256 &final_anchor)
a8ac403d 1968{
2dc35992 1969 witnesses.resize(commitments.size());
a8ac403d 1970 CBlockIndex* pindex = chainActive.Genesis();
1760b3cd 1971 ZCIncrementalMerkleTree tree;
a8ac403d
SB
1972
1973 while (pindex) {
1974 CBlock block;
b8add6a4 1975 ReadBlockFromDisk(block, pindex,1);
a8ac403d
SB
1976
1977 BOOST_FOREACH(const CTransaction& tx, block.vtx)
1978 {
22de1602 1979 BOOST_FOREACH(const JSDescription& jsdesc, tx.vjoinsplit)
a8ac403d 1980 {
22de1602 1981 BOOST_FOREACH(const uint256 &note_commitment, jsdesc.commitments)
a8ac403d 1982 {
4bc00dc1 1983 tree.append(note_commitment);
1760b3cd 1984
2dc35992
SB
1985 BOOST_FOREACH(boost::optional<ZCIncrementalWitness>& wit, witnesses) {
1986 if (wit) {
4bc00dc1 1987 wit->append(note_commitment);
2dc35992
SB
1988 }
1989 }
1990
1991 size_t i = 0;
1992 BOOST_FOREACH(uint256& commitment, commitments) {
4bc00dc1 1993 if (note_commitment == commitment) {
2dc35992 1994 witnesses.at(i) = tree.witness();
1760b3cd 1995 }
2dc35992 1996 i++;
a8ac403d
SB
1997 }
1998 }
1999 }
2000 }
2001
ccb439c5 2002 uint256 current_anchor = tree.root();
a8ac403d
SB
2003
2004 // Consistency check: we should be able to find the current tree
2005 // in our CCoins view.
434f3284 2006 ZCIncrementalMerkleTree dummy_tree;
a8ac403d
SB
2007 assert(pcoinsTip->GetAnchorAt(current_anchor, dummy_tree));
2008
2009 pindex = chainActive.Next(pindex);
2010 }
2011
ccb439c5
SB
2012 // TODO: #93; Select a root via some heuristic.
2013 final_anchor = tree.root();
a8ac403d 2014
2dc35992
SB
2015 BOOST_FOREACH(boost::optional<ZCIncrementalWitness>& wit, witnesses) {
2016 if (wit) {
2017 assert(final_anchor == wit->root());
2018 }
1760b3cd 2019 }
a8ac403d
SB
2020}
2021
5b40d886
MF
2022/**
2023 * Scan the block chain (starting in pindexStart) for transactions
2024 * from or to us. If fUpdate is true, found transactions that already
2025 * exist in the wallet will be updated.
2026 */
e8ef3da7
WL
2027int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
2028{
2029 int ret = 0;
75b8953a 2030 int64_t nNow = GetTime();
11982d36 2031 const CChainParams& chainParams = Params();
e8ef3da7
WL
2032
2033 CBlockIndex* pindex = pindexStart;
e8ef3da7 2034 {
55a1db4f 2035 LOCK2(cs_main, cs_wallet);
39278369
CL
2036
2037 // no need to read and scan block, if block was created before
2038 // our wallet birthday (as adjusted for block time variability)
209377a7 2039 while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
39278369
CL
2040 pindex = chainActive.Next(pindex);
2041
2042 ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
11982d36
CF
2043 double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
2044 double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false);
e8ef3da7
WL
2045 while (pindex)
2046 {
39278369 2047 if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
11982d36 2048 ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
8da9dd07 2049
e8ef3da7 2050 CBlock block;
b8add6a4 2051 ReadBlockFromDisk(block, pindex,1);
e8ef3da7
WL
2052 BOOST_FOREACH(CTransaction& tx, block.vtx)
2053 {
d38da59b 2054 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
e8ef3da7
WL
2055 ret++;
2056 }
b6961fc1
JG
2057
2058 ZCIncrementalMerkleTree tree;
2059 // This should never fail: we should always be able to get the tree
2060 // state on the path to the tip of our chain
2061 assert(pcoinsTip->GetAnchorAt(pindex->hashAnchor, tree));
2062 // Increment note witness caches
2063 IncrementNoteWitnesses(pindex, &block, tree);
2064
4c6d41b8 2065 pindex = chainActive.Next(pindex);
75b8953a
B
2066 if (GetTime() >= nNow + 60) {
2067 nNow = GetTime();
11982d36 2068 LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
75b8953a 2069 }
e8ef3da7 2070 }
39278369 2071 ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
e8ef3da7
WL
2072 }
2073 return ret;
2074}
2075
2076void CWallet::ReacceptWalletTransactions()
2077{
7e6d23b1 2078 // If transactions aren't being broadcasted, don't let them into local mempool either
6f252627
WL
2079 if (!fBroadcastTransactions)
2080 return;
55a1db4f 2081 LOCK2(cs_main, cs_wallet);
e9c3215b 2082 std::map<int64_t, CWalletTx*> mapSorted;
2083
2084 // Sort pending wallet transactions based on their initial wallet insertion order
93a18a36 2085 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
e8ef3da7 2086 {
93a18a36
GA
2087 const uint256& wtxid = item.first;
2088 CWalletTx& wtx = item.second;
805344dc 2089 assert(wtx.GetHash() == wtxid);
e8ef3da7 2090
93a18a36
GA
2091 int nDepth = wtx.GetDepthInMainChain();
2092
e9c3215b 2093 if (!wtx.IsCoinBase() && nDepth < 0) {
2094 mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
e8ef3da7
WL
2095 }
2096 }
e9c3215b 2097
2098 // Try to add wallet transactions to memory pool
2099 BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted)
2100 {
2101 CWalletTx& wtx = *(item.second);
2102
2103 LOCK(mempool.cs);
2104 wtx.AcceptToMemoryPool(false);
2105 }
e8ef3da7
WL
2106}
2107
0f5954c4 2108bool CWalletTx::RelayWalletTransaction()
e8ef3da7 2109{
6f252627 2110 assert(pwallet->GetBroadcastTransactions());
e8ef3da7
WL
2111 if (!IsCoinBase())
2112 {
5eaf91a4 2113 if (GetDepthInMainChain() == 0) {
805344dc 2114 LogPrintf("Relaying wtx %s\n", GetHash().ToString());
d38da59b 2115 RelayTransaction((CTransaction)*this);
0f5954c4 2116 return true;
e8ef3da7
WL
2117 }
2118 }
0f5954c4 2119 return false;
e8ef3da7
WL
2120}
2121
3015e0bc 2122set<uint256> CWalletTx::GetConflicts() const
731b89b8
GA
2123{
2124 set<uint256> result;
2125 if (pwallet != NULL)
2126 {
805344dc 2127 uint256 myHash = GetHash();
3015e0bc 2128 result = pwallet->GetConflicts(myHash);
731b89b8
GA
2129 result.erase(myHash);
2130 }
2131 return result;
2132}
2133
bbacd882
CF
2134CAmount CWalletTx::GetDebit(const isminefilter& filter) const
2135{
2136 if (vin.empty())
2137 return 0;
2138
2139 CAmount debit = 0;
2140 if(filter & ISMINE_SPENDABLE)
2141 {
2142 if (fDebitCached)
2143 debit += nDebitCached;
2144 else
2145 {
2146 nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
2147 fDebitCached = true;
2148 debit += nDebitCached;
2149 }
2150 }
2151 if(filter & ISMINE_WATCH_ONLY)
2152 {
2153 if(fWatchDebitCached)
2154 debit += nWatchDebitCached;
2155 else
2156 {
2157 nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
2158 fWatchDebitCached = true;
2159 debit += nWatchDebitCached;
2160 }
2161 }
2162 return debit;
2163}
2164
2165CAmount CWalletTx::GetCredit(const isminefilter& filter) const
2166{
2167 // Must wait until coinbase is safely deep enough in the chain before valuing it
2168 if (IsCoinBase() && GetBlocksToMaturity() > 0)
2169 return 0;
2170
2171 int64_t credit = 0;
2172 if (filter & ISMINE_SPENDABLE)
2173 {
2174 // GetBalance can assume transactions in mapWallet won't change
2175 if (fCreditCached)
2176 credit += nCreditCached;
2177 else
2178 {
2179 nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
2180 fCreditCached = true;
2181 credit += nCreditCached;
2182 }
2183 }
2184 if (filter & ISMINE_WATCH_ONLY)
2185 {
2186 if (fWatchCreditCached)
2187 credit += nWatchCreditCached;
2188 else
2189 {
2190 nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
2191 fWatchCreditCached = true;
2192 credit += nWatchCreditCached;
2193 }
2194 }
2195 return credit;
2196}
2197
2198CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
2199{
2200 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
2201 {
2202 if (fUseCache && fImmatureCreditCached)
2203 return nImmatureCreditCached;
2204 nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
2205 fImmatureCreditCached = true;
2206 return nImmatureCreditCached;
2207 }
2208
2209 return 0;
2210}
2211
2212CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
2213{
2214 if (pwallet == 0)
2215 return 0;
2216
2217 // Must wait until coinbase is safely deep enough in the chain before valuing it
2218 if (IsCoinBase() && GetBlocksToMaturity() > 0)
2219 return 0;
2220
2221 if (fUseCache && fAvailableCreditCached)
2222 return nAvailableCreditCached;
2223
2224 CAmount nCredit = 0;
805344dc 2225 uint256 hashTx = GetHash();
bbacd882
CF
2226 for (unsigned int i = 0; i < vout.size(); i++)
2227 {
2228 if (!pwallet->IsSpent(hashTx, i))
2229 {
fab1429d 2230 nCredit += pwallet->GetCredit(*this, i, ISMINE_SPENDABLE);
bbacd882
CF
2231 if (!MoneyRange(nCredit))
2232 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
2233 }
2234 }
2235
2236 nAvailableCreditCached = nCredit;
2237 fAvailableCreditCached = true;
2238 return nCredit;
2239}
2240
2241CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
2242{
2243 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
2244 {
2245 if (fUseCache && fImmatureWatchCreditCached)
2246 return nImmatureWatchCreditCached;
2247 nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
2248 fImmatureWatchCreditCached = true;
2249 return nImmatureWatchCreditCached;
2250 }
2251
2252 return 0;
2253}
2254
2255CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
2256{
2257 if (pwallet == 0)
2258 return 0;
2259
2260 // Must wait until coinbase is safely deep enough in the chain before valuing it
2261 if (IsCoinBase() && GetBlocksToMaturity() > 0)
2262 return 0;
2263
2264 if (fUseCache && fAvailableWatchCreditCached)
2265 return nAvailableWatchCreditCached;
2266
2267 CAmount nCredit = 0;
2268 for (unsigned int i = 0; i < vout.size(); i++)
2269 {
805344dc 2270 if (!pwallet->IsSpent(GetHash(), i))
bbacd882 2271 {
fab1429d 2272 nCredit += pwallet->GetCredit(*this, i, ISMINE_WATCH_ONLY);
bbacd882
CF
2273 if (!MoneyRange(nCredit))
2274 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
2275 }
2276 }
2277
2278 nAvailableWatchCreditCached = nCredit;
2279 fAvailableWatchCreditCached = true;
2280 return nCredit;
2281}
2282
2283CAmount CWalletTx::GetChange() const
2284{
2285 if (fChangeCached)
2286 return nChangeCached;
2287 nChangeCached = pwallet->GetChange(*this);
2288 fChangeCached = true;
2289 return nChangeCached;
2290}
2291
2292bool CWalletTx::IsTrusted() const
2293{
2294 // Quick answer in most cases
75a4d512 2295 if (!CheckFinalTx(*this))
bbacd882
CF
2296 return false;
2297 int nDepth = GetDepthInMainChain();
2298 if (nDepth >= 1)
2299 return true;
2300 if (nDepth < 0)
2301 return false;
2302 if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
2303 return false;
2304
2305 // Trusted if all inputs are from us and are in the mempool:
2306 BOOST_FOREACH(const CTxIn& txin, vin)
2307 {
2308 // Transactions not sent by us: not trusted
2309 const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
2310 if (parent == NULL)
2311 return false;
2312 const CTxOut& parentOut = parent->vout[txin.prevout.n];
2313 if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
2314 return false;
2315 }
2316 return true;
2317}
2318
0f5954c4
GA
2319std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
2320{
2321 std::vector<uint256> result;
2322
2323 LOCK(cs_wallet);
2324 // Sort them in chronological order
2325 multimap<unsigned int, CWalletTx*> mapSorted;
2326 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
2327 {
2328 CWalletTx& wtx = item.second;
2329 // Don't rebroadcast if newer than nTime:
2330 if (wtx.nTimeReceived > nTime)
2331 continue;
2332 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
2333 }
2334 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
2335 {
2336 CWalletTx& wtx = *item.second;
2337 if (wtx.RelayWalletTransaction())
805344dc 2338 result.push_back(wtx.GetHash());
0f5954c4
GA
2339 }
2340 return result;
2341}
2342
2343void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
e8ef3da7
WL
2344{
2345 // Do this infrequently and randomly to avoid giving away
2346 // that these are our transactions.
6f252627 2347 if (GetTime() < nNextResend || !fBroadcastTransactions)
e8ef3da7 2348 return;
203d1ae6
LD
2349 bool fFirst = (nNextResend == 0);
2350 nNextResend = GetTime() + GetRand(30 * 60);
e8ef3da7
WL
2351 if (fFirst)
2352 return;
2353
2354 // Only do it if there's been a new block since last time
0f5954c4 2355 if (nBestBlockTime < nLastResend)
e8ef3da7 2356 return;
203d1ae6 2357 nLastResend = GetTime();
e8ef3da7 2358
0f5954c4
GA
2359 // Rebroadcast unconfirmed txes older than 5 minutes before the last
2360 // block was found:
2361 std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
2362 if (!relayed.empty())
2363 LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
e8ef3da7
WL
2364}
2365
5b40d886 2366/** @} */ // end of mapWallet
e8ef3da7
WL
2367
2368
2369
2370
5b40d886
MF
2371/** @defgroup Actions
2372 *
2373 * @{
2374 */
e8ef3da7
WL
2375
2376
a372168e 2377CAmount CWallet::GetBalance() const
e8ef3da7 2378{
a372168e 2379 CAmount nTotal = 0;
e8ef3da7 2380 {
55a1db4f 2381 LOCK2(cs_main, cs_wallet);
e8ef3da7
WL
2382 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2383 {
2384 const CWalletTx* pcoin = &(*it).second;
0542619d 2385 if (pcoin->IsTrusted())
8fdb7e10 2386 nTotal += pcoin->GetAvailableCredit();
e8ef3da7
WL
2387 }
2388 }
2389
e8ef3da7
WL
2390 return nTotal;
2391}
2392
a372168e 2393CAmount CWallet::GetUnconfirmedBalance() const
df5ccbd2 2394{
a372168e 2395 CAmount nTotal = 0;
df5ccbd2 2396 {
55a1db4f 2397 LOCK2(cs_main, cs_wallet);
df5ccbd2
WL
2398 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2399 {
2400 const CWalletTx* pcoin = &(*it).second;
75a4d512 2401 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
8fdb7e10 2402 nTotal += pcoin->GetAvailableCredit();
2403 }
2404 }
2405 return nTotal;
2406}
2407
a372168e 2408CAmount CWallet::GetImmatureBalance() const
8fdb7e10 2409{
a372168e 2410 CAmount nTotal = 0;
8fdb7e10 2411 {
55a1db4f 2412 LOCK2(cs_main, cs_wallet);
8fdb7e10 2413 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2414 {
966a0e8c
PK
2415 const CWalletTx* pcoin = &(*it).second;
2416 nTotal += pcoin->GetImmatureCredit();
df5ccbd2
WL
2417 }
2418 }
2419 return nTotal;
2420}
e8ef3da7 2421
a372168e 2422CAmount CWallet::GetWatchOnlyBalance() const
ffd40da3 2423{
a372168e 2424 CAmount nTotal = 0;
ffd40da3 2425 {
39cc4922 2426 LOCK2(cs_main, cs_wallet);
ffd40da3
J
2427 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2428 {
2429 const CWalletTx* pcoin = &(*it).second;
2430 if (pcoin->IsTrusted())
2431 nTotal += pcoin->GetAvailableWatchOnlyCredit();
2432 }
2433 }
870da77d 2434
ffd40da3
J
2435 return nTotal;
2436}
2437
a372168e 2438CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
ffd40da3 2439{
a372168e 2440 CAmount nTotal = 0;
ffd40da3 2441 {
39cc4922 2442 LOCK2(cs_main, cs_wallet);
ffd40da3
J
2443 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2444 {
2445 const CWalletTx* pcoin = &(*it).second;
75a4d512 2446 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
ffd40da3
J
2447 nTotal += pcoin->GetAvailableWatchOnlyCredit();
2448 }
2449 }
2450 return nTotal;
2451}
2452
a372168e 2453CAmount CWallet::GetImmatureWatchOnlyBalance() const
ffd40da3 2454{
a372168e 2455 CAmount nTotal = 0;
ffd40da3 2456 {
39cc4922 2457 LOCK2(cs_main, cs_wallet);
ffd40da3
J
2458 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2459 {
2460 const CWalletTx* pcoin = &(*it).second;
2461 nTotal += pcoin->GetImmatureWatchOnlyCredit();
2462 }
2463 }
2464 return nTotal;
2465}
2466
5b40d886
MF
2467/**
2468 * populate vCoins with vector of available COutputs.
2469 */
79383e0a 2470uint64_t komodo_interestnew(int32_t txheight,uint64_t nValue,uint32_t nLockTime,uint32_t tiptime);
c60397dd 2471uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 hash,int32_t n,int32_t checkheight,uint64_t checkvalue,int32_t tipheight);
0ad6a463 2472
be4f847b 2473void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue, bool fIncludeCoinBase) const
9b0369c7 2474{
5c439232 2475 uint64_t interest,*ptr;
9b0369c7
CM
2476 vCoins.clear();
2477
2478 {
ea3acaf3 2479 LOCK2(cs_main, cs_wallet);
9b0369c7
CM
2480 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2481 {
93a18a36 2482 const uint256& wtxid = it->first;
9b0369c7
CM
2483 const CWalletTx* pcoin = &(*it).second;
2484
75a4d512 2485 if (!CheckFinalTx(*pcoin))
a2709fad
GA
2486 continue;
2487
0542619d 2488 if (fOnlyConfirmed && !pcoin->IsTrusted())
9b0369c7
CM
2489 continue;
2490
2b1cda3b
S
2491 if (pcoin->IsCoinBase() && !fIncludeCoinBase)
2492 continue;
2493
9b0369c7
CM
2494 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
2495 continue;
2496
2b72d46f
GA
2497 int nDepth = pcoin->GetDepthInMainChain();
2498 if (nDepth < 0)
2499 continue;
53dce971 2500
fab1429d 2501 for (int i = 0; i < pcoin->vout.size(); i++)
0ad6a463 2502 {
ea340a14 2503 isminetype mine = IsMine(pcoin->vout[i]);
a3e192a3 2504 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
219953ce 2505 !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
6a86c24d 2506 (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
0ad6a463 2507 {
6ad13d7c 2508 if ( KOMODO_EXCHANGEWALLET == 0 )
0ad6a463 2509 {
6ad13d7c 2510 uint32_t locktime; int32_t txheight; CBlockIndex *tipindex;
2511 if ( ASSETCHAINS_SYMBOL[0] == 0 && chainActive.Tip() != 0 && chainActive.Tip()->nHeight >= 60000 )
0ad6a463 2512 {
6ad13d7c 2513 if ( pcoin->vout[i].nValue >= 10*COIN )
9d92c93d 2514 {
6ad13d7c 2515 if ( (tipindex= chainActive.Tip()) != 0 )
2516 {
c60397dd 2517 komodo_accrued_interest(&txheight,&locktime,wtxid,i,0,pcoin->vout[i].nValue,(int32_t)tipindex->nHeight);
79383e0a 2518 interest = komodo_interestnew(txheight,pcoin->vout[i].nValue,locktime,tipindex->nTime);
6ad13d7c 2519 } else interest = 0;
79383e0a 2520 //interest = komodo_interestnew(chainActive.Tip()->nHeight+1,pcoin->vout[i].nValue,pcoin->nLockTime,chainActive.Tip()->nTime);
6ad13d7c 2521 if ( interest != 0 )
2522 {
2523 //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);
2524 //fprintf(stderr,"wallet nValueRet %.8f += interest %.8f ht.%d lock.%u tip.%u\n",(double)pcoin->vout[i].nValue/COIN,(double)interest/COIN,chainActive.Tip()->nHeight+1,pcoin->nLockTime,chainActive.Tip()->nTime);
2525 //ptr = (uint64_t *)&pcoin->vout[i].nValue;
2526 //(*ptr) += interest;
2527 ptr = (uint64_t *)&pcoin->vout[i].interest;
2528 (*ptr) = interest;
2529 //pcoin->vout[i].nValue += interest;
2530 }
2531 else
2532 {
2533 ptr = (uint64_t *)&pcoin->vout[i].interest;
2534 (*ptr) = 0;
2535 }
e9e8044e 2536 }
258748f5 2537 else
2538 {
2539 ptr = (uint64_t *)&pcoin->vout[i].interest;
2540 (*ptr) = 0;
2541 }
0ad6a463 2542 }
258748f5 2543 else
2544 {
2545 ptr = (uint64_t *)&pcoin->vout[i].interest;
2546 (*ptr) = 0;
2547 }
2548 }
0ad6a463 2549 vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
2550 }
fdbb537d 2551 }
9b0369c7
CM
2552 }
2553 }
2554}
2555
0ad6a463 2556static 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)
831f59ce
CM
2557{
2558 vector<char> vfIncluded;
2559
2560 vfBest.assign(vValue.size(), true);
2561 nBest = nTotalLower;
2562
907a2aa4
GM
2563 seed_insecure_rand();
2564
831f59ce
CM
2565 for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
2566 {
2567 vfIncluded.assign(vValue.size(), false);
a372168e 2568 CAmount nTotal = 0;
831f59ce
CM
2569 bool fReachedTarget = false;
2570 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
2571 {
2572 for (unsigned int i = 0; i < vValue.size(); i++)
2573 {
907a2aa4
GM
2574 //The solver here uses a randomized algorithm,
2575 //the randomness serves no real security purpose but is just
2576 //needed to prevent degenerate behavior and it is important
5b40d886 2577 //that the rng is fast. We do not use a constant random sequence,
907a2aa4
GM
2578 //because there may be some privacy improvement by making
2579 //the selection random.
2580 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
831f59ce
CM
2581 {
2582 nTotal += vValue[i].first;
2583 vfIncluded[i] = true;
2584 if (nTotal >= nTargetValue)
2585 {
2586 fReachedTarget = true;
2587 if (nTotal < nBest)
2588 {
2589 nBest = nTotal;
2590 vfBest = vfIncluded;
2591 }
2592 nTotal -= vValue[i].first;
2593 vfIncluded[i] = false;
2594 }
2595 }
2596 }
2597 }
2598 }
2599}
2600
79383e0a 2601bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
e8ef3da7 2602{
79383e0a 2603 int32_t count = 0; //uint64_t lowest_interest = 0;
e8ef3da7 2604 setCoinsRet.clear();
79383e0a 2605 //memset(interests,0,sizeof(interests));
e8ef3da7 2606 nValueRet = 0;
e8ef3da7 2607 // List of values less than target
a372168e
MF
2608 pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
2609 coinLowestLarger.first = std::numeric_limits<CAmount>::max();
e8ef3da7 2610 coinLowestLarger.second.first = NULL;
a372168e
MF
2611 vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
2612 CAmount nTotalLower = 0;
e8ef3da7 2613
e333ab56
CM
2614 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
2615
c8988460 2616 BOOST_FOREACH(const COutput &output, vCoins)
e8ef3da7 2617 {
c8988460
PW
2618 if (!output.fSpendable)
2619 continue;
2620
9b0369c7 2621 const CWalletTx *pcoin = output.tx;
e8ef3da7 2622
a3e192a3 2623 if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
9b0369c7 2624 continue;
e8ef3da7 2625
9b0369c7 2626 int i = output.i;
a372168e 2627 CAmount n = pcoin->vout[i].nValue;
e8ef3da7 2628
a372168e 2629 pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
e8ef3da7 2630
9b0369c7
CM
2631 if (n == nTargetValue)
2632 {
2633 setCoinsRet.insert(coin.second);
2634 nValueRet += coin.first;
79383e0a 2635 //if ( KOMODO_EXCHANGEWALLET == 0 )
2636 // *interestp += pcoin->vout[i].interest;
9b0369c7
CM
2637 return true;
2638 }
2639 else if (n < nTargetValue + CENT)
2640 {
2641 vValue.push_back(coin);
2642 nTotalLower += n;
79383e0a 2643 //if ( KOMODO_EXCHANGEWALLET == 0 && count < sizeof(interests)/sizeof(*interests) )
2644 //{
9067057a 2645 //fprintf(stderr,"count.%d %.8f\n",count,(double)pcoin->vout[i].interest/COIN);
79383e0a 2646 //interests[count++] = pcoin->vout[i].interest;
2647 //}
2648 if ( nTotalLower > 4*nTargetValue + CENT )
92c2aa6b 2649 {
eaba9a27 2650 //fprintf(stderr,"why bother with all the utxo if we have double what is needed?\n");
92c2aa6b 2651 break;
2652 }
9b0369c7
CM
2653 }
2654 else if (n < coinLowestLarger.first)
2655 {
2656 coinLowestLarger = coin;
79383e0a 2657 //if ( KOMODO_EXCHANGEWALLET == 0 )
2658 // lowest_interest = pcoin->vout[i].interest;
e8ef3da7
WL
2659 }
2660 }
2661
831f59ce 2662 if (nTotalLower == nTargetValue)
e8ef3da7 2663 {
c376ac35 2664 for (unsigned int i = 0; i < vValue.size(); ++i)
e8ef3da7
WL
2665 {
2666 setCoinsRet.insert(vValue[i].second);
2667 nValueRet += vValue[i].first;
79383e0a 2668 //if ( KOMODO_EXCHANGEWALLET == 0 && i < count )
2669 // *interestp += interests[i];
e8ef3da7
WL
2670 }
2671 return true;
2672 }
2673
831f59ce 2674 if (nTotalLower < nTargetValue)
e8ef3da7
WL
2675 {
2676 if (coinLowestLarger.second.first == NULL)
2677 return false;
2678 setCoinsRet.insert(coinLowestLarger.second);
2679 nValueRet += coinLowestLarger.first;
79383e0a 2680 //if ( KOMODO_EXCHANGEWALLET == 0 )
2681 // *interestp += lowest_interest;
e8ef3da7
WL
2682 return true;
2683 }
2684
e8ef3da7 2685 // Solve subset sum by stochastic approximation
d650f96d 2686 sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
831f59ce 2687 vector<char> vfBest;
a372168e 2688 CAmount nBest;
e8ef3da7 2689
831f59ce
CM
2690 ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
2691 if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
2692 ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
e8ef3da7 2693
831f59ce
CM
2694 // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
2695 // or the next bigger coin is closer), return the bigger coin
2696 if (coinLowestLarger.second.first &&
2697 ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
e8ef3da7
WL
2698 {
2699 setCoinsRet.insert(coinLowestLarger.second);
2700 nValueRet += coinLowestLarger.first;
79383e0a 2701 //if ( KOMODO_EXCHANGEWALLET == 0 )
2702 // *interestp += lowest_interest;
e8ef3da7
WL
2703 }
2704 else {
c376ac35 2705 for (unsigned int i = 0; i < vValue.size(); i++)
e8ef3da7
WL
2706 if (vfBest[i])
2707 {
2708 setCoinsRet.insert(vValue[i].second);
2709 nValueRet += vValue[i].first;
79383e0a 2710 //if ( KOMODO_EXCHANGEWALLET == 0 && i < count )
2711 // *interestp += interests[i];
e8ef3da7
WL
2712 }
2713
faaeae1e 2714 LogPrint("selectcoins", "SelectCoins() best subset: ");
c376ac35 2715 for (unsigned int i = 0; i < vValue.size(); i++)
e8ef3da7 2716 if (vfBest[i])
4f0f864d 2717 LogPrint("selectcoins", "%s", FormatMoney(vValue[i].first));
7d9d134b 2718 LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
e8ef3da7
WL
2719 }
2720
2721 return true;
2722}
2723
79383e0a 2724bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl) const
e8ef3da7 2725{
2b1cda3b 2726 // Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
79383e0a 2727 uint64_t tmp; int32_t retval;
2728 //if ( interestp == 0 )
2729 //{
2730 // interestp = &tmp;
2731 // *interestp = 0;
2732 //}
2b1cda3b
S
2733 vector<COutput> vCoinsNoCoinbase, vCoinsWithCoinbase;
2734 AvailableCoins(vCoinsNoCoinbase, true, coinControl, false, false);
2735 AvailableCoins(vCoinsWithCoinbase, true, coinControl, false, true);
2736 fOnlyCoinbaseCoinsRet = vCoinsNoCoinbase.size() == 0 && vCoinsWithCoinbase.size() > 0;
2737
2738 // If coinbase utxos can only be sent to zaddrs, exclude any coinbase utxos from coin selection.
2739 bool fProtectCoinbase = Params().GetConsensus().fCoinbaseMustBeProtected;
2740 vector<COutput> vCoins = (fProtectCoinbase) ? vCoinsNoCoinbase : vCoinsWithCoinbase;
2741
2742 // Output parameter fNeedCoinbaseCoinsRet is set to true if coinbase utxos need to be spent to meet target amount
2743 if (fProtectCoinbase && vCoinsWithCoinbase.size() > vCoinsNoCoinbase.size()) {
2744 CAmount value = 0;
2745 for (const COutput& out : vCoinsNoCoinbase) {
2746 if (!out.fSpendable) {
2747 continue;
2748 }
2749 value += out.tx->vout[out.i].nValue;
f87150f4 2750 if ( KOMODO_EXCHANGEWALLET == 0 )
2751 value += out.tx->vout[out.i].interest;
2b1cda3b
S
2752 }
2753 if (value <= nTargetValue) {
2754 CAmount valueWithCoinbase = 0;
2755 for (const COutput& out : vCoinsWithCoinbase) {
2756 if (!out.fSpendable) {
2757 continue;
2758 }
2759 valueWithCoinbase += out.tx->vout[out.i].nValue;
f87150f4 2760 if ( KOMODO_EXCHANGEWALLET == 0 )
2761 valueWithCoinbase += out.tx->vout[out.i].interest;
2b1cda3b
S
2762 }
2763 fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
2764 }
2765 }
6a86c24d 2766 // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
aa30f655 2767 if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
6a86c24d
CL
2768 {
2769 BOOST_FOREACH(const COutput& out, vCoins)
2770 {
aa30f655
MC
2771 if (!out.fSpendable)
2772 continue;
6a86c24d 2773 nValueRet += out.tx->vout[out.i].nValue;
79383e0a 2774 //if ( KOMODO_EXCHANGEWALLET == 0 )
2775 // *interestp += out.tx->vout[out.i].interest;
6a86c24d
CL
2776 setCoinsRet.insert(make_pair(out.tx, out.i));
2777 }
2778 return (nValueRet >= nTargetValue);
2779 }
aa30f655
MC
2780 // calculate value from preset inputs and store them
2781 set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
2782 CAmount nValueFromPresetInputs = 0;
2783
2784 std::vector<COutPoint> vPresetInputs;
2785 if (coinControl)
2786 coinControl->ListSelected(vPresetInputs);
2787 BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
2788 {
2789 map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
2790 if (it != mapWallet.end())
2791 {
2792 const CWalletTx* pcoin = &it->second;
2793 // Clearly invalid input, fail
2794 if (pcoin->vout.size() <= outpoint.n)
2795 return false;
2796 nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
945f015d 2797 if ( KOMODO_EXCHANGEWALLET == 0 )
2798 nValueFromPresetInputs += pcoin->vout[outpoint.n].interest;
aa30f655
MC
2799 setPresetCoins.insert(make_pair(pcoin, outpoint.n));
2800 } else
2801 return false; // TODO: Allow non-wallet inputs
2802 }
2803
2804 // remove preset inputs from vCoins
2805 for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
2806 {
2807 if (setPresetCoins.count(make_pair(it->tx, it->i)))
2808 it = vCoins.erase(it);
2809 else
2810 ++it;
2811 }
945f015d 2812 retval = false;
2813 if ( nTargetValue <= nValueFromPresetInputs )
2814 retval = true;
79383e0a 2815 else if ( SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) != 0 )
945f015d 2816 retval = true;
79383e0a 2817 else if ( SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) != 0 )
945f015d 2818 retval = true;
79383e0a 2819 else if ( bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet) != 0 )
945f015d 2820 retval = true;
aa30f655
MC
2821 // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2822 setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
aa30f655
MC
2823 // add preset inputs to the total value selected
2824 nValueRet += nValueFromPresetInputs;
945f015d 2825 return retval;
e8ef3da7
WL
2826}
2827
aa30f655
MC
2828bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason)
2829{
2830 vector<CRecipient> vecSend;
2831
2832 // Turn the txout set into a CRecipient vector
2833 BOOST_FOREACH(const CTxOut& txOut, tx.vout)
2834 {
2835 CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
2836 vecSend.push_back(recipient);
2837 }
2838
2839 CCoinControl coinControl;
2840 coinControl.fAllowOtherInputs = true;
2841 BOOST_FOREACH(const CTxIn& txin, tx.vin)
2842 coinControl.Select(txin.prevout);
2843
2844 CReserveKey reservekey(this);
2845 CWalletTx wtx;
9bb37bf0 2846
aa30f655
MC
2847 if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
2848 return false;
2849
2850 if (nChangePosRet != -1)
2851 tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
2852
2853 // Add new txins (keeping original txin scriptSig/order)
2854 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
2855 {
2856 bool found = false;
2857 BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
2858 {
2859 if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
2860 {
2861 found = true;
2862 break;
2863 }
2864 }
2865 if (!found)
2866 tx.vin.push_back(txin);
2867 }
2868
2869 return true;
e8ef3da7
WL
2870}
2871
aa30f655
MC
2872bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
2873 int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
e8ef3da7 2874{
79383e0a 2875 uint64_t interest2 = 0; CAmount nValue = 0; unsigned int nSubtractFeeFromAmount = 0;
292623ad 2876 BOOST_FOREACH (const CRecipient& recipient, vecSend)
e8ef3da7 2877 {
292623ad 2878 if (nValue < 0 || recipient.nAmount < 0)
1f00f4e9
GA
2879 {
2880 strFailReason = _("Transaction amounts must be positive");
e8ef3da7 2881 return false;
1f00f4e9 2882 }
292623ad
CL
2883 nValue += recipient.nAmount;
2884
2885 if (recipient.fSubtractFeeFromAmount)
2886 nSubtractFeeFromAmount++;
e8ef3da7
WL
2887 }
2888 if (vecSend.empty() || nValue < 0)
1f00f4e9
GA
2889 {
2890 strFailReason = _("Transaction amounts must be positive");
e8ef3da7 2891 return false;
1f00f4e9 2892 }
e8ef3da7 2893
b33d1f5e 2894 wtxNew.fTimeReceivedIsTxTime = true;
4c6e2295 2895 wtxNew.BindWallet(this);
9bb37bf0 2896 int nextBlockHeight = chainActive.Height() + 1;
072099d7 2897 CMutableTransaction txNew = CreateNewContextualCMutableTransaction(
9000990c 2898 Params().GetConsensus(), nextBlockHeight);
c3e43fb1 2899 txNew.nLockTime = (uint32_t)chainActive.Tip()->nTime + 1; // set to a time close to now
e8ef3da7 2900
9bb37bf0
JG
2901 // Activates after Overwinter network upgrade
2902 // Set nExpiryHeight to expiryDelta (default 20) blocks past current block height
9000990c 2903 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER))
2904 {
9bb37bf0
JG
2905 if (nextBlockHeight + expiryDelta >= TX_EXPIRY_HEIGHT_THRESHOLD){
2906 strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD.");
7b92f27e 2907 return false;
9bb37bf0
JG
2908 } else {
2909 txNew.nExpiryHeight = nextBlockHeight + expiryDelta;
2910 }
e19d8b3d 2911 }
9bb37bf0 2912
e8ef3da7 2913 {
f8dcd5ca 2914 LOCK2(cs_main, cs_wallet);
e8ef3da7 2915 {
c1c9d5b4 2916 nFeeRet = 0;
050d2e95 2917 while (true)
e8ef3da7 2918 {
f19ffc34 2919 //interest = 0;
4949004d
PW
2920 txNew.vin.clear();
2921 txNew.vout.clear();
e8ef3da7 2922 wtxNew.fFromMe = true;
292623ad
CL
2923 nChangePosRet = -1;
2924 bool fFirst = true;
e8ef3da7 2925
292623ad
CL
2926 CAmount nTotalValue = nValue;
2927 if (nSubtractFeeFromAmount == 0)
2928 nTotalValue += nFeeRet;
e8ef3da7
WL
2929 double dPriority = 0;
2930 // vouts to the payees
292623ad 2931 BOOST_FOREACH (const CRecipient& recipient, vecSend)
8de9bb53 2932 {
292623ad
CL
2933 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
2934
2935 if (recipient.fSubtractFeeFromAmount)
2936 {
2937 txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
2938
2939 if (fFirst) // first receiver pays the remainder not divisible by output count
2940 {
2941 fFirst = false;
2942 txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
2943 }
2944 }
2945
13fc83c7 2946 if (txout.IsDust(::minRelayTxFee))
1f00f4e9 2947 {
292623ad
CL
2948 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
2949 {
2950 if (txout.nValue < 0)
2951 strFailReason = _("The transaction amount is too small to pay the fee");
2952 else
2953 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
2954 }
2955 else
2956 strFailReason = _("Transaction amount too small");
8de9bb53 2957 return false;
1f00f4e9 2958 }
4949004d 2959 txNew.vout.push_back(txout);
8de9bb53 2960 }
e8ef3da7
WL
2961
2962 // Choose coins to use
2963 set<pair<const CWalletTx*,unsigned int> > setCoins;
a372168e 2964 CAmount nValueIn = 0;
2b1cda3b
S
2965 bool fOnlyCoinbaseCoins = false;
2966 bool fNeedCoinbaseCoins = false;
9152feb5 2967 interest2 = 0;
79383e0a 2968 if (!SelectCoins(nTotalValue, setCoins, nValueIn, fOnlyCoinbaseCoins, fNeedCoinbaseCoins, coinControl))
1f00f4e9 2969 {
2b1cda3b
S
2970 if (fOnlyCoinbaseCoins && Params().GetConsensus().fCoinbaseMustBeProtected) {
2971 strFailReason = _("Coinbase funds can only be sent to a zaddr");
2972 } else if (fNeedCoinbaseCoins) {
2973 strFailReason = _("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr");
2974 } else {
2975 strFailReason = _("Insufficient funds");
2976 }
e8ef3da7 2977 return false;
1f00f4e9 2978 }
e8ef3da7
WL
2979 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
2980 {
a372168e 2981 CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
2d9b0b7f 2982 //The coin age after the next block (depth+1) is used instead of the current,
d7836552
GM
2983 //reflecting an assumption the user would accept a bit more delay for
2984 //a chance at a free transaction.
2d9b0b7f 2985 //But mempool inputs might still be in the mempool, so their age stays 0
38dfbe15 2986 //fprintf(stderr,"nCredit %.8f interest %.8f\n",(double)nCredit/COIN,(double)pcoin.first->vout[pcoin.second].interest/COIN);
d1f29a9d 2987 if ( KOMODO_EXCHANGEWALLET == 0 && ASSETCHAINS_SYMBOL[0] == 0 )
608252ed 2988 {
6ad13d7c 2989 interest2 += pcoin.first->vout[pcoin.second].interest;
d1f29a9d 2990 //fprintf(stderr,"%.8f ",(double)pcoin.first->vout[pcoin.second].interest/COIN);
85cb030e 2991 }
2d9b0b7f
AM
2992 int age = pcoin.first->GetDepthInMainChain();
2993 if (age != 0)
2994 age += 1;
2995 dPriority += (double)nCredit * age;
e8ef3da7 2996 }
79383e0a 2997 //if ( KOMODO_EXCHANGEWALLET != 0 )
2998 //{
2626c7e3 2999 //fprintf(stderr,"KOMODO_EXCHANGEWALLET disable interest sum %.8f, interest2 %.8f\n",(double)interest/COIN,(double)interest2/COIN);
79383e0a 3000 //interest = 0; // interest2 also
3001 //}
608252ed 3002 CAmount nChange = (nValueIn - nValue + interest2);
4ea19a87 3003//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);
292623ad
CL
3004 if (nSubtractFeeFromAmount == 0)
3005 nChange -= nFeeRet;
a7dd11c6
PW
3006
3007 if (nChange > 0)
e8ef3da7 3008 {
bf798734
GA
3009 // Fill a vout to ourself
3010 // TODO: pass in scriptChange instead of reservekey so
3011 // change transaction isn't always pay-to-bitcoin-address
e8ef3da7 3012 CScript scriptChange;
6a86c24d
CL
3013
3014 // coin control: send change to custom address
3015 if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
0be990ba 3016 scriptChange = GetScriptForDestination(coinControl->destChange);
6a86c24d
CL
3017
3018 // no coin control: send change to newly generated address
3019 else
3020 {
3021 // Note: We use a new key here to keep it from being obvious which side is the change.
3022 // The drawback is that by not reusing a previous key, the change may be lost if a
3023 // backup is restored, if the backup doesn't have the new private key for the change.
3024 // If we reused the old key, it would be possible to add code to look for and
3025 // rediscover unknown transactions that were written with keys of ours to recover
3026 // post-backup change.
3027
3028 // Reserve a new key pair from key pool
3029 CPubKey vchPubKey;
3ec03ada 3030 extern int32_t USE_EXTERNAL_PUBKEY; extern std::string NOTARY_PUBKEY;
3031 if ( USE_EXTERNAL_PUBKEY == 0 )
3032 {
3ec03ada 3033 bool ret;
3034 ret = reservekey.GetReservedKey(vchPubKey);
3035 assert(ret); // should never fail, as we just unlocked
3036 scriptChange = GetScriptForDestination(vchPubKey.GetID());
3037 }
3038 else
3039 {
18c6cfce 3040 //fprintf(stderr,"use notary pubkey\n");
3ec03ada 3041 scriptChange = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
3042 }
6a86c24d 3043 }
e8ef3da7 3044
8de9bb53
GA
3045 CTxOut newTxOut(nChange, scriptChange);
3046
292623ad
CL
3047 // We do not move dust-change to fees, because the sender would end up paying more than requested.
3048 // This would be against the purpose of the all-inclusive feature.
3049 // So instead we raise the change and deduct from the recipient.
3050 if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
3051 {
3052 CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
3053 newTxOut.nValue += nDust; // raise change until no more dust
3054 for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
3055 {
3056 if (vecSend[i].fSubtractFeeFromAmount)
3057 {
3058 txNew.vout[i].nValue -= nDust;
3059 if (txNew.vout[i].IsDust(::minRelayTxFee))
3060 {
3061 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
3062 return false;
3063 }
3064 break;
3065 }
3066 }
3067 }
3068
8de9bb53
GA
3069 // Never create dust outputs; if we would, just
3070 // add the dust to the fee.
13fc83c7 3071 if (newTxOut.IsDust(::minRelayTxFee))
8de9bb53
GA
3072 {
3073 nFeeRet += nChange;
3074 reservekey.ReturnKey();
3075 }
3076 else
3077 {
429dabb5 3078 nChangePosRet = txNew.vout.size() - 1; // dont change first or last
292623ad 3079 vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
4949004d 3080 txNew.vout.insert(position, newTxOut);
8de9bb53 3081 }
f38345e9 3082 } else reservekey.ReturnKey();
e8ef3da7
WL
3083
3084 // Fill vin
ba7fcc8d
PT
3085 //
3086 // Note how the sequence number is set to max()-1 so that the
3087 // nLockTime set above actually works.
e8ef3da7 3088 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
805344dc 3089 txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
ba7fcc8d 3090 std::numeric_limits<unsigned int>::max()-1));
e8ef3da7 3091
9e84b5aa
S
3092 // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
3093 size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
3094 if (limit > 0) {
3095 size_t n = txNew.vin.size();
3096 if (n > limit) {
3097 strFailReason = _(strprintf("Too many transparent inputs %zu > limit %zu", n, limit).c_str());
3098 return false;
3099 }
3100 }
3101
be126699
JG
3102 // Grab the current consensus branch ID
3103 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
3104
e8ef3da7
WL
3105 // Sign
3106 int nIn = 0;
aa30f655 3107 CTransaction txNewConst(txNew);
e8ef3da7 3108 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
aa30f655
MC
3109 {
3110 bool signSuccess;
3111 const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
157a5d0d 3112 SignatureData sigdata;
aa30f655 3113 if (sign)
be126699 3114 signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
aa30f655 3115 else
be126699 3116 signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
aa30f655
MC
3117
3118 if (!signSuccess)
1f00f4e9
GA
3119 {
3120 strFailReason = _("Signing transaction failed");
e8ef3da7 3121 return false;
157a5d0d
PW
3122 } else {
3123 UpdateTransaction(txNew, nIn, sigdata);
1f00f4e9 3124 }
157a5d0d 3125
aa30f655
MC
3126 nIn++;
3127 }
3128
3129 unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
3130
3131 // Remove scriptSigs if we used dummy signatures for fee calculation
3132 if (!sign) {
3133 BOOST_FOREACH (CTxIn& vin, txNew.vin)
3134 vin.scriptSig = CScript();
3135 }
e8ef3da7 3136
4949004d
PW
3137 // Embed the constructed transaction data in wtxNew.
3138 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
3139
e8ef3da7 3140 // Limit size
74f15a73 3141 if (nBytes >= MAX_TX_SIZE)
1f00f4e9
GA
3142 {
3143 strFailReason = _("Transaction too large");
e8ef3da7 3144 return false;
1f00f4e9 3145 }
aa30f655 3146
4d707d51 3147 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
e8ef3da7 3148
aa279d61
GM
3149 // Can we complete this as a free transaction?
3150 if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
3151 {
3152 // Not enough fee: enough priority?
3153 double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
3154 // Not enough mempool history to estimate: use hard-coded AllowFree.
3155 if (dPriorityNeeded <= 0 && AllowFree(dPriority))
3156 break;
3157
3158 // Small enough, and priority high enough, to send for free
3159 if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
3160 break;
3161 }
b33d1f5e 3162
1e3fdfaa 3163 CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
3164 if ( nFeeNeeded < 5000 )
3165 nFeeNeeded = 5000;
b33d1f5e 3166
aa279d61
GM
3167 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
3168 // because we must be at the maximum allowed fee.
3169 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
e8ef3da7 3170 {
aa279d61
GM
3171 strFailReason = _("Transaction too large for fee policy");
3172 return false;
e8ef3da7
WL
3173 }
3174
aa279d61
GM
3175 if (nFeeRet >= nFeeNeeded)
3176 break; // Done, enough fee included.
b33d1f5e
GA
3177
3178 // Include more fee and try again.
3179 nFeeRet = nFeeNeeded;
3180 continue;
e8ef3da7
WL
3181 }
3182 }
3183 }
e8ef3da7 3184
292623ad 3185 return true;
e8ef3da7
WL
3186}
3187
5b40d886
MF
3188/**
3189 * Call after CreateTransaction unless you want to abort
3190 */
e8ef3da7
WL
3191bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
3192{
e8ef3da7 3193 {
f8dcd5ca 3194 LOCK2(cs_main, cs_wallet);
7d9d134b 3195 LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
e8ef3da7
WL
3196 {
3197 // This is only to keep the database open to defeat the auto-flush for the
3198 // duration of this scope. This is the only place where this optimization
3199 // maybe makes sense; please don't do it anywhere else.
44bc988e 3200 CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
e8ef3da7
WL
3201
3202 // Take key pair from key pool so it won't be used again
3203 reservekey.KeepKey();
3204
3205 // Add tx to wallet, because if it has change it's also ours,
3206 // otherwise just for transaction history.
44bc988e 3207 AddToWallet(wtxNew, false, pwalletdb);
e8ef3da7 3208
93a18a36 3209 // Notify that old coins are spent
e8ef3da7
WL
3210 set<CWalletTx*> setCoins;
3211 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
3212 {
3213 CWalletTx &coin = mapWallet[txin.prevout.hash];
4c6e2295 3214 coin.BindWallet(this);
805344dc 3215 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
e8ef3da7
WL
3216 }
3217
3218 if (fFileBacked)
3219 delete pwalletdb;
3220 }
3221
3222 // Track how many getdata requests our transaction gets
805344dc 3223 mapRequestCount[wtxNew.GetHash()] = 0;
e8ef3da7 3224
6f252627 3225 if (fBroadcastTransactions)
e8ef3da7 3226 {
6f252627
WL
3227 // Broadcast
3228 if (!wtxNew.AcceptToMemoryPool(false))
3229 {
68c266b2 3230 fprintf(stderr,"commit failed\n");
3231 // This must not fail. The transaction has already been signed and recorded.
7ff9d122 3232 LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
6f252627
WL
3233 return false;
3234 }
3235 wtxNew.RelayWalletTransaction();
e8ef3da7 3236 }
e8ef3da7 3237 }
e8ef3da7
WL
3238 return true;
3239}
3240
a372168e 3241CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
b33d1f5e
GA
3242{
3243 // payTxFee is user-set "I want to pay this much"
a372168e 3244 CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
c1c9d5b4
CL
3245 // user selected total at least (default=true)
3246 if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
3247 nFeeNeeded = payTxFee.GetFeePerK();
b33d1f5e
GA
3248 // User didn't set: use -txconfirmtarget to estimate...
3249 if (nFeeNeeded == 0)
3250 nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
3251 // ... unless we don't have enough mempool data, in which case fall
3252 // back to a hard-coded fee
3253 if (nFeeNeeded == 0)
13fc83c7 3254 nFeeNeeded = minTxFee.GetFee(nTxBytes);
aa279d61
GM
3255 // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
3256 if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
3257 nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
3258 // But always obey the maximum
3259 if (nFeeNeeded > maxTxFee)
3260 nFeeNeeded = maxTxFee;
b33d1f5e
GA
3261 return nFeeNeeded;
3262}
3263
e8ef3da7 3264
cf53fd7c 3265void komodo_prefetch(FILE *fp);
e8ef3da7 3266
eed1785f 3267DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
e8ef3da7
WL
3268{
3269 if (!fFileBacked)
4f76be1d 3270 return DB_LOAD_OK;
e8ef3da7 3271 fFirstRunRet = false;
e86c03cf 3272 if ( 0 ) // doesnt help
cf53fd7c 3273 {
e86c03cf 3274 fprintf(stderr,"loading wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
cf53fd7c 3275 FILE *fp;
3276 if ( (fp= fopen(strWalletFile.c_str(),"rb")) != 0 )
3277 {
3278 komodo_prefetch(fp);
3279 fclose(fp);
3280 }
3281 }
e86c03cf 3282 //fprintf(stderr,"prefetched wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
eed1785f 3283 DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
e86c03cf 3284 //fprintf(stderr,"loaded wallet %s %u\n",strWalletFile.c_str(),(uint32_t)time(NULL));
d764d916 3285 if (nLoadWalletRet == DB_NEED_REWRITE)
9e9869d0 3286 {
d764d916
GA
3287 if (CDB::Rewrite(strWalletFile, "\x04pool"))
3288 {
012ca1c9 3289 LOCK(cs_wallet);
d764d916
GA
3290 setKeyPool.clear();
3291 // Note: can't top-up keypool here, because wallet is locked.
3292 // User will be prompted to unlock wallet the next operation
c6de7c35 3293 // that requires a new key.
d764d916 3294 }
9e9869d0
PW
3295 }
3296
7ec55267
MC
3297 if (nLoadWalletRet != DB_LOAD_OK)
3298 return nLoadWalletRet;
fd61d6f5 3299 fFirstRunRet = !vchDefaultKey.IsValid();
e8ef3da7 3300
39278369
CL
3301 uiInterface.LoadWallet(this);
3302
116df55e 3303 return DB_LOAD_OK;
e8ef3da7
WL
3304}
3305
ae3d0aba 3306
77cbd462 3307DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
518f3bda
JG
3308{
3309 if (!fFileBacked)
3310 return DB_LOAD_OK;
77cbd462 3311 DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
518f3bda
JG
3312 if (nZapWalletTxRet == DB_NEED_REWRITE)
3313 {
3314 if (CDB::Rewrite(strWalletFile, "\x04pool"))
3315 {
3316 LOCK(cs_wallet);
3317 setKeyPool.clear();
3318 // Note: can't top-up keypool here, because wallet is locked.
3319 // User will be prompted to unlock wallet the next operation
5b40d886 3320 // that requires a new key.
518f3bda
JG
3321 }
3322 }
3323
3324 if (nZapWalletTxRet != DB_LOAD_OK)
3325 return nZapWalletTxRet;
3326
3327 return DB_LOAD_OK;
3328}
3329
3330
a41d5fe0 3331bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
ae3d0aba 3332{
ca4cf5cf
GA
3333 bool fUpdated = false;
3334 {
3335 LOCK(cs_wallet); // mapAddressBook
3336 std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
3337 fUpdated = mi != mapAddressBook.end();
3338 mapAddressBook[address].name = strName;
3339 if (!strPurpose.empty()) /* update purpose only if requested */
3340 mapAddressBook[address].purpose = strPurpose;
3341 }
8d657a65 3342 NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
ca4cf5cf 3343 strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
ae3d0aba
WL
3344 if (!fFileBacked)
3345 return false;
a41d5fe0
GA
3346 if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
3347 return false;
10254401 3348 return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
ae3d0aba
WL
3349}
3350
a41d5fe0 3351bool CWallet::DelAddressBook(const CTxDestination& address)
ae3d0aba 3352{
b10e1470 3353 {
ca4cf5cf
GA
3354 LOCK(cs_wallet); // mapAddressBook
3355
3356 if(fFileBacked)
b10e1470 3357 {
ca4cf5cf
GA
3358 // Delete destdata tuples associated with address
3359 std::string strAddress = CBitcoinAddress(address).ToString();
3360 BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
3361 {
3362 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
3363 }
b10e1470 3364 }
ca4cf5cf 3365 mapAddressBook.erase(address);
b10e1470
WL
3366 }
3367
8d657a65 3368 NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
ca4cf5cf 3369
ae3d0aba
WL
3370 if (!fFileBacked)
3371 return false;
a41d5fe0 3372 CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
10254401 3373 return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
ae3d0aba
WL
3374}
3375
fd61d6f5 3376bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
ae3d0aba
WL
3377{
3378 if (fFileBacked)
3379 {
3380 if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
3381 return false;
3382 }
3383 vchDefaultKey = vchPubKey;
3384 return true;
3385}
3386
5b40d886
MF
3387/**
3388 * Mark old keypool keys as used,
3389 * and generate all new keys
3390 */
37971fcc
GA
3391bool CWallet::NewKeyPool()
3392{
37971fcc 3393 {
f8dcd5ca 3394 LOCK(cs_wallet);
37971fcc 3395 CWalletDB walletdb(strWalletFile);
51ed9ec9 3396 BOOST_FOREACH(int64_t nIndex, setKeyPool)
37971fcc
GA
3397 walletdb.ErasePool(nIndex);
3398 setKeyPool.clear();
3399
3400 if (IsLocked())
3401 return false;
3402
51ed9ec9 3403 int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
37971fcc
GA
3404 for (int i = 0; i < nKeys; i++)
3405 {
51ed9ec9 3406 int64_t nIndex = i+1;
37971fcc
GA
3407 walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
3408 setKeyPool.insert(nIndex);
3409 }
f48742c2 3410 LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
37971fcc
GA
3411 }
3412 return true;
3413}
3414
13dd2d09 3415bool CWallet::TopUpKeyPool(unsigned int kpSize)
e8ef3da7 3416{
e8ef3da7 3417 {
f8dcd5ca
PW
3418 LOCK(cs_wallet);
3419
4e87d341
MC
3420 if (IsLocked())
3421 return false;
3422
e8ef3da7
WL
3423 CWalletDB walletdb(strWalletFile);
3424
3425 // Top up key pool
13dd2d09
JG
3426 unsigned int nTargetSize;
3427 if (kpSize > 0)
3428 nTargetSize = kpSize;
3429 else
51ed9ec9 3430 nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
13dd2d09 3431
faf705a4 3432 while (setKeyPool.size() < (nTargetSize + 1))
e8ef3da7 3433 {
51ed9ec9 3434 int64_t nEnd = 1;
e8ef3da7
WL
3435 if (!setKeyPool.empty())
3436 nEnd = *(--setKeyPool.end()) + 1;
3437 if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
5262fde0 3438 throw runtime_error("TopUpKeyPool(): writing generated key failed");
e8ef3da7 3439 setKeyPool.insert(nEnd);
783b182c 3440 LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
e8ef3da7 3441 }
4e87d341
MC
3442 }
3443 return true;
3444}
3445
51ed9ec9 3446void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
4e87d341
MC
3447{
3448 nIndex = -1;
fd61d6f5 3449 keypool.vchPubKey = CPubKey();
4e87d341 3450 {
f8dcd5ca
PW
3451 LOCK(cs_wallet);
3452
4e87d341
MC
3453 if (!IsLocked())
3454 TopUpKeyPool();
e8ef3da7
WL
3455
3456 // Get the oldest key
4e87d341
MC
3457 if(setKeyPool.empty())
3458 return;
3459
3460 CWalletDB walletdb(strWalletFile);
3461
e8ef3da7
WL
3462 nIndex = *(setKeyPool.begin());
3463 setKeyPool.erase(setKeyPool.begin());
3464 if (!walletdb.ReadPool(nIndex, keypool))
5262fde0 3465 throw runtime_error("ReserveKeyFromKeyPool(): read failed");
fd61d6f5 3466 if (!HaveKey(keypool.vchPubKey.GetID()))
5262fde0 3467 throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
fd61d6f5 3468 assert(keypool.vchPubKey.IsValid());
36a65612 3469 //LogPrintf("keypool reserve %d\n", nIndex);
e8ef3da7
WL
3470 }
3471}
3472
51ed9ec9 3473void CWallet::KeepKey(int64_t nIndex)
e8ef3da7
WL
3474{
3475 // Remove from key pool
3476 if (fFileBacked)
3477 {
3478 CWalletDB walletdb(strWalletFile);
6cc4a62c 3479 walletdb.ErasePool(nIndex);
e8ef3da7 3480 }
f48742c2 3481 LogPrintf("keypool keep %d\n", nIndex);
e8ef3da7
WL
3482}
3483
51ed9ec9 3484void CWallet::ReturnKey(int64_t nIndex)
e8ef3da7
WL
3485{
3486 // Return to key pool
f8dcd5ca
PW
3487 {
3488 LOCK(cs_wallet);
e8ef3da7 3489 setKeyPool.insert(nIndex);
f8dcd5ca 3490 }
36a65612 3491 //LogPrintf("keypool return %d\n", nIndex);
e8ef3da7
WL
3492}
3493
71ac5052 3494bool CWallet::GetKeyFromPool(CPubKey& result)
e8ef3da7 3495{
51ed9ec9 3496 int64_t nIndex = 0;
e8ef3da7 3497 CKeyPool keypool;
7db3b75b 3498 {
f8dcd5ca 3499 LOCK(cs_wallet);
ed02c95d
GA
3500 ReserveKeyFromKeyPool(nIndex, keypool);
3501 if (nIndex == -1)
7db3b75b 3502 {
ed02c95d
GA
3503 if (IsLocked()) return false;
3504 result = GenerateNewKey();
7db3b75b
GA
3505 return true;
3506 }
ed02c95d
GA
3507 KeepKey(nIndex);
3508 result = keypool.vchPubKey;
7db3b75b 3509 }
7db3b75b 3510 return true;
e8ef3da7
WL
3511}
3512
51ed9ec9 3513int64_t CWallet::GetOldestKeyPoolTime()
e8ef3da7 3514{
51ed9ec9 3515 int64_t nIndex = 0;
e8ef3da7
WL
3516 CKeyPool keypool;
3517 ReserveKeyFromKeyPool(nIndex, keypool);
4e87d341
MC
3518 if (nIndex == -1)
3519 return GetTime();
e8ef3da7
WL
3520 ReturnKey(nIndex);
3521 return keypool.nTime;
3522}
3523
a372168e 3524std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
22dfd735 3525{
a372168e 3526 map<CTxDestination, CAmount> balances;
22dfd735 3527
3528 {
3529 LOCK(cs_wallet);
3530 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
3531 {
3532 CWalletTx *pcoin = &walletEntry.second;
3533
75a4d512 3534 if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted())
22dfd735 3535 continue;
3536
3537 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
3538 continue;
3539
3540 int nDepth = pcoin->GetDepthInMainChain();
a3e192a3 3541 if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
22dfd735 3542 continue;
3543
b1093efa 3544 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
22dfd735 3545 {
b1093efa 3546 CTxDestination addr;
22dfd735 3547 if (!IsMine(pcoin->vout[i]))
3548 continue;
b1093efa
GM
3549 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
3550 continue;
22dfd735 3551
a372168e 3552 CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
22dfd735 3553
22dfd735 3554 if (!balances.count(addr))
3555 balances[addr] = 0;
3556 balances[addr] += n;
3557 }
3558 }
3559 }
3560
3561 return balances;
3562}
3563
b1093efa 3564set< set<CTxDestination> > CWallet::GetAddressGroupings()
22dfd735 3565{
95691680 3566 AssertLockHeld(cs_wallet); // mapWallet
b1093efa
GM
3567 set< set<CTxDestination> > groupings;
3568 set<CTxDestination> grouping;
22dfd735 3569
3570 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
3571 {
3572 CWalletTx *pcoin = &walletEntry.second;
3573
a3fad211 3574 if (pcoin->vin.size() > 0)
22dfd735 3575 {
a3fad211 3576 bool any_mine = false;
22dfd735 3577 // group all input addresses with each other
3578 BOOST_FOREACH(CTxIn txin, pcoin->vin)
b1093efa
GM
3579 {
3580 CTxDestination address;
a3fad211
GM
3581 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
3582 continue;
b1093efa
GM
3583 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
3584 continue;
3585 grouping.insert(address);
a3fad211 3586 any_mine = true;
b1093efa 3587 }
22dfd735 3588
3589 // group change with input addresses
a3fad211
GM
3590 if (any_mine)
3591 {
3592 BOOST_FOREACH(CTxOut txout, pcoin->vout)
3593 if (IsChange(txout))
3594 {
3595 CTxDestination txoutAddr;
3596 if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
3597 continue;
3598 grouping.insert(txoutAddr);
3599 }
3600 }
3601 if (grouping.size() > 0)
3602 {
3603 groupings.insert(grouping);
3604 grouping.clear();
3605 }
22dfd735 3606 }
3607
3608 // group lone addrs by themselves
b1093efa 3609 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
22dfd735 3610 if (IsMine(pcoin->vout[i]))
3611 {
b1093efa
GM
3612 CTxDestination address;
3613 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
3614 continue;
3615 grouping.insert(address);
22dfd735 3616 groupings.insert(grouping);
3617 grouping.clear();
3618 }
3619 }
3620
b1093efa
GM
3621 set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
3622 map< CTxDestination, set<CTxDestination>* > setmap; // map addresses to the unique group containing it
3623 BOOST_FOREACH(set<CTxDestination> grouping, groupings)
22dfd735 3624 {
3625 // make a set of all the groups hit by this new group
b1093efa
GM
3626 set< set<CTxDestination>* > hits;
3627 map< CTxDestination, set<CTxDestination>* >::iterator it;
3628 BOOST_FOREACH(CTxDestination address, grouping)
22dfd735 3629 if ((it = setmap.find(address)) != setmap.end())
3630 hits.insert((*it).second);
3631
3632 // merge all hit groups into a new single group and delete old groups
b1093efa
GM
3633 set<CTxDestination>* merged = new set<CTxDestination>(grouping);
3634 BOOST_FOREACH(set<CTxDestination>* hit, hits)
22dfd735 3635 {
3636 merged->insert(hit->begin(), hit->end());
3637 uniqueGroupings.erase(hit);
3638 delete hit;
3639 }
3640 uniqueGroupings.insert(merged);
3641
3642 // update setmap
b1093efa 3643 BOOST_FOREACH(CTxDestination element, *merged)
22dfd735 3644 setmap[element] = merged;
3645 }
3646
b1093efa
GM
3647 set< set<CTxDestination> > ret;
3648 BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
22dfd735 3649 {
3650 ret.insert(*uniqueGrouping);
3651 delete uniqueGrouping;
3652 }
3653
3654 return ret;
3655}
3656
db954a65 3657std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
3624356e 3658{
43422a01 3659 LOCK(cs_wallet);
3624356e
GA
3660 set<CTxDestination> result;
3661 BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
3662 {
3663 const CTxDestination& address = item.first;
3664 const string& strName = item.second.name;
3665 if (strName == strAccount)
3666 result.insert(address);
3667 }
3668 return result;
3669}
3670
360cfe14 3671bool CReserveKey::GetReservedKey(CPubKey& pubkey)
e8ef3da7
WL
3672{
3673 if (nIndex == -1)
3674 {
3675 CKeyPool keypool;
3676 pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
0d7b28e5
MC
3677 if (nIndex != -1)
3678 vchPubKey = keypool.vchPubKey;
360cfe14 3679 else {
6c37f7fd 3680 return false;
cee69980 3681 }
e8ef3da7 3682 }
fd61d6f5 3683 assert(vchPubKey.IsValid());
360cfe14
PW
3684 pubkey = vchPubKey;
3685 return true;
e8ef3da7
WL
3686}
3687
3688void CReserveKey::KeepKey()
3689{
3690 if (nIndex != -1)
3691 pwallet->KeepKey(nIndex);
3692 nIndex = -1;
fd61d6f5 3693 vchPubKey = CPubKey();
e8ef3da7
WL
3694}
3695
3696void CReserveKey::ReturnKey()
3697{
3698 if (nIndex != -1)
3699 pwallet->ReturnKey(nIndex);
3700 nIndex = -1;
fd61d6f5 3701 vchPubKey = CPubKey();
e8ef3da7 3702}
ae3d0aba 3703
434e4273 3704void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
30ab2c9c
PW
3705{
3706 setAddress.clear();
3707
3708 CWalletDB walletdb(strWalletFile);
3709
f8dcd5ca 3710 LOCK2(cs_main, cs_wallet);
51ed9ec9 3711 BOOST_FOREACH(const int64_t& id, setKeyPool)
30ab2c9c
PW
3712 {
3713 CKeyPool keypool;
3714 if (!walletdb.ReadPool(id, keypool))
5262fde0 3715 throw runtime_error("GetAllReserveKeyHashes(): read failed");
fd61d6f5 3716 assert(keypool.vchPubKey.IsValid());
10254401
PW
3717 CKeyID keyID = keypool.vchPubKey.GetID();
3718 if (!HaveKey(keyID))
5262fde0 3719 throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
10254401 3720 setAddress.insert(keyID);
30ab2c9c
PW
3721 }
3722}
fe4a6550
WL
3723
3724void CWallet::UpdatedTransaction(const uint256 &hashTx)
3725{
3726 {
3727 LOCK(cs_wallet);
3728 // Only notify UI if this transaction is in this wallet
3729 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
3730 if (mi != mapWallet.end())
3731 NotifyTransactionChanged(this, hashTx, CT_UPDATED);
3732 }
3733}
fdbb537d
JG
3734
3735void CWallet::LockCoin(COutPoint& output)
3736{
95691680 3737 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3738 setLockedCoins.insert(output);
3739}
3740
3741void CWallet::UnlockCoin(COutPoint& output)
3742{
95691680 3743 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3744 setLockedCoins.erase(output);
3745}
3746
3747void CWallet::UnlockAllCoins()
3748{
95691680 3749 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3750 setLockedCoins.clear();
3751}
3752
3753bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
3754{
95691680 3755 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3756 COutPoint outpt(hash, n);
3757
3758 return (setLockedCoins.count(outpt) > 0);
3759}
3760
3761void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
3762{
95691680 3763 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3764 for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
3765 it != setLockedCoins.end(); it++) {
3766 COutPoint outpt = (*it);
3767 vOutpts.push_back(outpt);
3768 }
3769}
3770
98a4f6a6
BM
3771
3772// Note Locking Operations
3773
3774void CWallet::LockNote(JSOutPoint& output)
3775{
3776 AssertLockHeld(cs_wallet); // setLockedNotes
3777 setLockedNotes.insert(output);
3778}
3779
3780void CWallet::UnlockNote(JSOutPoint& output)
3781{
3782 AssertLockHeld(cs_wallet); // setLockedNotes
3783 setLockedNotes.erase(output);
3784}
3785
3786void CWallet::UnlockAllNotes()
3787{
3788 AssertLockHeld(cs_wallet); // setLockedNotes
3789 setLockedNotes.clear();
3790}
3791
3792bool CWallet::IsLockedNote(uint256 hash, size_t js, uint8_t n) const
3793{
3794 AssertLockHeld(cs_wallet); // setLockedNotes
3795 JSOutPoint outpt(hash, js, n);
3796
3797 return (setLockedNotes.count(outpt) > 0);
3798}
3799
3800std::vector<JSOutPoint> CWallet::ListLockedNotes()
3801{
3802 AssertLockHeld(cs_wallet); // setLockedNotes
3803 std::vector<JSOutPoint> vOutpts(setLockedNotes.begin(), setLockedNotes.end());
3804 return vOutpts;
3805}
3806
5b40d886 3807/** @} */ // end of Actions
8b59a3d3 3808
3809class CAffectedKeysVisitor : public boost::static_visitor<void> {
3810private:
3811 const CKeyStore &keystore;
3812 std::vector<CKeyID> &vKeys;
3813
3814public:
3815 CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
3816
3817 void Process(const CScript &script) {
3818 txnouttype type;
3819 std::vector<CTxDestination> vDest;
3820 int nRequired;
3821 if (ExtractDestinations(script, type, vDest, nRequired)) {
3822 BOOST_FOREACH(const CTxDestination &dest, vDest)
3823 boost::apply_visitor(*this, dest);
3824 }
3825 }
3826
3827 void operator()(const CKeyID &keyId) {
3828 if (keystore.HaveKey(keyId))
3829 vKeys.push_back(keyId);
3830 }
3831
3832 void operator()(const CScriptID &scriptId) {
3833 CScript script;
3834 if (keystore.GetCScript(scriptId, script))
3835 Process(script);
3836 }
3837
3838 void operator()(const CNoDestination &none) {}
3839};
3840
51ed9ec9 3841void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
95691680 3842 AssertLockHeld(cs_wallet); // mapKeyMetadata
434e4273
PW
3843 mapKeyBirth.clear();
3844
3845 // get birth times for keys with metadata
3846 for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
3847 if (it->second.nCreateTime)
3848 mapKeyBirth[it->first] = it->second.nCreateTime;
3849
3850 // map in which we'll infer heights of other keys
4c6d41b8 3851 CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
434e4273
PW
3852 std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
3853 std::set<CKeyID> setKeys;
3854 GetKeys(setKeys);
3855 BOOST_FOREACH(const CKeyID &keyid, setKeys) {
3856 if (mapKeyBirth.count(keyid) == 0)
3857 mapKeyFirstBlock[keyid] = pindexMax;
3858 }
3859 setKeys.clear();
3860
3861 // if there are no such keys, we're done
3862 if (mapKeyFirstBlock.empty())
3863 return;
3864
3865 // find first block that affects those keys, if there are any left
3866 std::vector<CKeyID> vAffected;
3867 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
3868 // iterate over all wallet transactions...
3869 const CWalletTx &wtx = (*it).second;
145d5be8 3870 BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
4c6d41b8 3871 if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
434e4273
PW
3872 // ... which are already in a block
3873 int nHeight = blit->second->nHeight;
3874 BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
3875 // iterate over all their outputs
8b59a3d3 3876 CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
434e4273
PW
3877 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
3878 // ... and all their affected keys
3879 std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
3880 if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
3881 rit->second = blit->second;
3882 }
3883 vAffected.clear();
3884 }
3885 }
3886 }
3887
3888 // Extract block timestamps for those keys
3889 for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
209377a7 3890 mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
434e4273 3891}
b10e1470
WL
3892
3893bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
3894{
8476d5d4
CL
3895 if (boost::get<CNoDestination>(&dest))
3896 return false;
3897
b10e1470
WL
3898 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
3899 if (!fFileBacked)
3900 return true;
3901 return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
3902}
3903
3904bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
3905{
3906 if (!mapAddressBook[dest].destdata.erase(key))
3907 return false;
3908 if (!fFileBacked)
3909 return true;
3910 return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
3911}
3912
3913bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
3914{
3915 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
3916 return true;
3917}
3918
3919bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
3920{
3921 std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
3922 if(i != mapAddressBook.end())
3923 {
3924 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
3925 if(j != i->second.destdata.end())
3926 {
3927 if(value)
3928 *value = j->second;
3929 return true;
3930 }
3931 }
3932 return false;
3933}
af8297c0
WL
3934
3935CKeyPool::CKeyPool()
3936{
3937 nTime = GetTime();
3938}
3939
3940CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
3941{
3942 nTime = GetTime();
3943 vchPubKey = vchPubKeyIn;
3944}
3945
3946CWalletKey::CWalletKey(int64_t nExpires)
3947{
3948 nTimeCreated = (nExpires ? GetTime() : 0);
3949 nTimeExpires = nExpires;
3950}
0101483f 3951
4b0deb3b 3952int CMerkleTx::SetMerkleBranch(const CBlock& block)
0101483f
WL
3953{
3954 AssertLockHeld(cs_main);
3955 CBlock blockTmp;
3956
4b0deb3b
DK
3957 // Update the tx's hashBlock
3958 hashBlock = block.GetHash();
0101483f 3959
4b0deb3b
DK
3960 // Locate the transaction
3961 for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++)
3962 if (block.vtx[nIndex] == *(CTransaction*)this)
3963 break;
3964 if (nIndex == (int)block.vtx.size())
3965 {
3966 vMerkleBranch.clear();
3967 nIndex = -1;
5262fde0 3968 LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
4b0deb3b 3969 return 0;
0101483f
WL
3970 }
3971
4b0deb3b
DK
3972 // Fill in merkle branch
3973 vMerkleBranch = block.GetMerkleBranch(nIndex);
3974
0101483f 3975 // Is the tx in a block that's in the main chain
145d5be8 3976 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
0101483f
WL
3977 if (mi == mapBlockIndex.end())
3978 return 0;
4b0deb3b 3979 const CBlockIndex* pindex = (*mi).second;
0101483f
WL
3980 if (!pindex || !chainActive.Contains(pindex))
3981 return 0;
3982
3983 return chainActive.Height() - pindex->nHeight + 1;
3984}
3985
a31e8bad 3986int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
0101483f 3987{
4f152496 3988 if (hashBlock.IsNull() || nIndex == -1)
0101483f
WL
3989 return 0;
3990 AssertLockHeld(cs_main);
3991
3992 // Find the block it claims to be in
145d5be8 3993 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
0101483f
WL
3994 if (mi == mapBlockIndex.end())
3995 return 0;
3996 CBlockIndex* pindex = (*mi).second;
3997 if (!pindex || !chainActive.Contains(pindex))
3998 return 0;
3999
4000 // Make sure the merkle branch connects to this block
4001 if (!fMerkleVerified)
4002 {
805344dc 4003 if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
0101483f
WL
4004 return 0;
4005 fMerkleVerified = true;
4006 }
4007
4008 pindexRet = pindex;
4009 return chainActive.Height() - pindex->nHeight + 1;
4010}
4011
a31e8bad 4012int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
0101483f
WL
4013{
4014 AssertLockHeld(cs_main);
4015 int nResult = GetDepthInMainChainINTERNAL(pindexRet);
805344dc 4016 if (nResult == 0 && !mempool.exists(GetHash()))
0101483f
WL
4017 return -1; // Not in chain, not in mempool
4018
4019 return nResult;
4020}
4021
4022int CMerkleTx::GetBlocksToMaturity() const
4023{
7a90b9dd 4024 if ( ASSETCHAINS_SYMBOL[0] == 0 )
4025 COINBASE_MATURITY = _COINBASE_MATURITY;
0101483f
WL
4026 if (!IsCoinBase())
4027 return 0;
39267c35 4028 int32_t depth = GetDepthInMainChain();
204cf3fc 4029 int32_t ut = UnlockTime(0);
c2f6623f 4030 int32_t toMaturity = (ut - chainActive.Height()) < 0 ? 0 : ut - chainActive.Height();
4031 //printf("depth.%i, unlockTime.%i, toMaturity.%i\n", depth, ut, toMaturity);
4032 ut = (COINBASE_MATURITY - depth) < 0 ? 0 : COINBASE_MATURITY - depth;
204cf3fc 4033 return(ut < toMaturity ? toMaturity : ut);
0101483f
WL
4034}
4035
1371e6f5 4036bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
0101483f
WL
4037{
4038 CValidationState state;
1371e6f5 4039 return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
0101483f
WL
4040}
4041
cb0d208f
S
4042/**
4043 * Find notes in the wallet filtered by payment address, min depth and ability to spend.
4044 * These notes are decrypted and added to the output parameter vector, outEntries.
4045 */
9a2b8ae5 4046void CWallet::GetFilteredNotes(std::vector<CNotePlaintextEntry> & outEntries, std::string address, int minDepth, bool ignoreSpent, bool ignoreUnspendable)
a5ac2e25 4047{
bdbe8e85
JG
4048 std::set<PaymentAddress> filterAddresses;
4049
a5ac2e25 4050 if (address.length() > 0) {
bdbe8e85 4051 filterAddresses.insert(CZCPaymentAddress(address).Get());
a5ac2e25
S
4052 }
4053
bdbe8e85
JG
4054 GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable);
4055}
4056
4057/**
4058 * Find notes in the wallet filtered by payment addresses, min depth and ability to spend.
4059 * These notes are decrypted and added to the output parameter vector, outEntries.
4060 */
4061void CWallet::GetFilteredNotes(
4062 std::vector<CNotePlaintextEntry>& outEntries,
4063 std::set<PaymentAddress>& filterAddresses,
4064 int minDepth,
4065 bool ignoreSpent,
4066 bool ignoreUnspendable)
4067{
a5ac2e25
S
4068 LOCK2(cs_main, cs_wallet);
4069
4070 for (auto & p : mapWallet) {
4071 CWalletTx wtx = p.second;
4072
4073 // Filter the transactions before checking for notes
4074 if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < minDepth) {
4075 continue;
4076 }
4077
dec49d1f 4078 if (wtx.mapNoteData.size() == 0) {
a5ac2e25
S
4079 continue;
4080 }
4081
dec49d1f 4082 for (auto & pair : wtx.mapNoteData) {
a5ac2e25
S
4083 JSOutPoint jsop = pair.first;
4084 CNoteData nd = pair.second;
4085 PaymentAddress pa = nd.address;
4086
4087 // skip notes which belong to a different payment address in the wallet
bdbe8e85 4088 if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
a5ac2e25
S
4089 continue;
4090 }
4091
4092 // skip note which has been spent
1a62587e 4093 if (ignoreSpent && nd.nullifier && IsSpent(*nd.nullifier)) {
a5ac2e25
S
4094 continue;
4095 }
4096
9a2b8ae5
JG
4097 // skip notes which cannot be spent
4098 if (ignoreUnspendable && !HaveSpendingKey(pa)) {
4099 continue;
4100 }
98a4f6a6
BM
4101
4102 // skip locked notes
4103 if (IsLockedNote(jsop.hash, jsop.js, jsop.n)) {
4104 continue;
4105 }
9a2b8ae5 4106
a5ac2e25
S
4107 int i = jsop.js; // Index into CTransaction.vjoinsplit
4108 int j = jsop.n; // Index into JSDescription.ciphertexts
4109
4110 // Get cached decryptor
4111 ZCNoteDecryption decryptor;
4112 if (!GetNoteDecryptor(pa, decryptor)) {
4113 // Note decryptors are created when the wallet is loaded, so it should always exist
4114 throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", CZCPaymentAddress(pa).ToString()));
4115 }
4116
4117 // determine amount of funds in the note
4118 auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey);
4119 try {
4120 NotePlaintext plaintext = NotePlaintext::decrypt(
4121 decryptor,
4122 wtx.vjoinsplit[i].ciphertexts[j],
4123 wtx.vjoinsplit[i].ephemeralKey,
4124 hSig,
4125 (unsigned char) j);
4126
bdbe8e85 4127 outEntries.push_back(CNotePlaintextEntry{jsop, pa, plaintext});
a5ac2e25 4128
51fde9ea 4129 } catch (const note_decryption_failed &err) {
a5ac2e25
S
4130 // Couldn't decrypt with this spending key
4131 throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", CZCPaymentAddress(pa).ToString()));
51fde9ea
JG
4132 } catch (const std::exception &exc) {
4133 // Unexpected failure
4134 throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", CZCPaymentAddress(pa).ToString(), exc.what()));
a5ac2e25
S
4135 }
4136 }
4137 }
4138}
This page took 1.194202 seconds and 4 git commands to generate.