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