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