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