]> Git Repo - VerusCoin.git/blame - src/wallet/wallet.cpp
Rename CWallet::AddToSpends methods for clarity.
[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) {
586 if (mapTxNullifiers.count(nullifier) <= 1) {
587 continue; // No conflict if zero or one spends
588 }
589 range_n = mapTxNullifiers.equal_range(nullifier);
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;
716 range = mapTxNullifiers.equal_range(nullifier);
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
JG
738{
739 mapTxNullifiers.insert(make_pair(nullifier, wtxid));
740
741 pair<TxNullifiers::iterator, TxNullifiers::iterator> range;
742 range = mapTxNullifiers.equal_range(nullifier);
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{
005f3ad1 1313 if (wtxIn.mapSproutNoteData.empty() || wtxIn.mapSproutNoteData == wtx.mapSproutNoteData) {
ac1c9435
JG
1314 return false;
1315 }
005f3ad1 1316 auto tmp = wtxIn.mapSproutNoteData;
ac1c9435 1317 // Ensure we keep any cached witnesses we may already have
005f3ad1 1318 for (const std::pair<JSOutPoint, SproutNoteData> nd : wtx.mapSproutNoteData) {
ac1c9435
JG
1319 if (tmp.count(nd.first) && nd.second.witnesses.size() > 0) {
1320 tmp.at(nd.first).witnesses.assign(
1321 nd.second.witnesses.cbegin(), nd.second.witnesses.cend());
1322 }
4a6a4847 1323 tmp.at(nd.first).witnessHeight = nd.second.witnessHeight;
ac1c9435
JG
1324 }
1325 // Now copy over the updated note data
005f3ad1 1326 wtx.mapSproutNoteData = tmp;
ac1c9435
JG
1327 return true;
1328}
1329
5b40d886
MF
1330/**
1331 * Add a transaction to the wallet, or update it.
1332 * pblock is optional, but should be provided if the transaction is known to be in a block.
1333 * If fUpdate is true, existing transactions will be updated.
1334 */
d38da59b 1335bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
e8ef3da7 1336{
e8ef3da7 1337 {
53d56881 1338 AssertLockHeld(cs_wallet);
805344dc 1339 bool fExisted = mapWallet.count(tx.GetHash()) != 0;
6cc4a62c 1340 if (fExisted && !fUpdate) return false;
57faf44e 1341 auto noteData = FindMySproutNotes(tx);
c3a7307a 1342 if (fExisted || IsMine(tx) || IsFromMe(tx) || noteData.size() > 0)
6cc4a62c
GA
1343 {
1344 CWalletTx wtx(this,tx);
44bc988e 1345
be74c80d 1346 if (noteData.size() > 0) {
8e8279e7 1347 wtx.SetSproutNoteData(noteData);
be74c80d 1348 }
8e8279e7 1349 // TODO: Sapling note data
c3a7307a 1350
6cc4a62c
GA
1351 // Get merkle branch if transaction was found in a block
1352 if (pblock)
4b0deb3b 1353 wtx.SetMerkleBranch(*pblock);
44bc988e
CL
1354
1355 // Do not flush the wallet here for performance reasons
1356 // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
1357 CWalletDB walletdb(strWalletFile, "r+", false);
1358
1359 return AddToWallet(wtx, false, &walletdb);
6cc4a62c 1360 }
e8ef3da7 1361 }
e8ef3da7
WL
1362 return false;
1363}
1364
d38da59b 1365void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
93a18a36 1366{
55a1db4f 1367 LOCK2(cs_main, cs_wallet);
d38da59b 1368 if (!AddToWalletIfInvolvingMe(tx, pblock, true))
93a18a36
GA
1369 return; // Not one of ours
1370
ac1c9435
JG
1371 MarkAffectedTransactionsDirty(tx);
1372}
1373
1374void CWallet::MarkAffectedTransactionsDirty(const CTransaction& tx)
1375{
93a18a36
GA
1376 // If a transaction changes 'conflicted' state, that changes the balance
1377 // available of the outputs it spends. So force those to be
1378 // recomputed, also:
1379 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1380 {
1381 if (mapWallet.count(txin.prevout.hash))
1382 mapWallet[txin.prevout.hash].MarkDirty();
1383 }
8db7e25c
JG
1384 for (const JSDescription& jsdesc : tx.vjoinsplit) {
1385 for (const uint256& nullifier : jsdesc.nullifiers) {
f41bf503
S
1386 if (mapSproutNullifiersToNotes.count(nullifier) &&
1387 mapWallet.count(mapSproutNullifiersToNotes[nullifier].hash)) {
1388 mapWallet[mapSproutNullifiersToNotes[nullifier].hash].MarkDirty();
8db7e25c
JG
1389 }
1390 }
1391 }
00588c3f
PW
1392}
1393
1394void CWallet::EraseFromWallet(const uint256 &hash)
e8ef3da7
WL
1395{
1396 if (!fFileBacked)
00588c3f 1397 return;
e8ef3da7 1398 {
f8dcd5ca 1399 LOCK(cs_wallet);
e8ef3da7
WL
1400 if (mapWallet.erase(hash))
1401 CWalletDB(strWalletFile).EraseTx(hash);
1402 }
00588c3f 1403 return;
e8ef3da7
WL
1404}
1405
1406
1a62587e
JG
1407/**
1408 * Returns a nullifier if the SpendingKey is available
1409 * Throws std::runtime_error if the decryptor doesn't match this note
1410 */
618206c7
S
1411boost::optional<uint256> CWallet::GetSproutNoteNullifier(const JSDescription &jsdesc,
1412 const libzcash::SproutPaymentAddress &address,
1413 const ZCNoteDecryption &dec,
1414 const uint256 &hSig,
1415 uint8_t n) const
1a62587e
JG
1416{
1417 boost::optional<uint256> ret;
5020a936 1418 auto note_pt = libzcash::SproutNotePlaintext::decrypt(
1a62587e
JG
1419 dec,
1420 jsdesc.ciphertexts[n],
1421 jsdesc.ephemeralKey,
1422 hSig,
1423 (unsigned char) n);
1424 auto note = note_pt.note(address);
9a2b8ae5
JG
1425 // SpendingKeys are only available if:
1426 // - We have them (this isn't a viewing key)
1427 // - The wallet is unlocked
e5eab182 1428 libzcash::SproutSpendingKey key;
25d5e80c 1429 if (GetSproutSpendingKey(address, key)) {
1a62587e
JG
1430 ret = note.nullifier(key);
1431 }
1432 return ret;
1433}
1434
e492d986
JG
1435/**
1436 * Finds all output notes in the given transaction that have been sent to
1437 * PaymentAddresses in this wallet.
1438 *
1439 * It should never be necessary to call this method with a CWalletTx, because
57faf44e 1440 * the result of FindMySproutNotes (for the addresses available at the time) will
005f3ad1 1441 * already have been cached in CWalletTx.mapSproutNoteData.
e492d986 1442 */
57faf44e 1443mapSproutNoteData_t CWallet::FindMySproutNotes(const CTransaction &tx) const
02e67455 1444{
3fac1020 1445 LOCK(cs_SpendingKeyStore);
fa511e10 1446 uint256 hash = tx.GetHash();
02e67455 1447
005f3ad1 1448 mapSproutNoteData_t noteData;
02e67455
JG
1449 for (size_t i = 0; i < tx.vjoinsplit.size(); i++) {
1450 auto hSig = tx.vjoinsplit[i].h_sig(*pzcashParams, tx.joinSplitPubKey);
1451 for (uint8_t j = 0; j < tx.vjoinsplit[i].ciphertexts.size(); j++) {
3fac1020 1452 for (const NoteDecryptorMap::value_type& item : mapNoteDecryptors) {
02e67455 1453 try {
02e67455 1454 auto address = item.first;
02e67455 1455 JSOutPoint jsoutpt {hash, i, j};
618206c7 1456 auto nullifier = GetSproutNoteNullifier(
1a62587e
JG
1457 tx.vjoinsplit[i],
1458 address,
1459 item.second,
1460 hSig, j);
1461 if (nullifier) {
005f3ad1 1462 SproutNoteData nd {address, *nullifier};
1a62587e
JG
1463 noteData.insert(std::make_pair(jsoutpt, nd));
1464 } else {
005f3ad1 1465 SproutNoteData nd {address};
1a62587e
JG
1466 noteData.insert(std::make_pair(jsoutpt, nd));
1467 }
02e67455 1468 break;
51fde9ea 1469 } catch (const note_decryption_failed &err) {
1a62587e 1470 // Couldn't decrypt with this decryptor
32a103aa
JG
1471 } catch (const std::exception &exc) {
1472 // Unexpected failure
57faf44e 1473 LogPrintf("FindMySproutNotes(): Unexpected error while testing decrypt:\n");
32a103aa 1474 LogPrintf("%s\n", exc.what());
02e67455
JG
1475 }
1476 }
1477 }
1478 }
1479 return noteData;
1480}
1481
1551db87
JG
1482bool CWallet::IsFromMe(const uint256& nullifier) const
1483{
1484 {
1485 LOCK(cs_wallet);
f41bf503
S
1486 if (mapSproutNullifiersToNotes.count(nullifier) &&
1487 mapWallet.count(mapSproutNullifiersToNotes.at(nullifier).hash)) {
1551db87
JG
1488 return true;
1489 }
1490 }
1491 return false;
1492}
1493
8e8279e7 1494void CWallet::GetSproutNoteWitnesses(std::vector<JSOutPoint> notes,
8ea8ef98 1495 std::vector<boost::optional<SproutWitness>>& witnesses,
8e8279e7 1496 uint256 &final_anchor)
be74c80d 1497{
29523dc7
EOW
1498 LOCK(cs_wallet);
1499 witnesses.resize(notes.size());
1500 boost::optional<uint256> rt;
1501 int i = 0;
1502 for (JSOutPoint note : notes) {
1503 if (mapWallet.count(note.hash) &&
1504 mapWallet[note.hash].mapSproutNoteData.count(note) &&
1505 mapWallet[note.hash].mapSproutNoteData[note].witnesses.size() > 0) {
1506 witnesses[i] = mapWallet[note.hash].mapSproutNoteData[note].witnesses.front();
1507 if (!rt) {
1508 rt = witnesses[i]->root();
1509 } else {
1510 assert(*rt == witnesses[i]->root());
be74c80d 1511 }
be74c80d 1512 }
29523dc7
EOW
1513 i++;
1514 }
1515 // All returned witnesses have the same anchor
1516 if (rt) {
1517 final_anchor = *rt;
be74c80d
JG
1518 }
1519}
1520
e6b0a8b9 1521void CWallet::GetSaplingNoteWitnesses(std::vector<SaplingOutPoint> notes,
8ea8ef98 1522 std::vector<boost::optional<SaplingWitness>>& witnesses,
e6b0a8b9
EOW
1523 uint256 &final_anchor)
1524{
1525 LOCK(cs_wallet);
1526 witnesses.resize(notes.size());
1527 boost::optional<uint256> rt;
1528 int i = 0;
1529 for (SaplingOutPoint note : notes) {
1530 if (mapWallet.count(note.hash) &&
1531 mapWallet[note.hash].mapSaplingNoteData.count(note) &&
1532 mapWallet[note.hash].mapSaplingNoteData[note].witnesses.size() > 0) {
1533 witnesses[i] = mapWallet[note.hash].mapSaplingNoteData[note].witnesses.front();
1534 if (!rt) {
1535 rt = witnesses[i]->root();
1536 } else {
1537 assert(*rt == witnesses[i]->root());
1538 }
1539 }
1540 i++;
1541 }
1542 // All returned witnesses have the same anchor
1543 if (rt) {
1544 final_anchor = *rt;
1545 }
1546}
1547
c8988460 1548isminetype CWallet::IsMine(const CTxIn &txin) const
e8ef3da7 1549{
e8ef3da7 1550 {
f8dcd5ca 1551 LOCK(cs_wallet);
e8ef3da7
WL
1552 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1553 if (mi != mapWallet.end())
1554 {
1555 const CWalletTx& prev = (*mi).second;
1556 if (txin.prevout.n < prev.vout.size())
c8988460 1557 return IsMine(prev.vout[txin.prevout.n]);
e8ef3da7
WL
1558 }
1559 }
a3e192a3 1560 return ISMINE_NO;
e8ef3da7
WL
1561}
1562
a372168e 1563CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
e8ef3da7 1564{
e8ef3da7 1565 {
f8dcd5ca 1566 LOCK(cs_wallet);
e8ef3da7
WL
1567 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1568 if (mi != mapWallet.end())
1569 {
1570 const CWalletTx& prev = (*mi).second;
1571 if (txin.prevout.n < prev.vout.size())
d4640d7d 1572 if (IsMine(prev.vout[txin.prevout.n]) & filter)
e8ef3da7
WL
1573 return prev.vout[txin.prevout.n].nValue;
1574 }
1575 }
1576 return 0;
1577}
1578
eca0b1ea
JT
1579isminetype CWallet::IsMine(const CTxOut& txout) const
1580{
1581 return ::IsMine(*this, txout.scriptPubKey);
1582}
1583
1584CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
1585{
1586 if (!MoneyRange(txout.nValue))
1587 throw std::runtime_error("CWallet::GetCredit(): value out of range");
1588 return ((IsMine(txout) & filter) ? txout.nValue : 0);
1589}
1590
e679ec96
GA
1591bool CWallet::IsChange(const CTxOut& txout) const
1592{
2a45a494 1593 // TODO: fix handling of 'change' outputs. The assumption is that any
d5087d1b 1594 // payment to a script that is ours, but is not in the address book
2a45a494
GA
1595 // is change. That assumption is likely to break when we implement multisignature
1596 // wallets that return change back into a multi-signature-protected address;
1597 // a better way of identifying which outputs are 'the send' and which are
1598 // 'the change' will need to be implemented (maybe extend CWalletTx to remember
1599 // which output, if any, was change).
d5087d1b 1600 if (::IsMine(*this, txout.scriptPubKey))
f8dcd5ca 1601 {
d5087d1b
PW
1602 CTxDestination address;
1603 if (!ExtractDestination(txout.scriptPubKey, address))
1604 return true;
1605
f8dcd5ca
PW
1606 LOCK(cs_wallet);
1607 if (!mapAddressBook.count(address))
1608 return true;
1609 }
e679ec96
GA
1610 return false;
1611}
1612
eca0b1ea
JT
1613CAmount CWallet::GetChange(const CTxOut& txout) const
1614{
1615 if (!MoneyRange(txout.nValue))
1616 throw std::runtime_error("CWallet::GetChange(): value out of range");
1617 return (IsChange(txout) ? txout.nValue : 0);
1618}
1619
1620bool CWallet::IsMine(const CTransaction& tx) const
1621{
1622 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1623 if (IsMine(txout))
1624 return true;
1625 return false;
1626}
1627
1628bool CWallet::IsFromMe(const CTransaction& tx) const
1629{
1551db87
JG
1630 if (GetDebit(tx, ISMINE_ALL) > 0) {
1631 return true;
1632 }
1633 for (const JSDescription& jsdesc : tx.vjoinsplit) {
1634 for (const uint256& nullifier : jsdesc.nullifiers) {
1635 if (IsFromMe(nullifier)) {
1636 return true;
1637 }
1638 }
1639 }
1640 return false;
eca0b1ea
JT
1641}
1642
1643CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
1644{
1645 CAmount nDebit = 0;
1646 BOOST_FOREACH(const CTxIn& txin, tx.vin)
1647 {
1648 nDebit += GetDebit(txin, filter);
1649 if (!MoneyRange(nDebit))
1650 throw std::runtime_error("CWallet::GetDebit(): value out of range");
1651 }
1652 return nDebit;
1653}
1654
1655CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
1656{
1657 CAmount nCredit = 0;
1658 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1659 {
1660 nCredit += GetCredit(txout, filter);
1661 if (!MoneyRange(nCredit))
1662 throw std::runtime_error("CWallet::GetCredit(): value out of range");
1663 }
1664 return nCredit;
1665}
1666
1667CAmount CWallet::GetChange(const CTransaction& tx) const
1668{
1669 CAmount nChange = 0;
1670 BOOST_FOREACH(const CTxOut& txout, tx.vout)
1671 {
1672 nChange += GetChange(txout);
1673 if (!MoneyRange(nChange))
1674 throw std::runtime_error("CWallet::GetChange(): value out of range");
1675 }
1676 return nChange;
1677}
1678
8e8279e7 1679void CWalletTx::SetSproutNoteData(mapSproutNoteData_t &noteData)
c3a7307a 1680{
005f3ad1
EOW
1681 mapSproutNoteData.clear();
1682 for (const std::pair<JSOutPoint, SproutNoteData> nd : noteData) {
c3a7307a
JG
1683 if (nd.first.js < vjoinsplit.size() &&
1684 nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
1685 // Store the address and nullifier for the Note
005f3ad1 1686 mapSproutNoteData[nd.first] = nd.second;
c3a7307a 1687 } else {
57faf44e 1688 // If FindMySproutNotes() was used to obtain noteData,
c3a7307a 1689 // this should never happen
8e8279e7 1690 throw std::logic_error("CWalletTx::SetSproutNoteData(): Invalid note");
c3a7307a
JG
1691 }
1692 }
1693}
1694
e6b0a8b9
EOW
1695void CWalletTx::SetSaplingNoteData(mapSaplingNoteData_t &noteData)
1696{
1697 mapSaplingNoteData.clear();
1698 for (const std::pair<SaplingOutPoint, SaplingNoteData> nd : noteData) {
1699 if (nd.first.n < vShieldedOutput.size()) {
1700 mapSaplingNoteData[nd.first] = nd.second;
1701 } else {
1702 throw std::logic_error("CWalletTx::SetSaplingNoteData(): Invalid note");
1703 }
1704 }
1705}
1706
51ed9ec9 1707int64_t CWalletTx::GetTxTime() const
e8ef3da7 1708{
51ed9ec9 1709 int64_t n = nTimeSmart;
c3f95ef1 1710 return n ? n : nTimeReceived;
e8ef3da7
WL
1711}
1712
1713int CWalletTx::GetRequestCount() const
1714{
1715 // Returns -1 if it wasn't being tracked
1716 int nRequests = -1;
e8ef3da7 1717 {
f8dcd5ca 1718 LOCK(pwallet->cs_wallet);
e8ef3da7
WL
1719 if (IsCoinBase())
1720 {
1721 // Generated block
4f152496 1722 if (!hashBlock.IsNull())
e8ef3da7
WL
1723 {
1724 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
1725 if (mi != pwallet->mapRequestCount.end())
1726 nRequests = (*mi).second;
1727 }
1728 }
1729 else
1730 {
1731 // Did anyone request this transaction?
805344dc 1732 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
e8ef3da7
WL
1733 if (mi != pwallet->mapRequestCount.end())
1734 {
1735 nRequests = (*mi).second;
1736
1737 // How about the block it's in?
4f152496 1738 if (nRequests == 0 && !hashBlock.IsNull())
e8ef3da7
WL
1739 {
1740 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
1741 if (mi != pwallet->mapRequestCount.end())
1742 nRequests = (*mi).second;
1743 else
1744 nRequests = 1; // If it's in someone else's block it must have got out
1745 }
1746 }
1747 }
1748 }
1749 return nRequests;
1750}
1751
86cf60b5 1752// GetAmounts will determine the transparent debits and credits for a given wallet tx.
1b4568cb 1753void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
a372168e 1754 list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
e8ef3da7 1755{
e07c8e91 1756 nFee = 0;
e8ef3da7
WL
1757 listReceived.clear();
1758 listSent.clear();
1759 strSentAccount = strFromAccount;
1760
86cf60b5 1761 // Is this tx sent/signed by me?
a372168e 1762 CAmount nDebit = GetDebit(filter);
86cf60b5
S
1763 bool isFromMyTaddr = nDebit > 0; // debit>0 means we signed/sent this transaction
1764
1765 // Does this tx spend my notes?
1766 bool isFromMyZaddr = false;
1767 for (const JSDescription& js : vjoinsplit) {
1768 for (const uint256& nullifier : js.nullifiers) {
1769 if (pwallet->IsFromMe(nullifier)) {
1770 isFromMyZaddr = true;
1771 break;
1772 }
1773 }
1774 if (isFromMyZaddr) {
1775 break;
1776 }
1777 }
1778
1779 // Compute fee if we sent this transaction.
1780 if (isFromMyTaddr) {
1781 CAmount nValueOut = GetValueOut(); // transparent outputs plus all vpub_old
1782 CAmount nValueIn = 0;
97b46f00 1783 nValueIn += GetShieldedValueIn();
86cf60b5
S
1784 nFee = nDebit - nValueOut + nValueIn;
1785 }
1786
1787 // Create output entry for vpub_old/new, if we sent utxos from this transaction
1788 if (isFromMyTaddr) {
1789 CAmount myVpubOld = 0;
1790 CAmount myVpubNew = 0;
1791 for (const JSDescription& js : vjoinsplit) {
1792 bool fMyJSDesc = false;
1793
1794 // Check input side
1795 for (const uint256& nullifier : js.nullifiers) {
1796 if (pwallet->IsFromMe(nullifier)) {
1797 fMyJSDesc = true;
1798 break;
1799 }
1800 }
1801
1802 // Check output side
1803 if (!fMyJSDesc) {
005f3ad1 1804 for (const std::pair<JSOutPoint, SproutNoteData> nd : this->mapSproutNoteData) {
86cf60b5
S
1805 if (nd.first.js < vjoinsplit.size() && nd.first.n < vjoinsplit[nd.first.js].ciphertexts.size()) {
1806 fMyJSDesc = true;
1807 break;
1808 }
1809 }
1810 }
1811
1812 if (fMyJSDesc) {
1813 myVpubOld += js.vpub_old;
1814 myVpubNew += js.vpub_new;
1815 }
1816
1817 if (!MoneyRange(js.vpub_old) || !MoneyRange(js.vpub_new) || !MoneyRange(myVpubOld) || !MoneyRange(myVpubNew)) {
1818 throw std::runtime_error("CWalletTx::GetAmounts: value out of range");
1819 }
1820 }
1821
1822 // Create an output for the value taken from or added to the transparent value pool by JoinSplits
1823 if (myVpubOld > myVpubNew) {
1824 COutputEntry output = {CNoDestination(), myVpubOld - myVpubNew, (int)vout.size()};
1825 listSent.push_back(output);
1826 } else if (myVpubNew > myVpubOld) {
1827 COutputEntry output = {CNoDestination(), myVpubNew - myVpubOld, (int)vout.size()};
1828 listReceived.push_back(output);
1829 }
e8ef3da7
WL
1830 }
1831
e679ec96 1832 // Sent/received.
5bb76550 1833 for (unsigned int i = 0; i < vout.size(); ++i)
e8ef3da7 1834 {
1b4568cb 1835 const CTxOut& txout = vout[i];
a5c6c5d6 1836 isminetype fIsMine = pwallet->IsMine(txout);
96ed6821
LD
1837 // Only need to handle txouts if AT LEAST one of these is true:
1838 // 1) they debit from us (sent)
1839 // 2) the output is to us (received)
1840 if (nDebit > 0)
1841 {
1842 // Don't report 'change' txouts
1843 if (pwallet->IsChange(txout))
1844 continue;
96ed6821 1845 }
a5c6c5d6 1846 else if (!(fIsMine & filter))
96ed6821
LD
1847 continue;
1848
1849 // In either case, we need to get the destination address
10254401 1850 CTxDestination address;
10254401 1851 if (!ExtractDestination(txout.scriptPubKey, address))
e8ef3da7 1852 {
881a85a2 1853 LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
805344dc 1854 this->GetHash().ToString());
96ed6821 1855 address = CNoDestination();
e8ef3da7
WL
1856 }
1857
5bb76550 1858 COutputEntry output = {address, txout.nValue, (int)i};
1b4568cb 1859
96ed6821 1860 // If we are debited by the transaction, add the output as a "sent" entry
e8ef3da7 1861 if (nDebit > 0)
1b4568cb 1862 listSent.push_back(output);
e8ef3da7 1863
96ed6821 1864 // If we are receiving the output, add it as a "received" entry
d512534c 1865 if (fIsMine & filter)
1b4568cb 1866 listReceived.push_back(output);
e8ef3da7
WL
1867 }
1868
1869}
1870
a372168e
MF
1871void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
1872 CAmount& nSent, CAmount& nFee, const isminefilter& filter) const
e8ef3da7 1873{
e07c8e91 1874 nReceived = nSent = nFee = 0;
e8ef3da7 1875
a372168e 1876 CAmount allFee;
e8ef3da7 1877 string strSentAccount;
1b4568cb
CL
1878 list<COutputEntry> listReceived;
1879 list<COutputEntry> listSent;
d4640d7d 1880 GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
e8ef3da7 1881
e8ef3da7
WL
1882 if (strAccount == strSentAccount)
1883 {
1b4568cb
CL
1884 BOOST_FOREACH(const COutputEntry& s, listSent)
1885 nSent += s.amount;
e8ef3da7
WL
1886 nFee = allFee;
1887 }
e8ef3da7 1888 {
f8dcd5ca 1889 LOCK(pwallet->cs_wallet);
1b4568cb 1890 BOOST_FOREACH(const COutputEntry& r, listReceived)
e8ef3da7 1891 {
1b4568cb 1892 if (pwallet->mapAddressBook.count(r.destination))
e8ef3da7 1893 {
1b4568cb 1894 map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
61885513 1895 if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
1b4568cb 1896 nReceived += r.amount;
e8ef3da7
WL
1897 }
1898 else if (strAccount.empty())
1899 {
1b4568cb 1900 nReceived += r.amount;
e8ef3da7
WL
1901 }
1902 }
1903 }
1904}
1905
722fa283 1906
44bc988e 1907bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
e8ef3da7 1908{
805344dc 1909 return pwalletdb->WriteTx(GetHash(), *this);
e8ef3da7
WL
1910}
1911
4bc00dc1 1912void CWallet::WitnessNoteCommitment(std::vector<uint256> commitments,
8ea8ef98 1913 std::vector<boost::optional<SproutWitness>>& witnesses,
4bc00dc1 1914 uint256 &final_anchor)
a8ac403d 1915{
2dc35992 1916 witnesses.resize(commitments.size());
a8ac403d 1917 CBlockIndex* pindex = chainActive.Genesis();
4fc309f0 1918 SproutMerkleTree tree;
a8ac403d
SB
1919
1920 while (pindex) {
1921 CBlock block;
1922 ReadBlockFromDisk(block, pindex);
1923
1924 BOOST_FOREACH(const CTransaction& tx, block.vtx)
1925 {
22de1602 1926 BOOST_FOREACH(const JSDescription& jsdesc, tx.vjoinsplit)
a8ac403d 1927 {
22de1602 1928 BOOST_FOREACH(const uint256 &note_commitment, jsdesc.commitments)
a8ac403d 1929 {
4bc00dc1 1930 tree.append(note_commitment);
1760b3cd 1931
8ea8ef98 1932 BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) {
2dc35992 1933 if (wit) {
4bc00dc1 1934 wit->append(note_commitment);
2dc35992
SB
1935 }
1936 }
1937
1938 size_t i = 0;
1939 BOOST_FOREACH(uint256& commitment, commitments) {
4bc00dc1 1940 if (note_commitment == commitment) {
2dc35992 1941 witnesses.at(i) = tree.witness();
1760b3cd 1942 }
2dc35992 1943 i++;
a8ac403d
SB
1944 }
1945 }
1946 }
1947 }
1948
ccb439c5 1949 uint256 current_anchor = tree.root();
a8ac403d
SB
1950
1951 // Consistency check: we should be able to find the current tree
1952 // in our CCoins view.
4fc309f0 1953 SproutMerkleTree dummy_tree;
008f4ee8 1954 assert(pcoinsTip->GetSproutAnchorAt(current_anchor, dummy_tree));
a8ac403d
SB
1955
1956 pindex = chainActive.Next(pindex);
1957 }
1958
ccb439c5
SB
1959 // TODO: #93; Select a root via some heuristic.
1960 final_anchor = tree.root();
a8ac403d 1961
8ea8ef98 1962 BOOST_FOREACH(boost::optional<SproutWitness>& wit, witnesses) {
2dc35992
SB
1963 if (wit) {
1964 assert(final_anchor == wit->root());
1965 }
1760b3cd 1966 }
a8ac403d
SB
1967}
1968
5b40d886
MF
1969/**
1970 * Scan the block chain (starting in pindexStart) for transactions
1971 * from or to us. If fUpdate is true, found transactions that already
1972 * exist in the wallet will be updated.
1973 */
e8ef3da7
WL
1974int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
1975{
1976 int ret = 0;
75b8953a 1977 int64_t nNow = GetTime();
11982d36 1978 const CChainParams& chainParams = Params();
e8ef3da7
WL
1979
1980 CBlockIndex* pindex = pindexStart;
e8ef3da7 1981 {
55a1db4f 1982 LOCK2(cs_main, cs_wallet);
39278369
CL
1983
1984 // no need to read and scan block, if block was created before
1985 // our wallet birthday (as adjusted for block time variability)
209377a7 1986 while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
39278369
CL
1987 pindex = chainActive.Next(pindex);
1988
1989 ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
11982d36
CF
1990 double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
1991 double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false);
e8ef3da7
WL
1992 while (pindex)
1993 {
39278369 1994 if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
11982d36 1995 ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
8da9dd07 1996
e8ef3da7 1997 CBlock block;
7db120d5 1998 ReadBlockFromDisk(block, pindex);
e8ef3da7
WL
1999 BOOST_FOREACH(CTransaction& tx, block.vtx)
2000 {
d38da59b 2001 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
e8ef3da7
WL
2002 ret++;
2003 }
b6961fc1 2004
4fc309f0
EOW
2005 SproutMerkleTree sproutTree;
2006 SaplingMerkleTree saplingTree;
b6961fc1
JG
2007 // This should never fail: we should always be able to get the tree
2008 // state on the path to the tip of our chain
f86ee1c2
EOW
2009 assert(pcoinsTip->GetSproutAnchorAt(pindex->hashSproutAnchor, sproutTree));
2010 if (pindex->pprev) {
d9fe33b8
S
2011 if (NetworkUpgradeActive(pindex->pprev->nHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2012 assert(pcoinsTip->GetSaplingAnchorAt(pindex->pprev->hashFinalSaplingRoot, saplingTree));
2013 }
f86ee1c2 2014 }
b6961fc1 2015 // Increment note witness caches
f86ee1c2 2016 IncrementNoteWitnesses(pindex, &block, sproutTree, saplingTree);
b6961fc1 2017
4c6d41b8 2018 pindex = chainActive.Next(pindex);
75b8953a
B
2019 if (GetTime() >= nNow + 60) {
2020 nNow = GetTime();
11982d36 2021 LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
75b8953a 2022 }
e8ef3da7 2023 }
39278369 2024 ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
e8ef3da7
WL
2025 }
2026 return ret;
2027}
2028
2029void CWallet::ReacceptWalletTransactions()
2030{
7e6d23b1 2031 // If transactions aren't being broadcasted, don't let them into local mempool either
6f252627
WL
2032 if (!fBroadcastTransactions)
2033 return;
55a1db4f 2034 LOCK2(cs_main, cs_wallet);
e9c3215b 2035 std::map<int64_t, CWalletTx*> mapSorted;
2036
2037 // Sort pending wallet transactions based on their initial wallet insertion order
93a18a36 2038 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
e8ef3da7 2039 {
93a18a36
GA
2040 const uint256& wtxid = item.first;
2041 CWalletTx& wtx = item.second;
805344dc 2042 assert(wtx.GetHash() == wtxid);
e8ef3da7 2043
93a18a36
GA
2044 int nDepth = wtx.GetDepthInMainChain();
2045
e9c3215b 2046 if (!wtx.IsCoinBase() && nDepth < 0) {
2047 mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
e8ef3da7
WL
2048 }
2049 }
e9c3215b 2050
2051 // Try to add wallet transactions to memory pool
2052 BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted)
2053 {
2054 CWalletTx& wtx = *(item.second);
2055
2056 LOCK(mempool.cs);
2057 wtx.AcceptToMemoryPool(false);
2058 }
e8ef3da7
WL
2059}
2060
0f5954c4 2061bool CWalletTx::RelayWalletTransaction()
e8ef3da7 2062{
6f252627 2063 assert(pwallet->GetBroadcastTransactions());
e8ef3da7
WL
2064 if (!IsCoinBase())
2065 {
5eaf91a4 2066 if (GetDepthInMainChain() == 0) {
805344dc 2067 LogPrintf("Relaying wtx %s\n", GetHash().ToString());
d38da59b 2068 RelayTransaction((CTransaction)*this);
0f5954c4 2069 return true;
e8ef3da7
WL
2070 }
2071 }
0f5954c4 2072 return false;
e8ef3da7
WL
2073}
2074
3015e0bc 2075set<uint256> CWalletTx::GetConflicts() const
731b89b8
GA
2076{
2077 set<uint256> result;
2078 if (pwallet != NULL)
2079 {
805344dc 2080 uint256 myHash = GetHash();
3015e0bc 2081 result = pwallet->GetConflicts(myHash);
731b89b8
GA
2082 result.erase(myHash);
2083 }
2084 return result;
2085}
2086
bbacd882
CF
2087CAmount CWalletTx::GetDebit(const isminefilter& filter) const
2088{
2089 if (vin.empty())
2090 return 0;
2091
2092 CAmount debit = 0;
2093 if(filter & ISMINE_SPENDABLE)
2094 {
2095 if (fDebitCached)
2096 debit += nDebitCached;
2097 else
2098 {
2099 nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
2100 fDebitCached = true;
2101 debit += nDebitCached;
2102 }
2103 }
2104 if(filter & ISMINE_WATCH_ONLY)
2105 {
2106 if(fWatchDebitCached)
2107 debit += nWatchDebitCached;
2108 else
2109 {
2110 nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
2111 fWatchDebitCached = true;
2112 debit += nWatchDebitCached;
2113 }
2114 }
2115 return debit;
2116}
2117
2118CAmount CWalletTx::GetCredit(const isminefilter& filter) const
2119{
2120 // Must wait until coinbase is safely deep enough in the chain before valuing it
2121 if (IsCoinBase() && GetBlocksToMaturity() > 0)
2122 return 0;
2123
2124 int64_t credit = 0;
2125 if (filter & ISMINE_SPENDABLE)
2126 {
2127 // GetBalance can assume transactions in mapWallet won't change
2128 if (fCreditCached)
2129 credit += nCreditCached;
2130 else
2131 {
2132 nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
2133 fCreditCached = true;
2134 credit += nCreditCached;
2135 }
2136 }
2137 if (filter & ISMINE_WATCH_ONLY)
2138 {
2139 if (fWatchCreditCached)
2140 credit += nWatchCreditCached;
2141 else
2142 {
2143 nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
2144 fWatchCreditCached = true;
2145 credit += nWatchCreditCached;
2146 }
2147 }
2148 return credit;
2149}
2150
2151CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
2152{
2153 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
2154 {
2155 if (fUseCache && fImmatureCreditCached)
2156 return nImmatureCreditCached;
2157 nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
2158 fImmatureCreditCached = true;
2159 return nImmatureCreditCached;
2160 }
2161
2162 return 0;
2163}
2164
2165CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
2166{
2167 if (pwallet == 0)
2168 return 0;
2169
2170 // Must wait until coinbase is safely deep enough in the chain before valuing it
2171 if (IsCoinBase() && GetBlocksToMaturity() > 0)
2172 return 0;
2173
2174 if (fUseCache && fAvailableCreditCached)
2175 return nAvailableCreditCached;
2176
2177 CAmount nCredit = 0;
805344dc 2178 uint256 hashTx = GetHash();
bbacd882
CF
2179 for (unsigned int i = 0; i < vout.size(); i++)
2180 {
2181 if (!pwallet->IsSpent(hashTx, i))
2182 {
2183 const CTxOut &txout = vout[i];
2184 nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
2185 if (!MoneyRange(nCredit))
2186 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
2187 }
2188 }
2189
2190 nAvailableCreditCached = nCredit;
2191 fAvailableCreditCached = true;
2192 return nCredit;
2193}
2194
2195CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
2196{
2197 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
2198 {
2199 if (fUseCache && fImmatureWatchCreditCached)
2200 return nImmatureWatchCreditCached;
2201 nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
2202 fImmatureWatchCreditCached = true;
2203 return nImmatureWatchCreditCached;
2204 }
2205
2206 return 0;
2207}
2208
2209CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
2210{
2211 if (pwallet == 0)
2212 return 0;
2213
2214 // Must wait until coinbase is safely deep enough in the chain before valuing it
2215 if (IsCoinBase() && GetBlocksToMaturity() > 0)
2216 return 0;
2217
2218 if (fUseCache && fAvailableWatchCreditCached)
2219 return nAvailableWatchCreditCached;
2220
2221 CAmount nCredit = 0;
2222 for (unsigned int i = 0; i < vout.size(); i++)
2223 {
805344dc 2224 if (!pwallet->IsSpent(GetHash(), i))
bbacd882
CF
2225 {
2226 const CTxOut &txout = vout[i];
2227 nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
2228 if (!MoneyRange(nCredit))
2229 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
2230 }
2231 }
2232
2233 nAvailableWatchCreditCached = nCredit;
2234 fAvailableWatchCreditCached = true;
2235 return nCredit;
2236}
2237
2238CAmount CWalletTx::GetChange() const
2239{
2240 if (fChangeCached)
2241 return nChangeCached;
2242 nChangeCached = pwallet->GetChange(*this);
2243 fChangeCached = true;
2244 return nChangeCached;
2245}
2246
2247bool CWalletTx::IsTrusted() const
2248{
2249 // Quick answer in most cases
75a4d512 2250 if (!CheckFinalTx(*this))
bbacd882
CF
2251 return false;
2252 int nDepth = GetDepthInMainChain();
2253 if (nDepth >= 1)
2254 return true;
2255 if (nDepth < 0)
2256 return false;
2257 if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
2258 return false;
2259
2260 // Trusted if all inputs are from us and are in the mempool:
2261 BOOST_FOREACH(const CTxIn& txin, vin)
2262 {
2263 // Transactions not sent by us: not trusted
2264 const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
2265 if (parent == NULL)
2266 return false;
2267 const CTxOut& parentOut = parent->vout[txin.prevout.n];
2268 if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
2269 return false;
2270 }
2271 return true;
2272}
2273
0f5954c4
GA
2274std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
2275{
2276 std::vector<uint256> result;
2277
2278 LOCK(cs_wallet);
2279 // Sort them in chronological order
2280 multimap<unsigned int, CWalletTx*> mapSorted;
2281 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
2282 {
2283 CWalletTx& wtx = item.second;
2284 // Don't rebroadcast if newer than nTime:
2285 if (wtx.nTimeReceived > nTime)
2286 continue;
2287 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
2288 }
2289 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
2290 {
2291 CWalletTx& wtx = *item.second;
2292 if (wtx.RelayWalletTransaction())
805344dc 2293 result.push_back(wtx.GetHash());
0f5954c4
GA
2294 }
2295 return result;
2296}
2297
2298void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
e8ef3da7
WL
2299{
2300 // Do this infrequently and randomly to avoid giving away
2301 // that these are our transactions.
6f252627 2302 if (GetTime() < nNextResend || !fBroadcastTransactions)
e8ef3da7 2303 return;
203d1ae6
LD
2304 bool fFirst = (nNextResend == 0);
2305 nNextResend = GetTime() + GetRand(30 * 60);
e8ef3da7
WL
2306 if (fFirst)
2307 return;
2308
2309 // Only do it if there's been a new block since last time
0f5954c4 2310 if (nBestBlockTime < nLastResend)
e8ef3da7 2311 return;
203d1ae6 2312 nLastResend = GetTime();
e8ef3da7 2313
0f5954c4
GA
2314 // Rebroadcast unconfirmed txes older than 5 minutes before the last
2315 // block was found:
2316 std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
2317 if (!relayed.empty())
2318 LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
e8ef3da7
WL
2319}
2320
5b40d886 2321/** @} */ // end of mapWallet
e8ef3da7
WL
2322
2323
2324
2325
5b40d886
MF
2326/** @defgroup Actions
2327 *
2328 * @{
2329 */
e8ef3da7
WL
2330
2331
a372168e 2332CAmount CWallet::GetBalance() const
e8ef3da7 2333{
a372168e 2334 CAmount nTotal = 0;
e8ef3da7 2335 {
55a1db4f 2336 LOCK2(cs_main, cs_wallet);
e8ef3da7
WL
2337 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2338 {
2339 const CWalletTx* pcoin = &(*it).second;
0542619d 2340 if (pcoin->IsTrusted())
8fdb7e10 2341 nTotal += pcoin->GetAvailableCredit();
e8ef3da7
WL
2342 }
2343 }
2344
e8ef3da7
WL
2345 return nTotal;
2346}
2347
a372168e 2348CAmount CWallet::GetUnconfirmedBalance() const
df5ccbd2 2349{
a372168e 2350 CAmount nTotal = 0;
df5ccbd2 2351 {
55a1db4f 2352 LOCK2(cs_main, cs_wallet);
df5ccbd2
WL
2353 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2354 {
2355 const CWalletTx* pcoin = &(*it).second;
75a4d512 2356 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
8fdb7e10 2357 nTotal += pcoin->GetAvailableCredit();
2358 }
2359 }
2360 return nTotal;
2361}
2362
a372168e 2363CAmount CWallet::GetImmatureBalance() const
8fdb7e10 2364{
a372168e 2365 CAmount nTotal = 0;
8fdb7e10 2366 {
55a1db4f 2367 LOCK2(cs_main, cs_wallet);
8fdb7e10 2368 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2369 {
966a0e8c
PK
2370 const CWalletTx* pcoin = &(*it).second;
2371 nTotal += pcoin->GetImmatureCredit();
df5ccbd2
WL
2372 }
2373 }
2374 return nTotal;
2375}
e8ef3da7 2376
a372168e 2377CAmount CWallet::GetWatchOnlyBalance() const
ffd40da3 2378{
a372168e 2379 CAmount nTotal = 0;
ffd40da3 2380 {
39cc4922 2381 LOCK2(cs_main, cs_wallet);
ffd40da3
J
2382 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2383 {
2384 const CWalletTx* pcoin = &(*it).second;
2385 if (pcoin->IsTrusted())
2386 nTotal += pcoin->GetAvailableWatchOnlyCredit();
2387 }
2388 }
870da77d 2389
ffd40da3
J
2390 return nTotal;
2391}
2392
a372168e 2393CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
ffd40da3 2394{
a372168e 2395 CAmount nTotal = 0;
ffd40da3 2396 {
39cc4922 2397 LOCK2(cs_main, cs_wallet);
ffd40da3
J
2398 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2399 {
2400 const CWalletTx* pcoin = &(*it).second;
75a4d512 2401 if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
ffd40da3
J
2402 nTotal += pcoin->GetAvailableWatchOnlyCredit();
2403 }
2404 }
2405 return nTotal;
2406}
2407
a372168e 2408CAmount CWallet::GetImmatureWatchOnlyBalance() const
ffd40da3 2409{
a372168e 2410 CAmount nTotal = 0;
ffd40da3 2411 {
39cc4922 2412 LOCK2(cs_main, cs_wallet);
ffd40da3
J
2413 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2414 {
2415 const CWalletTx* pcoin = &(*it).second;
2416 nTotal += pcoin->GetImmatureWatchOnlyCredit();
2417 }
2418 }
2419 return nTotal;
2420}
2421
5b40d886
MF
2422/**
2423 * populate vCoins with vector of available COutputs.
2424 */
2b1cda3b 2425void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue, bool fIncludeCoinBase) const
9b0369c7
CM
2426{
2427 vCoins.clear();
2428
2429 {
ea3acaf3 2430 LOCK2(cs_main, cs_wallet);
9b0369c7
CM
2431 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2432 {
93a18a36 2433 const uint256& wtxid = it->first;
9b0369c7
CM
2434 const CWalletTx* pcoin = &(*it).second;
2435
75a4d512 2436 if (!CheckFinalTx(*pcoin))
a2709fad
GA
2437 continue;
2438
0542619d 2439 if (fOnlyConfirmed && !pcoin->IsTrusted())
9b0369c7
CM
2440 continue;
2441
2b1cda3b
S
2442 if (pcoin->IsCoinBase() && !fIncludeCoinBase)
2443 continue;
2444
9b0369c7
CM
2445 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
2446 continue;
2447
2b72d46f
GA
2448 int nDepth = pcoin->GetDepthInMainChain();
2449 if (nDepth < 0)
2450 continue;
2451
fdbb537d 2452 for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
c8988460 2453 isminetype mine = IsMine(pcoin->vout[i]);
a3e192a3 2454 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
219953ce 2455 !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
aa30f655 2456 (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i)))
8d657a65 2457 vCoins.push_back(COutput(pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
fdbb537d 2458 }
9b0369c7
CM
2459 }
2460 }
2461}
2462
a372168e
MF
2463static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
2464 vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
831f59ce
CM
2465{
2466 vector<char> vfIncluded;
2467
2468 vfBest.assign(vValue.size(), true);
2469 nBest = nTotalLower;
2470
907a2aa4
GM
2471 seed_insecure_rand();
2472
831f59ce
CM
2473 for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
2474 {
2475 vfIncluded.assign(vValue.size(), false);
a372168e 2476 CAmount nTotal = 0;
831f59ce
CM
2477 bool fReachedTarget = false;
2478 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
2479 {
2480 for (unsigned int i = 0; i < vValue.size(); i++)
2481 {
907a2aa4
GM
2482 //The solver here uses a randomized algorithm,
2483 //the randomness serves no real security purpose but is just
2484 //needed to prevent degenerate behavior and it is important
5b40d886 2485 //that the rng is fast. We do not use a constant random sequence,
907a2aa4
GM
2486 //because there may be some privacy improvement by making
2487 //the selection random.
2488 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
831f59ce
CM
2489 {
2490 nTotal += vValue[i].first;
2491 vfIncluded[i] = true;
2492 if (nTotal >= nTargetValue)
2493 {
2494 fReachedTarget = true;
2495 if (nTotal < nBest)
2496 {
2497 nBest = nTotal;
2498 vfBest = vfIncluded;
2499 }
2500 nTotal -= vValue[i].first;
2501 vfIncluded[i] = false;
2502 }
2503 }
2504 }
2505 }
2506 }
2507}
2508
a372168e
MF
2509bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
2510 set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
e8ef3da7
WL
2511{
2512 setCoinsRet.clear();
2513 nValueRet = 0;
2514
2515 // List of values less than target
a372168e
MF
2516 pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
2517 coinLowestLarger.first = std::numeric_limits<CAmount>::max();
e8ef3da7 2518 coinLowestLarger.second.first = NULL;
a372168e
MF
2519 vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
2520 CAmount nTotalLower = 0;
e8ef3da7 2521
e333ab56
CM
2522 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
2523
c8988460 2524 BOOST_FOREACH(const COutput &output, vCoins)
e8ef3da7 2525 {
c8988460
PW
2526 if (!output.fSpendable)
2527 continue;
2528
9b0369c7 2529 const CWalletTx *pcoin = output.tx;
e8ef3da7 2530
a3e192a3 2531 if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
9b0369c7 2532 continue;
e8ef3da7 2533
9b0369c7 2534 int i = output.i;
a372168e 2535 CAmount n = pcoin->vout[i].nValue;
e8ef3da7 2536
a372168e 2537 pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
e8ef3da7 2538
9b0369c7
CM
2539 if (n == nTargetValue)
2540 {
2541 setCoinsRet.insert(coin.second);
2542 nValueRet += coin.first;
2543 return true;
2544 }
2545 else if (n < nTargetValue + CENT)
2546 {
2547 vValue.push_back(coin);
2548 nTotalLower += n;
2549 }
2550 else if (n < coinLowestLarger.first)
2551 {
2552 coinLowestLarger = coin;
e8ef3da7
WL
2553 }
2554 }
2555
831f59ce 2556 if (nTotalLower == nTargetValue)
e8ef3da7 2557 {
c376ac35 2558 for (unsigned int i = 0; i < vValue.size(); ++i)
e8ef3da7
WL
2559 {
2560 setCoinsRet.insert(vValue[i].second);
2561 nValueRet += vValue[i].first;
2562 }
2563 return true;
2564 }
2565
831f59ce 2566 if (nTotalLower < nTargetValue)
e8ef3da7
WL
2567 {
2568 if (coinLowestLarger.second.first == NULL)
2569 return false;
2570 setCoinsRet.insert(coinLowestLarger.second);
2571 nValueRet += coinLowestLarger.first;
2572 return true;
2573 }
2574
e8ef3da7 2575 // Solve subset sum by stochastic approximation
d650f96d 2576 sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
831f59ce 2577 vector<char> vfBest;
a372168e 2578 CAmount nBest;
e8ef3da7 2579
831f59ce
CM
2580 ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
2581 if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
2582 ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
e8ef3da7 2583
831f59ce
CM
2584 // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
2585 // or the next bigger coin is closer), return the bigger coin
2586 if (coinLowestLarger.second.first &&
2587 ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
e8ef3da7
WL
2588 {
2589 setCoinsRet.insert(coinLowestLarger.second);
2590 nValueRet += coinLowestLarger.first;
2591 }
2592 else {
c376ac35 2593 for (unsigned int i = 0; i < vValue.size(); i++)
e8ef3da7
WL
2594 if (vfBest[i])
2595 {
2596 setCoinsRet.insert(vValue[i].second);
2597 nValueRet += vValue[i].first;
2598 }
2599
faaeae1e 2600 LogPrint("selectcoins", "SelectCoins() best subset: ");
c376ac35 2601 for (unsigned int i = 0; i < vValue.size(); i++)
e8ef3da7 2602 if (vfBest[i])
7d9d134b
WL
2603 LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first));
2604 LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
e8ef3da7
WL
2605 }
2606
2607 return true;
2608}
2609
2b1cda3b 2610bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, bool& fOnlyCoinbaseCoinsRet, bool& fNeedCoinbaseCoinsRet, const CCoinControl* coinControl) const
e8ef3da7 2611{
2b1cda3b
S
2612 // Output parameter fOnlyCoinbaseCoinsRet is set to true when the only available coins are coinbase utxos.
2613 vector<COutput> vCoinsNoCoinbase, vCoinsWithCoinbase;
2614 AvailableCoins(vCoinsNoCoinbase, true, coinControl, false, false);
2615 AvailableCoins(vCoinsWithCoinbase, true, coinControl, false, true);
2616 fOnlyCoinbaseCoinsRet = vCoinsNoCoinbase.size() == 0 && vCoinsWithCoinbase.size() > 0;
2617
2618 // If coinbase utxos can only be sent to zaddrs, exclude any coinbase utxos from coin selection.
2619 bool fProtectCoinbase = Params().GetConsensus().fCoinbaseMustBeProtected;
2620 vector<COutput> vCoins = (fProtectCoinbase) ? vCoinsNoCoinbase : vCoinsWithCoinbase;
2621
2622 // Output parameter fNeedCoinbaseCoinsRet is set to true if coinbase utxos need to be spent to meet target amount
2623 if (fProtectCoinbase && vCoinsWithCoinbase.size() > vCoinsNoCoinbase.size()) {
2624 CAmount value = 0;
2625 for (const COutput& out : vCoinsNoCoinbase) {
2626 if (!out.fSpendable) {
2627 continue;
2628 }
2629 value += out.tx->vout[out.i].nValue;
2630 }
2631 if (value <= nTargetValue) {
2632 CAmount valueWithCoinbase = 0;
2633 for (const COutput& out : vCoinsWithCoinbase) {
2634 if (!out.fSpendable) {
2635 continue;
2636 }
2637 valueWithCoinbase += out.tx->vout[out.i].nValue;
2638 }
2639 fNeedCoinbaseCoinsRet = (valueWithCoinbase >= nTargetValue);
2640 }
2641 }
6a86c24d
CL
2642
2643 // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
aa30f655 2644 if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
6a86c24d
CL
2645 {
2646 BOOST_FOREACH(const COutput& out, vCoins)
2647 {
aa30f655
MC
2648 if (!out.fSpendable)
2649 continue;
6a86c24d
CL
2650 nValueRet += out.tx->vout[out.i].nValue;
2651 setCoinsRet.insert(make_pair(out.tx, out.i));
2652 }
2653 return (nValueRet >= nTargetValue);
2654 }
9b0369c7 2655
aa30f655
MC
2656 // calculate value from preset inputs and store them
2657 set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
2658 CAmount nValueFromPresetInputs = 0;
2659
2660 std::vector<COutPoint> vPresetInputs;
2661 if (coinControl)
2662 coinControl->ListSelected(vPresetInputs);
2663 BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
2664 {
2665 map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
2666 if (it != mapWallet.end())
2667 {
2668 const CWalletTx* pcoin = &it->second;
2669 // Clearly invalid input, fail
2670 if (pcoin->vout.size() <= outpoint.n)
2671 return false;
2672 nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
2673 setPresetCoins.insert(make_pair(pcoin, outpoint.n));
2674 } else
2675 return false; // TODO: Allow non-wallet inputs
2676 }
2677
2678 // remove preset inputs from vCoins
2679 for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
2680 {
2681 if (setPresetCoins.count(make_pair(it->tx, it->i)))
2682 it = vCoins.erase(it);
2683 else
2684 ++it;
2685 }
2686
2687 bool res = nTargetValue <= nValueFromPresetInputs ||
2688 SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, vCoins, setCoinsRet, nValueRet) ||
2689 SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, vCoins, setCoinsRet, nValueRet) ||
2690 (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet));
2691
2692 // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2693 setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
2694
2695 // add preset inputs to the total value selected
2696 nValueRet += nValueFromPresetInputs;
2697
2698 return res;
2699}
2700
2701bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason)
2702{
2703 vector<CRecipient> vecSend;
2704
2705 // Turn the txout set into a CRecipient vector
2706 BOOST_FOREACH(const CTxOut& txOut, tx.vout)
2707 {
2708 CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
2709 vecSend.push_back(recipient);
2710 }
2711
2712 CCoinControl coinControl;
2713 coinControl.fAllowOtherInputs = true;
2714 BOOST_FOREACH(const CTxIn& txin, tx.vin)
2715 coinControl.Select(txin.prevout);
2716
2717 CReserveKey reservekey(this);
2718 CWalletTx wtx;
efb7662d 2719
aa30f655
MC
2720 if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
2721 return false;
2722
2723 if (nChangePosRet != -1)
2724 tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
2725
2726 // Add new txins (keeping original txin scriptSig/order)
2727 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
2728 {
2729 bool found = false;
2730 BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
2731 {
2732 if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
2733 {
2734 found = true;
2735 break;
2736 }
2737 }
2738 if (!found)
2739 tx.vin.push_back(txin);
2740 }
2741
2742 return true;
e8ef3da7
WL
2743}
2744
aa30f655
MC
2745bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
2746 int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
e8ef3da7 2747{
a372168e 2748 CAmount nValue = 0;
292623ad
CL
2749 unsigned int nSubtractFeeFromAmount = 0;
2750 BOOST_FOREACH (const CRecipient& recipient, vecSend)
e8ef3da7 2751 {
292623ad 2752 if (nValue < 0 || recipient.nAmount < 0)
1f00f4e9
GA
2753 {
2754 strFailReason = _("Transaction amounts must be positive");
e8ef3da7 2755 return false;
1f00f4e9 2756 }
292623ad
CL
2757 nValue += recipient.nAmount;
2758
2759 if (recipient.fSubtractFeeFromAmount)
2760 nSubtractFeeFromAmount++;
e8ef3da7
WL
2761 }
2762 if (vecSend.empty() || nValue < 0)
1f00f4e9
GA
2763 {
2764 strFailReason = _("Transaction amounts must be positive");
e8ef3da7 2765 return false;
1f00f4e9 2766 }
e8ef3da7 2767
b33d1f5e 2768 wtxNew.fTimeReceivedIsTxTime = true;
4c6e2295 2769 wtxNew.BindWallet(this);
9bb37bf0 2770 int nextBlockHeight = chainActive.Height() + 1;
072099d7 2771 CMutableTransaction txNew = CreateNewContextualCMutableTransaction(
9bb37bf0 2772 Params().GetConsensus(), nextBlockHeight);
e8ef3da7 2773
9bb37bf0 2774 // Activates after Overwinter network upgrade
9bb37bf0 2775 if (NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
fa70084c 2776 if (txNew.nExpiryHeight >= TX_EXPIRY_HEIGHT_THRESHOLD){
9bb37bf0 2777 strFailReason = _("nExpiryHeight must be less than TX_EXPIRY_HEIGHT_THRESHOLD.");
7b92f27e 2778 return false;
9bb37bf0
JG
2779 }
2780 }
15ec5525 2781
25fee350 2782 unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING;
15ec5525
JG
2783 if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
2784 max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
2785 }
efb7662d 2786
ba7fcc8d
PT
2787 // Discourage fee sniping.
2788 //
2789 // However because of a off-by-one-error in previous versions we need to
2790 // neuter it by setting nLockTime to at least one less than nBestHeight.
2791 // Secondly currently propagation of transactions created for block heights
2792 // corresponding to blocks that were just mined may be iffy - transactions
2793 // aren't re-accepted into the mempool - we additionally neuter the code by
2794 // going ten blocks back. Doesn't yet do anything for sniping, but does act
2795 // to shake out wallet bugs like not showing nLockTime'd transactions at
2796 // all.
2797 txNew.nLockTime = std::max(0, chainActive.Height() - 10);
2798
2799 // Secondly occasionally randomly pick a nLockTime even further back, so
2800 // that transactions that are delayed after signing for whatever reason,
2801 // e.g. high-latency mix networks and some CoinJoin implementations, have
2802 // better privacy.
2803 if (GetRandInt(10) == 0)
2804 txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
2805
2806 assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
2807 assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
2808
e8ef3da7 2809 {
f8dcd5ca 2810 LOCK2(cs_main, cs_wallet);
e8ef3da7 2811 {
c1c9d5b4 2812 nFeeRet = 0;
050d2e95 2813 while (true)
e8ef3da7 2814 {
4949004d
PW
2815 txNew.vin.clear();
2816 txNew.vout.clear();
e8ef3da7 2817 wtxNew.fFromMe = true;
292623ad
CL
2818 nChangePosRet = -1;
2819 bool fFirst = true;
e8ef3da7 2820
292623ad
CL
2821 CAmount nTotalValue = nValue;
2822 if (nSubtractFeeFromAmount == 0)
2823 nTotalValue += nFeeRet;
e8ef3da7
WL
2824 double dPriority = 0;
2825 // vouts to the payees
292623ad 2826 BOOST_FOREACH (const CRecipient& recipient, vecSend)
8de9bb53 2827 {
292623ad
CL
2828 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
2829
2830 if (recipient.fSubtractFeeFromAmount)
2831 {
2832 txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
2833
2834 if (fFirst) // first receiver pays the remainder not divisible by output count
2835 {
2836 fFirst = false;
2837 txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
2838 }
2839 }
2840
13fc83c7 2841 if (txout.IsDust(::minRelayTxFee))
1f00f4e9 2842 {
292623ad
CL
2843 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
2844 {
2845 if (txout.nValue < 0)
2846 strFailReason = _("The transaction amount is too small to pay the fee");
2847 else
2848 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
2849 }
2850 else
2851 strFailReason = _("Transaction amount too small");
8de9bb53 2852 return false;
1f00f4e9 2853 }
4949004d 2854 txNew.vout.push_back(txout);
8de9bb53 2855 }
e8ef3da7
WL
2856
2857 // Choose coins to use
2858 set<pair<const CWalletTx*,unsigned int> > setCoins;
a372168e 2859 CAmount nValueIn = 0;
2b1cda3b
S
2860 bool fOnlyCoinbaseCoins = false;
2861 bool fNeedCoinbaseCoins = false;
2862 if (!SelectCoins(nTotalValue, setCoins, nValueIn, fOnlyCoinbaseCoins, fNeedCoinbaseCoins, coinControl))
1f00f4e9 2863 {
2b1cda3b
S
2864 if (fOnlyCoinbaseCoins && Params().GetConsensus().fCoinbaseMustBeProtected) {
2865 strFailReason = _("Coinbase funds can only be sent to a zaddr");
2866 } else if (fNeedCoinbaseCoins) {
2867 strFailReason = _("Insufficient funds, coinbase funds can only be spent after they have been sent to a zaddr");
2868 } else {
2869 strFailReason = _("Insufficient funds");
2870 }
e8ef3da7 2871 return false;
1f00f4e9 2872 }
e8ef3da7
WL
2873 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
2874 {
a372168e 2875 CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
2d9b0b7f 2876 //The coin age after the next block (depth+1) is used instead of the current,
d7836552
GM
2877 //reflecting an assumption the user would accept a bit more delay for
2878 //a chance at a free transaction.
2d9b0b7f
AM
2879 //But mempool inputs might still be in the mempool, so their age stays 0
2880 int age = pcoin.first->GetDepthInMainChain();
2881 if (age != 0)
2882 age += 1;
2883 dPriority += (double)nCredit * age;
e8ef3da7
WL
2884 }
2885
292623ad
CL
2886 CAmount nChange = nValueIn - nValue;
2887 if (nSubtractFeeFromAmount == 0)
2888 nChange -= nFeeRet;
a7dd11c6
PW
2889
2890 if (nChange > 0)
e8ef3da7 2891 {
bf798734
GA
2892 // Fill a vout to ourself
2893 // TODO: pass in scriptChange instead of reservekey so
2894 // change transaction isn't always pay-to-bitcoin-address
e8ef3da7 2895 CScript scriptChange;
6a86c24d
CL
2896
2897 // coin control: send change to custom address
2898 if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
0be990ba 2899 scriptChange = GetScriptForDestination(coinControl->destChange);
6a86c24d
CL
2900
2901 // no coin control: send change to newly generated address
2902 else
2903 {
2904 // Note: We use a new key here to keep it from being obvious which side is the change.
2905 // The drawback is that by not reusing a previous key, the change may be lost if a
2906 // backup is restored, if the backup doesn't have the new private key for the change.
2907 // If we reused the old key, it would be possible to add code to look for and
2908 // rediscover unknown transactions that were written with keys of ours to recover
2909 // post-backup change.
2910
2911 // Reserve a new key pair from key pool
2912 CPubKey vchPubKey;
9b59e3bd
GM
2913 bool ret;
2914 ret = reservekey.GetReservedKey(vchPubKey);
2915 assert(ret); // should never fail, as we just unlocked
6a86c24d 2916
0be990ba 2917 scriptChange = GetScriptForDestination(vchPubKey.GetID());
6a86c24d 2918 }
e8ef3da7 2919
8de9bb53
GA
2920 CTxOut newTxOut(nChange, scriptChange);
2921
292623ad
CL
2922 // We do not move dust-change to fees, because the sender would end up paying more than requested.
2923 // This would be against the purpose of the all-inclusive feature.
2924 // So instead we raise the change and deduct from the recipient.
2925 if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
2926 {
2927 CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
2928 newTxOut.nValue += nDust; // raise change until no more dust
2929 for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
2930 {
2931 if (vecSend[i].fSubtractFeeFromAmount)
2932 {
2933 txNew.vout[i].nValue -= nDust;
2934 if (txNew.vout[i].IsDust(::minRelayTxFee))
2935 {
2936 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
2937 return false;
2938 }
2939 break;
2940 }
2941 }
2942 }
2943
8de9bb53
GA
2944 // Never create dust outputs; if we would, just
2945 // add the dust to the fee.
13fc83c7 2946 if (newTxOut.IsDust(::minRelayTxFee))
8de9bb53
GA
2947 {
2948 nFeeRet += nChange;
2949 reservekey.ReturnKey();
2950 }
2951 else
2952 {
2953 // Insert change txn at random position:
292623ad
CL
2954 nChangePosRet = GetRandInt(txNew.vout.size()+1);
2955 vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
4949004d 2956 txNew.vout.insert(position, newTxOut);
8de9bb53 2957 }
e8ef3da7
WL
2958 }
2959 else
2960 reservekey.ReturnKey();
2961
2962 // Fill vin
ba7fcc8d
PT
2963 //
2964 // Note how the sequence number is set to max()-1 so that the
2965 // nLockTime set above actually works.
e8ef3da7 2966 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
805344dc 2967 txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
ba7fcc8d 2968 std::numeric_limits<unsigned int>::max()-1));
e8ef3da7 2969
9e84b5aa
S
2970 // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects
2971 size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0);
31afbcc5
JG
2972 {
2973 LOCK(cs_main);
2974 if (NetworkUpgradeActive(chainActive.Height() + 1, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER)) {
2975 limit = 0;
2976 }
2977 }
9e84b5aa
S
2978 if (limit > 0) {
2979 size_t n = txNew.vin.size();
2980 if (n > limit) {
2981 strFailReason = _(strprintf("Too many transparent inputs %zu > limit %zu", n, limit).c_str());
2982 return false;
2983 }
2984 }
2985
be126699
JG
2986 // Grab the current consensus branch ID
2987 auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
2988
e8ef3da7
WL
2989 // Sign
2990 int nIn = 0;
aa30f655 2991 CTransaction txNewConst(txNew);
e8ef3da7 2992 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
aa30f655
MC
2993 {
2994 bool signSuccess;
2995 const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
157a5d0d 2996 SignatureData sigdata;
aa30f655 2997 if (sign)
be126699 2998 signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
aa30f655 2999 else
be126699 3000 signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
aa30f655
MC
3001
3002 if (!signSuccess)
1f00f4e9
GA
3003 {
3004 strFailReason = _("Signing transaction failed");
e8ef3da7 3005 return false;
157a5d0d
PW
3006 } else {
3007 UpdateTransaction(txNew, nIn, sigdata);
1f00f4e9 3008 }
157a5d0d 3009
aa30f655
MC
3010 nIn++;
3011 }
3012
3013 unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
3014
3015 // Remove scriptSigs if we used dummy signatures for fee calculation
3016 if (!sign) {
3017 BOOST_FOREACH (CTxIn& vin, txNew.vin)
3018 vin.scriptSig = CScript();
3019 }
e8ef3da7 3020
4949004d
PW
3021 // Embed the constructed transaction data in wtxNew.
3022 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
3023
e8ef3da7 3024 // Limit size
15ec5525 3025 if (nBytes >= max_tx_size)
1f00f4e9
GA
3026 {
3027 strFailReason = _("Transaction too large");
e8ef3da7 3028 return false;
1f00f4e9 3029 }
aa30f655 3030
4d707d51 3031 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
e8ef3da7 3032
aa279d61
GM
3033 // Can we complete this as a free transaction?
3034 if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
3035 {
3036 // Not enough fee: enough priority?
3037 double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
3038 // Not enough mempool history to estimate: use hard-coded AllowFree.
3039 if (dPriorityNeeded <= 0 && AllowFree(dPriority))
3040 break;
3041
3042 // Small enough, and priority high enough, to send for free
3043 if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
3044 break;
3045 }
b33d1f5e 3046
aa279d61 3047 CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
b33d1f5e 3048
aa279d61
GM
3049 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
3050 // because we must be at the maximum allowed fee.
3051 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
e8ef3da7 3052 {
aa279d61
GM
3053 strFailReason = _("Transaction too large for fee policy");
3054 return false;
e8ef3da7
WL
3055 }
3056
aa279d61
GM
3057 if (nFeeRet >= nFeeNeeded)
3058 break; // Done, enough fee included.
b33d1f5e
GA
3059
3060 // Include more fee and try again.
3061 nFeeRet = nFeeNeeded;
3062 continue;
e8ef3da7
WL
3063 }
3064 }
3065 }
e8ef3da7 3066
292623ad 3067 return true;
e8ef3da7
WL
3068}
3069
5b40d886
MF
3070/**
3071 * Call after CreateTransaction unless you want to abort
3072 */
e8ef3da7
WL
3073bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
3074{
e8ef3da7 3075 {
f8dcd5ca 3076 LOCK2(cs_main, cs_wallet);
7d9d134b 3077 LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
e8ef3da7
WL
3078 {
3079 // This is only to keep the database open to defeat the auto-flush for the
3080 // duration of this scope. This is the only place where this optimization
3081 // maybe makes sense; please don't do it anywhere else.
44bc988e 3082 CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
e8ef3da7
WL
3083
3084 // Take key pair from key pool so it won't be used again
3085 reservekey.KeepKey();
3086
3087 // Add tx to wallet, because if it has change it's also ours,
3088 // otherwise just for transaction history.
44bc988e 3089 AddToWallet(wtxNew, false, pwalletdb);
e8ef3da7 3090
93a18a36 3091 // Notify that old coins are spent
e8ef3da7
WL
3092 set<CWalletTx*> setCoins;
3093 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
3094 {
3095 CWalletTx &coin = mapWallet[txin.prevout.hash];
4c6e2295 3096 coin.BindWallet(this);
805344dc 3097 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
e8ef3da7
WL
3098 }
3099
3100 if (fFileBacked)
3101 delete pwalletdb;
3102 }
3103
3104 // Track how many getdata requests our transaction gets
805344dc 3105 mapRequestCount[wtxNew.GetHash()] = 0;
e8ef3da7 3106
6f252627 3107 if (fBroadcastTransactions)
e8ef3da7 3108 {
6f252627
WL
3109 // Broadcast
3110 if (!wtxNew.AcceptToMemoryPool(false))
3111 {
3112 // This must not fail. The transaction has already been signed and recorded.
7ff9d122 3113 LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
6f252627
WL
3114 return false;
3115 }
3116 wtxNew.RelayWalletTransaction();
e8ef3da7 3117 }
e8ef3da7 3118 }
e8ef3da7
WL
3119 return true;
3120}
3121
a372168e 3122CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
b33d1f5e
GA
3123{
3124 // payTxFee is user-set "I want to pay this much"
a372168e 3125 CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
c1c9d5b4
CL
3126 // user selected total at least (default=true)
3127 if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
3128 nFeeNeeded = payTxFee.GetFeePerK();
b33d1f5e
GA
3129 // User didn't set: use -txconfirmtarget to estimate...
3130 if (nFeeNeeded == 0)
3131 nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
3132 // ... unless we don't have enough mempool data, in which case fall
3133 // back to a hard-coded fee
3134 if (nFeeNeeded == 0)
13fc83c7 3135 nFeeNeeded = minTxFee.GetFee(nTxBytes);
aa279d61
GM
3136 // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
3137 if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
3138 nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
3139 // But always obey the maximum
3140 if (nFeeNeeded > maxTxFee)
3141 nFeeNeeded = maxTxFee;
b33d1f5e
GA
3142 return nFeeNeeded;
3143}
3144
e8ef3da7
WL
3145
3146
3147
eed1785f 3148DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
e8ef3da7
WL
3149{
3150 if (!fFileBacked)
4f76be1d 3151 return DB_LOAD_OK;
e8ef3da7 3152 fFirstRunRet = false;
eed1785f 3153 DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
d764d916 3154 if (nLoadWalletRet == DB_NEED_REWRITE)
9e9869d0 3155 {
d764d916
GA
3156 if (CDB::Rewrite(strWalletFile, "\x04pool"))
3157 {
012ca1c9 3158 LOCK(cs_wallet);
d764d916
GA
3159 setKeyPool.clear();
3160 // Note: can't top-up keypool here, because wallet is locked.
3161 // User will be prompted to unlock wallet the next operation
c6de7c35 3162 // that requires a new key.
d764d916 3163 }
9e9869d0
PW
3164 }
3165
7ec55267
MC
3166 if (nLoadWalletRet != DB_LOAD_OK)
3167 return nLoadWalletRet;
fd61d6f5 3168 fFirstRunRet = !vchDefaultKey.IsValid();
e8ef3da7 3169
39278369
CL
3170 uiInterface.LoadWallet(this);
3171
116df55e 3172 return DB_LOAD_OK;
e8ef3da7
WL
3173}
3174
ae3d0aba 3175
77cbd462 3176DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
518f3bda
JG
3177{
3178 if (!fFileBacked)
3179 return DB_LOAD_OK;
77cbd462 3180 DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
518f3bda
JG
3181 if (nZapWalletTxRet == DB_NEED_REWRITE)
3182 {
3183 if (CDB::Rewrite(strWalletFile, "\x04pool"))
3184 {
3185 LOCK(cs_wallet);
3186 setKeyPool.clear();
3187 // Note: can't top-up keypool here, because wallet is locked.
3188 // User will be prompted to unlock wallet the next operation
5b40d886 3189 // that requires a new key.
518f3bda
JG
3190 }
3191 }
3192
3193 if (nZapWalletTxRet != DB_LOAD_OK)
3194 return nZapWalletTxRet;
3195
3196 return DB_LOAD_OK;
3197}
3198
3199
a41d5fe0 3200bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
ae3d0aba 3201{
ca4cf5cf
GA
3202 bool fUpdated = false;
3203 {
3204 LOCK(cs_wallet); // mapAddressBook
3205 std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
3206 fUpdated = mi != mapAddressBook.end();
3207 mapAddressBook[address].name = strName;
3208 if (!strPurpose.empty()) /* update purpose only if requested */
3209 mapAddressBook[address].purpose = strPurpose;
3210 }
8d657a65 3211 NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
ca4cf5cf 3212 strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
ae3d0aba
WL
3213 if (!fFileBacked)
3214 return false;
07444da1 3215 if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(EncodeDestination(address), strPurpose))
a41d5fe0 3216 return false;
07444da1 3217 return CWalletDB(strWalletFile).WriteName(EncodeDestination(address), strName);
ae3d0aba
WL
3218}
3219
a41d5fe0 3220bool CWallet::DelAddressBook(const CTxDestination& address)
ae3d0aba 3221{
b10e1470 3222 {
ca4cf5cf
GA
3223 LOCK(cs_wallet); // mapAddressBook
3224
3225 if(fFileBacked)
b10e1470 3226 {
ca4cf5cf 3227 // Delete destdata tuples associated with address
07444da1 3228 std::string strAddress = EncodeDestination(address);
ca4cf5cf
GA
3229 BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
3230 {
3231 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
3232 }
b10e1470 3233 }
ca4cf5cf 3234 mapAddressBook.erase(address);
b10e1470
WL
3235 }
3236
8d657a65 3237 NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
ca4cf5cf 3238
ae3d0aba
WL
3239 if (!fFileBacked)
3240 return false;
07444da1
PW
3241 CWalletDB(strWalletFile).ErasePurpose(EncodeDestination(address));
3242 return CWalletDB(strWalletFile).EraseName(EncodeDestination(address));
ae3d0aba
WL
3243}
3244
fd61d6f5 3245bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
ae3d0aba
WL
3246{
3247 if (fFileBacked)
3248 {
3249 if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
3250 return false;
3251 }
3252 vchDefaultKey = vchPubKey;
3253 return true;
3254}
3255
5b40d886
MF
3256/**
3257 * Mark old keypool keys as used,
efb7662d 3258 * and generate all new keys
5b40d886 3259 */
37971fcc
GA
3260bool CWallet::NewKeyPool()
3261{
37971fcc 3262 {
f8dcd5ca 3263 LOCK(cs_wallet);
37971fcc 3264 CWalletDB walletdb(strWalletFile);
51ed9ec9 3265 BOOST_FOREACH(int64_t nIndex, setKeyPool)
37971fcc
GA
3266 walletdb.ErasePool(nIndex);
3267 setKeyPool.clear();
3268
3269 if (IsLocked())
3270 return false;
3271
51ed9ec9 3272 int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
37971fcc
GA
3273 for (int i = 0; i < nKeys; i++)
3274 {
51ed9ec9 3275 int64_t nIndex = i+1;
37971fcc
GA
3276 walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
3277 setKeyPool.insert(nIndex);
3278 }
f48742c2 3279 LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
37971fcc
GA
3280 }
3281 return true;
3282}
3283
13dd2d09 3284bool CWallet::TopUpKeyPool(unsigned int kpSize)
e8ef3da7 3285{
e8ef3da7 3286 {
f8dcd5ca
PW
3287 LOCK(cs_wallet);
3288
4e87d341
MC
3289 if (IsLocked())
3290 return false;
3291
e8ef3da7
WL
3292 CWalletDB walletdb(strWalletFile);
3293
3294 // Top up key pool
13dd2d09
JG
3295 unsigned int nTargetSize;
3296 if (kpSize > 0)
3297 nTargetSize = kpSize;
3298 else
51ed9ec9 3299 nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
13dd2d09 3300
faf705a4 3301 while (setKeyPool.size() < (nTargetSize + 1))
e8ef3da7 3302 {
51ed9ec9 3303 int64_t nEnd = 1;
e8ef3da7
WL
3304 if (!setKeyPool.empty())
3305 nEnd = *(--setKeyPool.end()) + 1;
3306 if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
5262fde0 3307 throw runtime_error("TopUpKeyPool(): writing generated key failed");
e8ef3da7 3308 setKeyPool.insert(nEnd);
783b182c 3309 LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
e8ef3da7 3310 }
4e87d341
MC
3311 }
3312 return true;
3313}
3314
51ed9ec9 3315void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
4e87d341
MC
3316{
3317 nIndex = -1;
fd61d6f5 3318 keypool.vchPubKey = CPubKey();
4e87d341 3319 {
f8dcd5ca
PW
3320 LOCK(cs_wallet);
3321
4e87d341
MC
3322 if (!IsLocked())
3323 TopUpKeyPool();
e8ef3da7
WL
3324
3325 // Get the oldest key
4e87d341
MC
3326 if(setKeyPool.empty())
3327 return;
3328
3329 CWalletDB walletdb(strWalletFile);
3330
e8ef3da7
WL
3331 nIndex = *(setKeyPool.begin());
3332 setKeyPool.erase(setKeyPool.begin());
3333 if (!walletdb.ReadPool(nIndex, keypool))
5262fde0 3334 throw runtime_error("ReserveKeyFromKeyPool(): read failed");
fd61d6f5 3335 if (!HaveKey(keypool.vchPubKey.GetID()))
5262fde0 3336 throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
fd61d6f5 3337 assert(keypool.vchPubKey.IsValid());
f48742c2 3338 LogPrintf("keypool reserve %d\n", nIndex);
e8ef3da7
WL
3339 }
3340}
3341
51ed9ec9 3342void CWallet::KeepKey(int64_t nIndex)
e8ef3da7
WL
3343{
3344 // Remove from key pool
3345 if (fFileBacked)
3346 {
3347 CWalletDB walletdb(strWalletFile);
6cc4a62c 3348 walletdb.ErasePool(nIndex);
e8ef3da7 3349 }
f48742c2 3350 LogPrintf("keypool keep %d\n", nIndex);
e8ef3da7
WL
3351}
3352
51ed9ec9 3353void CWallet::ReturnKey(int64_t nIndex)
e8ef3da7
WL
3354{
3355 // Return to key pool
f8dcd5ca
PW
3356 {
3357 LOCK(cs_wallet);
e8ef3da7 3358 setKeyPool.insert(nIndex);
f8dcd5ca 3359 }
f48742c2 3360 LogPrintf("keypool return %d\n", nIndex);
e8ef3da7
WL
3361}
3362
71ac5052 3363bool CWallet::GetKeyFromPool(CPubKey& result)
e8ef3da7 3364{
51ed9ec9 3365 int64_t nIndex = 0;
e8ef3da7 3366 CKeyPool keypool;
7db3b75b 3367 {
f8dcd5ca 3368 LOCK(cs_wallet);
ed02c95d
GA
3369 ReserveKeyFromKeyPool(nIndex, keypool);
3370 if (nIndex == -1)
7db3b75b 3371 {
ed02c95d
GA
3372 if (IsLocked()) return false;
3373 result = GenerateNewKey();
7db3b75b
GA
3374 return true;
3375 }
ed02c95d
GA
3376 KeepKey(nIndex);
3377 result = keypool.vchPubKey;
7db3b75b 3378 }
7db3b75b 3379 return true;
e8ef3da7
WL
3380}
3381
51ed9ec9 3382int64_t CWallet::GetOldestKeyPoolTime()
e8ef3da7 3383{
51ed9ec9 3384 int64_t nIndex = 0;
e8ef3da7
WL
3385 CKeyPool keypool;
3386 ReserveKeyFromKeyPool(nIndex, keypool);
4e87d341
MC
3387 if (nIndex == -1)
3388 return GetTime();
e8ef3da7
WL
3389 ReturnKey(nIndex);
3390 return keypool.nTime;
3391}
3392
a372168e 3393std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
22dfd735 3394{
a372168e 3395 map<CTxDestination, CAmount> balances;
22dfd735 3396
3397 {
3398 LOCK(cs_wallet);
3399 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
3400 {
3401 CWalletTx *pcoin = &walletEntry.second;
3402
75a4d512 3403 if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted())
22dfd735 3404 continue;
3405
3406 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
3407 continue;
3408
3409 int nDepth = pcoin->GetDepthInMainChain();
a3e192a3 3410 if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
22dfd735 3411 continue;
3412
b1093efa 3413 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
22dfd735 3414 {
b1093efa 3415 CTxDestination addr;
22dfd735 3416 if (!IsMine(pcoin->vout[i]))
3417 continue;
b1093efa
GM
3418 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
3419 continue;
22dfd735 3420
a372168e 3421 CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
22dfd735 3422
22dfd735 3423 if (!balances.count(addr))
3424 balances[addr] = 0;
3425 balances[addr] += n;
3426 }
3427 }
3428 }
3429
3430 return balances;
3431}
3432
b1093efa 3433set< set<CTxDestination> > CWallet::GetAddressGroupings()
22dfd735 3434{
95691680 3435 AssertLockHeld(cs_wallet); // mapWallet
b1093efa
GM
3436 set< set<CTxDestination> > groupings;
3437 set<CTxDestination> grouping;
22dfd735 3438
3439 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
3440 {
3441 CWalletTx *pcoin = &walletEntry.second;
3442
a3fad211 3443 if (pcoin->vin.size() > 0)
22dfd735 3444 {
a3fad211 3445 bool any_mine = false;
22dfd735 3446 // group all input addresses with each other
3447 BOOST_FOREACH(CTxIn txin, pcoin->vin)
b1093efa
GM
3448 {
3449 CTxDestination address;
a3fad211
GM
3450 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
3451 continue;
b1093efa
GM
3452 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
3453 continue;
3454 grouping.insert(address);
a3fad211 3455 any_mine = true;
b1093efa 3456 }
22dfd735 3457
3458 // group change with input addresses
a3fad211
GM
3459 if (any_mine)
3460 {
3461 BOOST_FOREACH(CTxOut txout, pcoin->vout)
3462 if (IsChange(txout))
3463 {
3464 CTxDestination txoutAddr;
3465 if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
3466 continue;
3467 grouping.insert(txoutAddr);
3468 }
3469 }
3470 if (grouping.size() > 0)
3471 {
3472 groupings.insert(grouping);
3473 grouping.clear();
3474 }
22dfd735 3475 }
3476
3477 // group lone addrs by themselves
b1093efa 3478 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
22dfd735 3479 if (IsMine(pcoin->vout[i]))
3480 {
b1093efa
GM
3481 CTxDestination address;
3482 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
3483 continue;
3484 grouping.insert(address);
22dfd735 3485 groupings.insert(grouping);
3486 grouping.clear();
3487 }
3488 }
3489
b1093efa
GM
3490 set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
3491 map< CTxDestination, set<CTxDestination>* > setmap; // map addresses to the unique group containing it
3492 BOOST_FOREACH(set<CTxDestination> grouping, groupings)
22dfd735 3493 {
3494 // make a set of all the groups hit by this new group
b1093efa
GM
3495 set< set<CTxDestination>* > hits;
3496 map< CTxDestination, set<CTxDestination>* >::iterator it;
3497 BOOST_FOREACH(CTxDestination address, grouping)
22dfd735 3498 if ((it = setmap.find(address)) != setmap.end())
3499 hits.insert((*it).second);
3500
3501 // merge all hit groups into a new single group and delete old groups
b1093efa
GM
3502 set<CTxDestination>* merged = new set<CTxDestination>(grouping);
3503 BOOST_FOREACH(set<CTxDestination>* hit, hits)
22dfd735 3504 {
3505 merged->insert(hit->begin(), hit->end());
3506 uniqueGroupings.erase(hit);
3507 delete hit;
3508 }
3509 uniqueGroupings.insert(merged);
3510
3511 // update setmap
b1093efa 3512 BOOST_FOREACH(CTxDestination element, *merged)
22dfd735 3513 setmap[element] = merged;
3514 }
3515
b1093efa
GM
3516 set< set<CTxDestination> > ret;
3517 BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
22dfd735 3518 {
3519 ret.insert(*uniqueGrouping);
3520 delete uniqueGrouping;
3521 }
3522
3523 return ret;
3524}
3525
db954a65 3526std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
3624356e 3527{
43422a01 3528 LOCK(cs_wallet);
3624356e
GA
3529 set<CTxDestination> result;
3530 BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
3531 {
3532 const CTxDestination& address = item.first;
3533 const string& strName = item.second.name;
3534 if (strName == strAccount)
3535 result.insert(address);
3536 }
3537 return result;
3538}
3539
360cfe14 3540bool CReserveKey::GetReservedKey(CPubKey& pubkey)
e8ef3da7
WL
3541{
3542 if (nIndex == -1)
3543 {
3544 CKeyPool keypool;
3545 pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
0d7b28e5
MC
3546 if (nIndex != -1)
3547 vchPubKey = keypool.vchPubKey;
360cfe14 3548 else {
6c37f7fd 3549 return false;
cee69980 3550 }
e8ef3da7 3551 }
fd61d6f5 3552 assert(vchPubKey.IsValid());
360cfe14
PW
3553 pubkey = vchPubKey;
3554 return true;
e8ef3da7
WL
3555}
3556
3557void CReserveKey::KeepKey()
3558{
3559 if (nIndex != -1)
3560 pwallet->KeepKey(nIndex);
3561 nIndex = -1;
fd61d6f5 3562 vchPubKey = CPubKey();
e8ef3da7
WL
3563}
3564
3565void CReserveKey::ReturnKey()
3566{
3567 if (nIndex != -1)
3568 pwallet->ReturnKey(nIndex);
3569 nIndex = -1;
fd61d6f5 3570 vchPubKey = CPubKey();
e8ef3da7 3571}
ae3d0aba 3572
434e4273 3573void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
30ab2c9c
PW
3574{
3575 setAddress.clear();
3576
3577 CWalletDB walletdb(strWalletFile);
3578
f8dcd5ca 3579 LOCK2(cs_main, cs_wallet);
51ed9ec9 3580 BOOST_FOREACH(const int64_t& id, setKeyPool)
30ab2c9c
PW
3581 {
3582 CKeyPool keypool;
3583 if (!walletdb.ReadPool(id, keypool))
5262fde0 3584 throw runtime_error("GetAllReserveKeyHashes(): read failed");
fd61d6f5 3585 assert(keypool.vchPubKey.IsValid());
10254401
PW
3586 CKeyID keyID = keypool.vchPubKey.GetID();
3587 if (!HaveKey(keyID))
5262fde0 3588 throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
10254401 3589 setAddress.insert(keyID);
30ab2c9c
PW
3590 }
3591}
fe4a6550
WL
3592
3593void CWallet::UpdatedTransaction(const uint256 &hashTx)
3594{
3595 {
3596 LOCK(cs_wallet);
3597 // Only notify UI if this transaction is in this wallet
3598 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
3599 if (mi != mapWallet.end())
3600 NotifyTransactionChanged(this, hashTx, CT_UPDATED);
3601 }
3602}
fdbb537d
JG
3603
3604void CWallet::LockCoin(COutPoint& output)
3605{
95691680 3606 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3607 setLockedCoins.insert(output);
3608}
3609
3610void CWallet::UnlockCoin(COutPoint& output)
3611{
95691680 3612 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3613 setLockedCoins.erase(output);
3614}
3615
3616void CWallet::UnlockAllCoins()
3617{
95691680 3618 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3619 setLockedCoins.clear();
3620}
3621
3622bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
3623{
95691680 3624 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3625 COutPoint outpt(hash, n);
3626
3627 return (setLockedCoins.count(outpt) > 0);
3628}
3629
3630void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
3631{
95691680 3632 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
3633 for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
3634 it != setLockedCoins.end(); it++) {
3635 COutPoint outpt = (*it);
3636 vOutpts.push_back(outpt);
3637 }
3638}
3639
4e6400bc
BM
3640
3641// Note Locking Operations
3642
e935beb8 3643void CWallet::LockNote(const JSOutPoint& output)
4e6400bc
BM
3644{
3645 AssertLockHeld(cs_wallet); // setLockedNotes
3646 setLockedNotes.insert(output);
3647}
3648
e935beb8 3649void CWallet::UnlockNote(const JSOutPoint& output)
4e6400bc
BM
3650{
3651 AssertLockHeld(cs_wallet); // setLockedNotes
3652 setLockedNotes.erase(output);
3653}
3654
3655void CWallet::UnlockAllNotes()
3656{
3657 AssertLockHeld(cs_wallet); // setLockedNotes
3658 setLockedNotes.clear();
3659}
3660
e935beb8 3661bool CWallet::IsLockedNote(const JSOutPoint& outpt) const
4e6400bc
BM
3662{
3663 AssertLockHeld(cs_wallet); // setLockedNotes
4e6400bc
BM
3664
3665 return (setLockedNotes.count(outpt) > 0);
3666}
3667
3668std::vector<JSOutPoint> CWallet::ListLockedNotes()
3669{
3670 AssertLockHeld(cs_wallet); // setLockedNotes
3671 std::vector<JSOutPoint> vOutpts(setLockedNotes.begin(), setLockedNotes.end());
3672 return vOutpts;
3673}
3674
5b40d886 3675/** @} */ // end of Actions
8b59a3d3 3676
3677class CAffectedKeysVisitor : public boost::static_visitor<void> {
3678private:
3679 const CKeyStore &keystore;
3680 std::vector<CKeyID> &vKeys;
3681
3682public:
3683 CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
3684
3685 void Process(const CScript &script) {
3686 txnouttype type;
3687 std::vector<CTxDestination> vDest;
3688 int nRequired;
3689 if (ExtractDestinations(script, type, vDest, nRequired)) {
3690 BOOST_FOREACH(const CTxDestination &dest, vDest)
3691 boost::apply_visitor(*this, dest);
3692 }
3693 }
3694
3695 void operator()(const CKeyID &keyId) {
3696 if (keystore.HaveKey(keyId))
3697 vKeys.push_back(keyId);
3698 }
3699
3700 void operator()(const CScriptID &scriptId) {
3701 CScript script;
3702 if (keystore.GetCScript(scriptId, script))
3703 Process(script);
3704 }
3705
3706 void operator()(const CNoDestination &none) {}
3707};
3708
51ed9ec9 3709void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
95691680 3710 AssertLockHeld(cs_wallet); // mapKeyMetadata
434e4273
PW
3711 mapKeyBirth.clear();
3712
3713 // get birth times for keys with metadata
3714 for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
3715 if (it->second.nCreateTime)
3716 mapKeyBirth[it->first] = it->second.nCreateTime;
3717
3718 // map in which we'll infer heights of other keys
4c6d41b8 3719 CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
434e4273
PW
3720 std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
3721 std::set<CKeyID> setKeys;
3722 GetKeys(setKeys);
3723 BOOST_FOREACH(const CKeyID &keyid, setKeys) {
3724 if (mapKeyBirth.count(keyid) == 0)
3725 mapKeyFirstBlock[keyid] = pindexMax;
3726 }
3727 setKeys.clear();
3728
3729 // if there are no such keys, we're done
3730 if (mapKeyFirstBlock.empty())
3731 return;
3732
3733 // find first block that affects those keys, if there are any left
3734 std::vector<CKeyID> vAffected;
3735 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
3736 // iterate over all wallet transactions...
3737 const CWalletTx &wtx = (*it).second;
145d5be8 3738 BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
4c6d41b8 3739 if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
434e4273
PW
3740 // ... which are already in a block
3741 int nHeight = blit->second->nHeight;
3742 BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
3743 // iterate over all their outputs
8b59a3d3 3744 CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
434e4273
PW
3745 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
3746 // ... and all their affected keys
3747 std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
3748 if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
3749 rit->second = blit->second;
3750 }
3751 vAffected.clear();
3752 }
3753 }
3754 }
3755
3756 // Extract block timestamps for those keys
3757 for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
209377a7 3758 mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
434e4273 3759}
b10e1470
WL
3760
3761bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
3762{
8476d5d4
CL
3763 if (boost::get<CNoDestination>(&dest))
3764 return false;
3765
b10e1470
WL
3766 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
3767 if (!fFileBacked)
3768 return true;
07444da1 3769 return CWalletDB(strWalletFile).WriteDestData(EncodeDestination(dest), key, value);
b10e1470
WL
3770}
3771
3772bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
3773{
3774 if (!mapAddressBook[dest].destdata.erase(key))
3775 return false;
3776 if (!fFileBacked)
3777 return true;
07444da1 3778 return CWalletDB(strWalletFile).EraseDestData(EncodeDestination(dest), key);
b10e1470
WL
3779}
3780
3781bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
3782{
3783 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
3784 return true;
3785}
3786
3787bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
3788{
3789 std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
3790 if(i != mapAddressBook.end())
3791 {
3792 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
3793 if(j != i->second.destdata.end())
3794 {
3795 if(value)
3796 *value = j->second;
3797 return true;
3798 }
3799 }
3800 return false;
3801}
af8297c0
WL
3802
3803CKeyPool::CKeyPool()
3804{
3805 nTime = GetTime();
3806}
3807
3808CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
3809{
3810 nTime = GetTime();
3811 vchPubKey = vchPubKeyIn;
3812}
3813
3814CWalletKey::CWalletKey(int64_t nExpires)
3815{
3816 nTimeCreated = (nExpires ? GetTime() : 0);
3817 nTimeExpires = nExpires;
3818}
0101483f 3819
4b0deb3b 3820int CMerkleTx::SetMerkleBranch(const CBlock& block)
0101483f
WL
3821{
3822 AssertLockHeld(cs_main);
3823 CBlock blockTmp;
3824
4b0deb3b
DK
3825 // Update the tx's hashBlock
3826 hashBlock = block.GetHash();
0101483f 3827
4b0deb3b
DK
3828 // Locate the transaction
3829 for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++)
3830 if (block.vtx[nIndex] == *(CTransaction*)this)
3831 break;
3832 if (nIndex == (int)block.vtx.size())
3833 {
3834 vMerkleBranch.clear();
3835 nIndex = -1;
5262fde0 3836 LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
4b0deb3b 3837 return 0;
0101483f
WL
3838 }
3839
4b0deb3b
DK
3840 // Fill in merkle branch
3841 vMerkleBranch = block.GetMerkleBranch(nIndex);
3842
0101483f 3843 // Is the tx in a block that's in the main chain
145d5be8 3844 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
0101483f
WL
3845 if (mi == mapBlockIndex.end())
3846 return 0;
4b0deb3b 3847 const CBlockIndex* pindex = (*mi).second;
0101483f
WL
3848 if (!pindex || !chainActive.Contains(pindex))
3849 return 0;
3850
3851 return chainActive.Height() - pindex->nHeight + 1;
3852}
3853
a31e8bad 3854int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
0101483f 3855{
4f152496 3856 if (hashBlock.IsNull() || nIndex == -1)
0101483f
WL
3857 return 0;
3858 AssertLockHeld(cs_main);
3859
3860 // Find the block it claims to be in
145d5be8 3861 BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
0101483f
WL
3862 if (mi == mapBlockIndex.end())
3863 return 0;
3864 CBlockIndex* pindex = (*mi).second;
3865 if (!pindex || !chainActive.Contains(pindex))
3866 return 0;
3867
3868 // Make sure the merkle branch connects to this block
3869 if (!fMerkleVerified)
3870 {
805344dc 3871 if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
0101483f
WL
3872 return 0;
3873 fMerkleVerified = true;
3874 }
3875
3876 pindexRet = pindex;
3877 return chainActive.Height() - pindex->nHeight + 1;
3878}
3879
a31e8bad 3880int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
0101483f
WL
3881{
3882 AssertLockHeld(cs_main);
3883 int nResult = GetDepthInMainChainINTERNAL(pindexRet);
805344dc 3884 if (nResult == 0 && !mempool.exists(GetHash()))
0101483f
WL
3885 return -1; // Not in chain, not in mempool
3886
3887 return nResult;
3888}
3889
3890int CMerkleTx::GetBlocksToMaturity() const
3891{
3892 if (!IsCoinBase())
3893 return 0;
3894 return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
3895}
3896
3897
1371e6f5 3898bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
0101483f
WL
3899{
3900 CValidationState state;
1371e6f5 3901 return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
0101483f
WL
3902}
3903
cb0d208f
S
3904/**
3905 * Find notes in the wallet filtered by payment address, min depth and ability to spend.
3906 * These notes are decrypted and added to the output parameter vector, outEntries.
3907 */
5020a936 3908void CWallet::GetFilteredNotes(std::vector<CSproutNotePlaintextEntry> & outEntries, std::string address, int minDepth, bool ignoreSpent, bool ignoreUnspendable)
a5ac2e25 3909{
bdbe8e85
JG
3910 std::set<PaymentAddress> filterAddresses;
3911
a5ac2e25 3912 if (address.length() > 0) {
e5eab182 3913 filterAddresses.insert(DecodePaymentAddress(address));
a5ac2e25
S
3914 }
3915
bdbe8e85
JG
3916 GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable);
3917}
3918
3919/**
3920 * Find notes in the wallet filtered by payment addresses, min depth and ability to spend.
3921 * These notes are decrypted and added to the output parameter vector, outEntries.
3922 */
3923void CWallet::GetFilteredNotes(
5020a936 3924 std::vector<CSproutNotePlaintextEntry>& outEntries,
bdbe8e85
JG
3925 std::set<PaymentAddress>& filterAddresses,
3926 int minDepth,
3927 bool ignoreSpent,
3928 bool ignoreUnspendable)
3929{
a5ac2e25
S
3930 LOCK2(cs_main, cs_wallet);
3931
3932 for (auto & p : mapWallet) {
3933 CWalletTx wtx = p.second;
3934
3935 // Filter the transactions before checking for notes
3936 if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < minDepth) {
3937 continue;
3938 }
3939
005f3ad1 3940 if (wtx.mapSproutNoteData.size() == 0) {
a5ac2e25
S
3941 continue;
3942 }
3943
005f3ad1 3944 for (auto & pair : wtx.mapSproutNoteData) {
a5ac2e25 3945 JSOutPoint jsop = pair.first;
005f3ad1 3946 SproutNoteData nd = pair.second;
e5eab182 3947 SproutPaymentAddress pa = nd.address;
a5ac2e25
S
3948
3949 // skip notes which belong to a different payment address in the wallet
bdbe8e85 3950 if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
a5ac2e25
S
3951 continue;
3952 }
3953
3954 // skip note which has been spent
1a62587e 3955 if (ignoreSpent && nd.nullifier && IsSpent(*nd.nullifier)) {
a5ac2e25
S
3956 continue;
3957 }
3958
9a2b8ae5 3959 // skip notes which cannot be spent
25d5e80c 3960 if (ignoreUnspendable && !HaveSproutSpendingKey(pa)) {
9a2b8ae5
JG
3961 continue;
3962 }
efb7662d 3963
4e6400bc 3964 // skip locked notes
b87e271a 3965 if (IsLockedNote(jsop)) {
4e6400bc
BM
3966 continue;
3967 }
9a2b8ae5 3968
a5ac2e25
S
3969 int i = jsop.js; // Index into CTransaction.vjoinsplit
3970 int j = jsop.n; // Index into JSDescription.ciphertexts
3971
3972 // Get cached decryptor
3973 ZCNoteDecryption decryptor;
3974 if (!GetNoteDecryptor(pa, decryptor)) {
3975 // Note decryptors are created when the wallet is loaded, so it should always exist
80ed13d5 3976 throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", EncodePaymentAddress(pa)));
a5ac2e25
S
3977 }
3978
3979 // determine amount of funds in the note
3980 auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey);
3981 try {
5020a936 3982 SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt(
a5ac2e25
S
3983 decryptor,
3984 wtx.vjoinsplit[i].ciphertexts[j],
3985 wtx.vjoinsplit[i].ephemeralKey,
3986 hSig,
3987 (unsigned char) j);
3988
5020a936 3989 outEntries.push_back(CSproutNotePlaintextEntry{jsop, pa, plaintext});
a5ac2e25 3990
51fde9ea 3991 } catch (const note_decryption_failed &err) {
a5ac2e25 3992 // Couldn't decrypt with this spending key
80ed13d5 3993 throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", EncodePaymentAddress(pa)));
51fde9ea
JG
3994 } catch (const std::exception &exc) {
3995 // Unexpected failure
80ed13d5 3996 throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what()));
a5ac2e25
S
3997 }
3998 }
3999 }
4000}
d72c19a6
S
4001
4002
4003/* Find unspent notes filtered by payment address, min depth and max depth */
4004void CWallet::GetUnspentFilteredNotes(
5020a936 4005 std::vector<CUnspentSproutNotePlaintextEntry>& outEntries,
d72c19a6
S
4006 std::set<PaymentAddress>& filterAddresses,
4007 int minDepth,
4008 int maxDepth,
4009 bool requireSpendingKey)
4010{
4011 LOCK2(cs_main, cs_wallet);
4012
4013 for (auto & p : mapWallet) {
4014 CWalletTx wtx = p.second;
4015
4016 // Filter the transactions before checking for notes
4017 if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < minDepth || wtx.GetDepthInMainChain() > maxDepth) {
4018 continue;
4019 }
4020
005f3ad1 4021 if (wtx.mapSproutNoteData.size() == 0) {
d72c19a6
S
4022 continue;
4023 }
4024
005f3ad1 4025 for (auto & pair : wtx.mapSproutNoteData) {
d72c19a6 4026 JSOutPoint jsop = pair.first;
005f3ad1 4027 SproutNoteData nd = pair.second;
e5eab182 4028 SproutPaymentAddress pa = nd.address;
d72c19a6
S
4029
4030 // skip notes which belong to a different payment address in the wallet
4031 if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
4032 continue;
4033 }
4034
4035 // skip note which has been spent
4036 if (nd.nullifier && IsSpent(*nd.nullifier)) {
4037 continue;
4038 }
4039
4040 // skip notes where the spending key is not available
25d5e80c 4041 if (requireSpendingKey && !HaveSproutSpendingKey(pa)) {
d72c19a6
S
4042 continue;
4043 }
4044
4045 int i = jsop.js; // Index into CTransaction.vjoinsplit
4046 int j = jsop.n; // Index into JSDescription.ciphertexts
4047
4048 // Get cached decryptor
4049 ZCNoteDecryption decryptor;
4050 if (!GetNoteDecryptor(pa, decryptor)) {
4051 // Note decryptors are created when the wallet is loaded, so it should always exist
80ed13d5 4052 throw std::runtime_error(strprintf("Could not find note decryptor for payment address %s", EncodePaymentAddress(pa)));
d72c19a6
S
4053 }
4054
4055 // determine amount of funds in the note
4056 auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey);
4057 try {
5020a936 4058 SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt(
d72c19a6
S
4059 decryptor,
4060 wtx.vjoinsplit[i].ciphertexts[j],
4061 wtx.vjoinsplit[i].ephemeralKey,
4062 hSig,
4063 (unsigned char) j);
4064
5020a936 4065 outEntries.push_back(CUnspentSproutNotePlaintextEntry{jsop, pa, plaintext, wtx.GetDepthInMainChain()});
d72c19a6
S
4066
4067 } catch (const note_decryption_failed &err) {
4068 // Couldn't decrypt with this spending key
80ed13d5 4069 throw std::runtime_error(strprintf("Could not decrypt note for payment address %s", EncodePaymentAddress(pa)));
d72c19a6
S
4070 } catch (const std::exception &exc) {
4071 // Unexpected failure
80ed13d5 4072 throw std::runtime_error(strprintf("Error while decrypting note for payment address %s: %s", EncodePaymentAddress(pa), exc.what()));
d72c19a6
S
4073 }
4074 }
4075 }
4076}
4077
This page took 0.940305 seconds and 4 git commands to generate.