1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <wallet/wallet.h>
7 
8 #include <chain.h>
9 #include <consensus/consensus.h>
10 #include <consensus/validation.h>
11 #include <fs.h>
12 #include <interfaces/chain.h>
13 #include <interfaces/wallet.h>
14 #include <key.h>
15 #include <key_io.h>
16 #include <names/encoding.h>
17 #include <optional.h>
18 #include <policy/fees.h>
19 #include <policy/policy.h>
20 #include <primitives/block.h>
21 #include <primitives/transaction.h>
22 #include <script/descriptor.h>
23 #include <script/names.h>
24 #include <script/script.h>
25 #include <script/signingprovider.h>
26 #include <txmempool.h>
27 #include <util/bip32.h>
28 #include <util/check.h>
29 #include <util/error.h>
30 #include <util/fees.h>
31 #include <util/moneystr.h>
32 #include <util/rbf.h>
33 #include <util/string.h>
34 #include <util/translation.h>
35 #include <wallet/coincontrol.h>
36 #include <wallet/fees.h>
37 
38 #include <univalue.h>
39 
40 #include <algorithm>
41 #include <assert.h>
42 
43 #include <boost/algorithm/string/replace.hpp>
44 
45 using interfaces::FoundBlock;
46 
47 const std::map<uint64_t,std::string> WALLET_FLAG_CAVEATS{
48     {WALLET_FLAG_AVOID_REUSE,
49         "You need to rescan the blockchain in order to correctly mark used "
50         "destinations in the past. Until this is done, some destinations may "
51         "be considered unused, even if the opposite is the case."
52     },
53 };
54 
55 static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10;
56 
57 static RecursiveMutex cs_wallets;
58 static std::vector<std::shared_ptr<CWallet>> vpwallets GUARDED_BY(cs_wallets);
59 static std::list<LoadWalletFn> g_load_wallet_fns GUARDED_BY(cs_wallets);
60 
AddWalletSetting(interfaces::Chain & chain,const std::string & wallet_name)61 bool AddWalletSetting(interfaces::Chain& chain, const std::string& wallet_name)
62 {
63     util::SettingsValue setting_value = chain.getRwSetting("wallet");
64     if (!setting_value.isArray()) setting_value.setArray();
65     for (const util::SettingsValue& value : setting_value.getValues()) {
66         if (value.isStr() && value.get_str() == wallet_name) return true;
67     }
68     setting_value.push_back(wallet_name);
69     return chain.updateRwSetting("wallet", setting_value);
70 }
71 
RemoveWalletSetting(interfaces::Chain & chain,const std::string & wallet_name)72 bool RemoveWalletSetting(interfaces::Chain& chain, const std::string& wallet_name)
73 {
74     util::SettingsValue setting_value = chain.getRwSetting("wallet");
75     if (!setting_value.isArray()) return true;
76     util::SettingsValue new_value(util::SettingsValue::VARR);
77     for (const util::SettingsValue& value : setting_value.getValues()) {
78         if (!value.isStr() || value.get_str() != wallet_name) new_value.push_back(value);
79     }
80     if (new_value.size() == setting_value.size()) return true;
81     return chain.updateRwSetting("wallet", new_value);
82 }
83 
UpdateWalletSetting(interfaces::Chain & chain,const std::string & wallet_name,Optional<bool> load_on_startup,std::vector<bilingual_str> & warnings)84 static void UpdateWalletSetting(interfaces::Chain& chain,
85                                 const std::string& wallet_name,
86                                 Optional<bool> load_on_startup,
87                                 std::vector<bilingual_str>& warnings)
88 {
89     if (load_on_startup == nullopt) return;
90     if (load_on_startup.get() && !AddWalletSetting(chain, wallet_name)) {
91         warnings.emplace_back(Untranslated("Wallet load on startup setting could not be updated, so wallet may not be loaded next node startup."));
92     } else if (!load_on_startup.get() && !RemoveWalletSetting(chain, wallet_name)) {
93         warnings.emplace_back(Untranslated("Wallet load on startup setting could not be updated, so wallet may still be loaded next node startup."));
94     }
95 }
96 
AddWallet(const std::shared_ptr<CWallet> & wallet)97 bool AddWallet(const std::shared_ptr<CWallet>& wallet)
98 {
99     LOCK(cs_wallets);
100     assert(wallet);
101     std::vector<std::shared_ptr<CWallet>>::const_iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
102     if (i != vpwallets.end()) return false;
103     vpwallets.push_back(wallet);
104     wallet->ConnectScriptPubKeyManNotifiers();
105     wallet->NotifyCanGetAddressesChanged();
106     return true;
107 }
108 
RemoveWallet(const std::shared_ptr<CWallet> & wallet,Optional<bool> load_on_start,std::vector<bilingual_str> & warnings)109 bool RemoveWallet(const std::shared_ptr<CWallet>& wallet, Optional<bool> load_on_start, std::vector<bilingual_str>& warnings)
110 {
111     assert(wallet);
112 
113     interfaces::Chain& chain = wallet->chain();
114     std::string name = wallet->GetName();
115 
116     // Unregister with the validation interface which also drops shared ponters.
117     wallet->m_chain_notifications_handler.reset();
118     LOCK(cs_wallets);
119     std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
120     if (i == vpwallets.end()) return false;
121     vpwallets.erase(i);
122 
123     // Write the wallet setting
124     UpdateWalletSetting(chain, name, load_on_start, warnings);
125 
126     return true;
127 }
128 
RemoveWallet(const std::shared_ptr<CWallet> & wallet,Optional<bool> load_on_start)129 bool RemoveWallet(const std::shared_ptr<CWallet>& wallet, Optional<bool> load_on_start)
130 {
131     std::vector<bilingual_str> warnings;
132     return RemoveWallet(wallet, load_on_start, warnings);
133 }
134 
GetWallets()135 std::vector<std::shared_ptr<CWallet>> GetWallets()
136 {
137     LOCK(cs_wallets);
138     return vpwallets;
139 }
140 
GetWallet(const std::string & name)141 std::shared_ptr<CWallet> GetWallet(const std::string& name)
142 {
143     LOCK(cs_wallets);
144     for (const std::shared_ptr<CWallet>& wallet : vpwallets) {
145         if (wallet->GetName() == name) return wallet;
146     }
147     return nullptr;
148 }
149 
HandleLoadWallet(LoadWalletFn load_wallet)150 std::unique_ptr<interfaces::Handler> HandleLoadWallet(LoadWalletFn load_wallet)
151 {
152     LOCK(cs_wallets);
153     auto it = g_load_wallet_fns.emplace(g_load_wallet_fns.end(), std::move(load_wallet));
154     return interfaces::MakeHandler([it] { LOCK(cs_wallets); g_load_wallet_fns.erase(it); });
155 }
156 
157 static Mutex g_loading_wallet_mutex;
158 static Mutex g_wallet_release_mutex;
159 static std::condition_variable g_wallet_release_cv;
160 static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mutex);
161 static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
162 
163 // Custom deleter for shared_ptr<CWallet>.
ReleaseWallet(CWallet * wallet)164 static void ReleaseWallet(CWallet* wallet)
165 {
166     const std::string name = wallet->GetName();
167     wallet->WalletLogPrintf("Releasing wallet\n");
168     wallet->Flush();
169     delete wallet;
170     // Wallet is now released, notify UnloadWallet, if any.
171     {
172         LOCK(g_wallet_release_mutex);
173         if (g_unloading_wallet_set.erase(name) == 0) {
174             // UnloadWallet was not called for this wallet, all done.
175             return;
176         }
177     }
178     g_wallet_release_cv.notify_all();
179 }
180 
UnloadWallet(std::shared_ptr<CWallet> && wallet)181 void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
182 {
183     // Mark wallet for unloading.
184     const std::string name = wallet->GetName();
185     {
186         LOCK(g_wallet_release_mutex);
187         auto it = g_unloading_wallet_set.insert(name);
188         assert(it.second);
189     }
190     // The wallet can be in use so it's not possible to explicitly unload here.
191     // Notify the unload intent so that all remaining shared pointers are
192     // released.
193     wallet->NotifyUnload();
194 
195     // Time to ditch our shared_ptr and wait for ReleaseWallet call.
196     wallet.reset();
197     {
198         WAIT_LOCK(g_wallet_release_mutex, lock);
199         while (g_unloading_wallet_set.count(name) == 1) {
200             g_wallet_release_cv.wait(lock);
201         }
202     }
203 }
204 
205 namespace {
LoadWalletInternal(interfaces::Chain & chain,const std::string & name,Optional<bool> load_on_start,const DatabaseOptions & options,DatabaseStatus & status,bilingual_str & error,std::vector<bilingual_str> & warnings)206 std::shared_ptr<CWallet> LoadWalletInternal(interfaces::Chain& chain, const std::string& name, Optional<bool> load_on_start, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
207 {
208     try {
209         std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(name, options, status, error);
210         if (!database) {
211             error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error;
212             return nullptr;
213         }
214 
215         std::shared_ptr<CWallet> wallet = CWallet::Create(chain, name, std::move(database), options.create_flags, error, warnings);
216         if (!wallet) {
217             error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error;
218             status = DatabaseStatus::FAILED_LOAD;
219             return nullptr;
220         }
221         AddWallet(wallet);
222         wallet->postInitProcess();
223 
224         // Write the wallet setting
225         UpdateWalletSetting(chain, name, load_on_start, warnings);
226 
227         return wallet;
228     } catch (const std::runtime_error& e) {
229         error = Untranslated(e.what());
230         status = DatabaseStatus::FAILED_LOAD;
231         return nullptr;
232     }
233 }
234 } // namespace
235 
LoadWallet(interfaces::Chain & chain,const std::string & name,Optional<bool> load_on_start,const DatabaseOptions & options,DatabaseStatus & status,bilingual_str & error,std::vector<bilingual_str> & warnings)236 std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, Optional<bool> load_on_start, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
237 {
238     auto result = WITH_LOCK(g_loading_wallet_mutex, return g_loading_wallet_set.insert(name));
239     if (!result.second) {
240         error = Untranslated("Wallet already being loading.");
241         status = DatabaseStatus::FAILED_LOAD;
242         return nullptr;
243     }
244     auto wallet = LoadWalletInternal(chain, name, load_on_start, options, status, error, warnings);
245     WITH_LOCK(g_loading_wallet_mutex, g_loading_wallet_set.erase(result.first));
246     return wallet;
247 }
248 
CreateWallet(interfaces::Chain & chain,const std::string & name,Optional<bool> load_on_start,DatabaseOptions & options,DatabaseStatus & status,bilingual_str & error,std::vector<bilingual_str> & warnings)249 std::shared_ptr<CWallet> CreateWallet(interfaces::Chain& chain, const std::string& name, Optional<bool> load_on_start, DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
250 {
251     uint64_t wallet_creation_flags = options.create_flags;
252     const SecureString& passphrase = options.create_passphrase;
253 
254     if (wallet_creation_flags & WALLET_FLAG_DESCRIPTORS) options.require_format = DatabaseFormat::SQLITE;
255 
256     // Indicate that the wallet is actually supposed to be blank and not just blank to make it encrypted
257     bool create_blank = (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET);
258 
259     // Born encrypted wallets need to be created blank first.
260     if (!passphrase.empty()) {
261         wallet_creation_flags |= WALLET_FLAG_BLANK_WALLET;
262     }
263 
264     // Wallet::Verify will check if we're trying to create a wallet with a duplicate name.
265     std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(name, options, status, error);
266     if (!database) {
267         error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error;
268         status = DatabaseStatus::FAILED_VERIFY;
269         return nullptr;
270     }
271 
272     // Do not allow a passphrase when private keys are disabled
273     if (!passphrase.empty() && (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
274         error = Untranslated("Passphrase provided but private keys are disabled. A passphrase is only used to encrypt private keys, so cannot be used for wallets with private keys disabled.");
275         status = DatabaseStatus::FAILED_CREATE;
276         return nullptr;
277     }
278 
279     // Make the wallet
280     std::shared_ptr<CWallet> wallet = CWallet::Create(chain, name, std::move(database), wallet_creation_flags, error, warnings);
281     if (!wallet) {
282         error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error;
283         status = DatabaseStatus::FAILED_CREATE;
284         return nullptr;
285     }
286 
287     // Encrypt the wallet
288     if (!passphrase.empty() && !(wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
289         if (!wallet->EncryptWallet(passphrase)) {
290             error = Untranslated("Error: Wallet created but failed to encrypt.");
291             status = DatabaseStatus::FAILED_ENCRYPT;
292             return nullptr;
293         }
294         if (!create_blank) {
295             // Unlock the wallet
296             if (!wallet->Unlock(passphrase)) {
297                 error = Untranslated("Error: Wallet was encrypted but could not be unlocked");
298                 status = DatabaseStatus::FAILED_ENCRYPT;
299                 return nullptr;
300             }
301 
302             // Set a seed for the wallet
303             {
304                 LOCK(wallet->cs_wallet);
305                 if (wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
306                     wallet->SetupDescriptorScriptPubKeyMans();
307                 } else {
308                     for (auto spk_man : wallet->GetActiveScriptPubKeyMans()) {
309                         if (!spk_man->SetupGeneration()) {
310                             error = Untranslated("Unable to generate initial keys");
311                             status = DatabaseStatus::FAILED_CREATE;
312                             return nullptr;
313                         }
314                     }
315                 }
316             }
317 
318             // Relock the wallet
319             wallet->Lock();
320         }
321     }
322     AddWallet(wallet);
323     wallet->postInitProcess();
324 
325     // Write the wallet settings
326     UpdateWalletSetting(chain, name, load_on_start, warnings);
327 
328     status = DatabaseStatus::SUCCESS;
329     return wallet;
330 }
331 
332 /** @defgroup mapWallet
333  *
334  * @{
335  */
336 
ToString() const337 std::string COutput::ToString() const
338 {
339     return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->tx->vout[i].nValue));
340 }
341 
GetWalletTx(const uint256 & hash) const342 const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
343 {
344     AssertLockHeld(cs_wallet);
345     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
346     if (it == mapWallet.end())
347         return nullptr;
348     return &(it->second);
349 }
350 
UpgradeKeyMetadata()351 void CWallet::UpgradeKeyMetadata()
352 {
353     if (IsLocked() || IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) {
354         return;
355     }
356 
357     auto spk_man = GetLegacyScriptPubKeyMan();
358     if (!spk_man) {
359         return;
360     }
361 
362     spk_man->UpgradeKeyMetadata();
363     SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
364 }
365 
Unlock(const SecureString & strWalletPassphrase,bool accept_no_keys)366 bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys)
367 {
368     CCrypter crypter;
369     CKeyingMaterial _vMasterKey;
370 
371     {
372         LOCK(cs_wallet);
373         for (const MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
374         {
375             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
376                 return false;
377             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
378                 continue; // try another master key
379             if (Unlock(_vMasterKey, accept_no_keys)) {
380                 // Now that we've unlocked, upgrade the key metadata
381                 UpgradeKeyMetadata();
382                 return true;
383             }
384         }
385     }
386     return false;
387 }
388 
ChangeWalletPassphrase(const SecureString & strOldWalletPassphrase,const SecureString & strNewWalletPassphrase)389 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
390 {
391     bool fWasLocked = IsLocked();
392 
393     {
394         LOCK(cs_wallet);
395         Lock();
396 
397         CCrypter crypter;
398         CKeyingMaterial _vMasterKey;
399         for (MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
400         {
401             if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
402                 return false;
403             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
404                 return false;
405             if (Unlock(_vMasterKey))
406             {
407                 int64_t nStartTime = GetTimeMillis();
408                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
409                 pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))));
410 
411                 nStartTime = GetTimeMillis();
412                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
413                 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
414 
415                 if (pMasterKey.second.nDeriveIterations < 25000)
416                     pMasterKey.second.nDeriveIterations = 25000;
417 
418                 WalletLogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
419 
420                 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
421                     return false;
422                 if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
423                     return false;
424                 WalletBatch(*database).WriteMasterKey(pMasterKey.first, pMasterKey.second);
425                 if (fWasLocked)
426                     Lock();
427                 return true;
428             }
429         }
430     }
431 
432     return false;
433 }
434 
chainStateFlushed(const CBlockLocator & loc)435 void CWallet::chainStateFlushed(const CBlockLocator& loc)
436 {
437     WalletBatch batch(*database);
438     batch.WriteBestBlock(loc);
439 }
440 
SetMinVersion(enum WalletFeature nVersion,WalletBatch * batch_in)441 void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in)
442 {
443     LOCK(cs_wallet);
444     if (nWalletVersion >= nVersion)
445         return;
446     nWalletVersion = nVersion;
447 
448     {
449         WalletBatch* batch = batch_in ? batch_in : new WalletBatch(*database);
450         if (nWalletVersion > 40000)
451             batch->WriteMinVersion(nWalletVersion);
452         if (!batch_in)
453             delete batch;
454     }
455 }
456 
GetConflicts(const uint256 & txid) const457 std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
458 {
459     std::set<uint256> result;
460     AssertLockHeld(cs_wallet);
461 
462     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
463     if (it == mapWallet.end())
464         return result;
465     const CWalletTx& wtx = it->second;
466 
467     std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
468 
469     for (const CTxIn& txin : wtx.tx->vin)
470     {
471         if (mapTxSpends.count(txin.prevout) <= 1)
472             continue;  // No conflict if zero or one spends
473         range = mapTxSpends.equal_range(txin.prevout);
474         for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
475             result.insert(_it->second);
476     }
477     return result;
478 }
479 
HasWalletSpend(const uint256 & txid) const480 bool CWallet::HasWalletSpend(const uint256& txid) const
481 {
482     AssertLockHeld(cs_wallet);
483     auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
484     return (iter != mapTxSpends.end() && iter->first.hash == txid);
485 }
486 
Flush()487 void CWallet::Flush()
488 {
489     database->Flush();
490 }
491 
Close()492 void CWallet::Close()
493 {
494     database->Close();
495 }
496 
SyncMetaData(std::pair<TxSpends::iterator,TxSpends::iterator> range)497 void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> range)
498 {
499     // We want all the wallet transactions in range to have the same metadata as
500     // the oldest (smallest nOrderPos).
501     // So: find smallest nOrderPos:
502 
503     int nMinOrderPos = std::numeric_limits<int>::max();
504     const CWalletTx* copyFrom = nullptr;
505     for (TxSpends::iterator it = range.first; it != range.second; ++it) {
506         const CWalletTx* wtx = &mapWallet.at(it->second);
507         if (wtx->nOrderPos < nMinOrderPos) {
508             nMinOrderPos = wtx->nOrderPos;
509             copyFrom = wtx;
510         }
511     }
512 
513     if (!copyFrom) {
514         return;
515     }
516 
517     // Now copy data from copyFrom to rest:
518     for (TxSpends::iterator it = range.first; it != range.second; ++it)
519     {
520         const uint256& hash = it->second;
521         CWalletTx* copyTo = &mapWallet.at(hash);
522         if (copyFrom == copyTo) continue;
523         assert(copyFrom && "Oldest wallet transaction in range assumed to have been found.");
524         if (!copyFrom->IsEquivalentTo(*copyTo)) continue;
525         copyTo->mapValue = copyFrom->mapValue;
526         copyTo->vOrderForm = copyFrom->vOrderForm;
527         // fTimeReceivedIsTxTime not copied on purpose
528         // nTimeReceived not copied on purpose
529         copyTo->nTimeSmart = copyFrom->nTimeSmart;
530         copyTo->fFromMe = copyFrom->fFromMe;
531         // nOrderPos not copied on purpose
532         // cached members not copied on purpose
533     }
534 }
535 
536 /**
537  * Outpoint is spent if any non-conflicted transaction
538  * spends it:
539  */
IsSpent(const uint256 & hash,unsigned int n) const540 bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
541 {
542     const COutPoint outpoint(hash, n);
543     std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
544     range = mapTxSpends.equal_range(outpoint);
545 
546     for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
547     {
548         const uint256& wtxid = it->second;
549         std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
550         if (mit != mapWallet.end()) {
551             int depth = mit->second.GetDepthInMainChain();
552             if (depth > 0  || (depth == 0 && !mit->second.isAbandoned()))
553                 return true; // Spent
554         }
555     }
556     return false;
557 }
558 
AddToSpends(const COutPoint & outpoint,const uint256 & wtxid)559 void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
560 {
561     mapTxSpends.insert(std::make_pair(outpoint, wtxid));
562 
563     setLockedCoins.erase(outpoint);
564 
565     std::pair<TxSpends::iterator, TxSpends::iterator> range;
566     range = mapTxSpends.equal_range(outpoint);
567     SyncMetaData(range);
568 }
569 
570 
AddToSpends(const uint256 & wtxid)571 void CWallet::AddToSpends(const uint256& wtxid)
572 {
573     auto it = mapWallet.find(wtxid);
574     assert(it != mapWallet.end());
575     CWalletTx& thisTx = it->second;
576     if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
577         return;
578 
579     for (const CTxIn& txin : thisTx.tx->vin)
580         AddToSpends(txin.prevout, wtxid);
581 }
582 
EncryptWallet(const SecureString & strWalletPassphrase)583 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
584 {
585     if (IsCrypted())
586         return false;
587 
588     CKeyingMaterial _vMasterKey;
589 
590     _vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
591     GetStrongRandBytes(&_vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
592 
593     CMasterKey kMasterKey;
594 
595     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
596     GetStrongRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
597 
598     CCrypter crypter;
599     int64_t nStartTime = GetTimeMillis();
600     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
601     kMasterKey.nDeriveIterations = static_cast<unsigned int>(2500000 / ((double)(GetTimeMillis() - nStartTime)));
602 
603     nStartTime = GetTimeMillis();
604     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
605     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
606 
607     if (kMasterKey.nDeriveIterations < 25000)
608         kMasterKey.nDeriveIterations = 25000;
609 
610     WalletLogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
611 
612     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
613         return false;
614     if (!crypter.Encrypt(_vMasterKey, kMasterKey.vchCryptedKey))
615         return false;
616 
617     {
618         LOCK(cs_wallet);
619         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
620         WalletBatch* encrypted_batch = new WalletBatch(*database);
621         if (!encrypted_batch->TxnBegin()) {
622             delete encrypted_batch;
623             encrypted_batch = nullptr;
624             return false;
625         }
626         encrypted_batch->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
627 
628         for (const auto& spk_man_pair : m_spk_managers) {
629             auto spk_man = spk_man_pair.second.get();
630             if (!spk_man->Encrypt(_vMasterKey, encrypted_batch)) {
631                 encrypted_batch->TxnAbort();
632                 delete encrypted_batch;
633                 encrypted_batch = nullptr;
634                 // We now probably have half of our keys encrypted in memory, and half not...
635                 // die and let the user reload the unencrypted wallet.
636                 assert(false);
637             }
638         }
639 
640         // Encryption was introduced in version 0.4.0
641         SetMinVersion(FEATURE_WALLETCRYPT, encrypted_batch);
642 
643         if (!encrypted_batch->TxnCommit()) {
644             delete encrypted_batch;
645             encrypted_batch = nullptr;
646             // We now have keys encrypted in memory, but not on disk...
647             // die to avoid confusion and let the user reload the unencrypted wallet.
648             assert(false);
649         }
650 
651         delete encrypted_batch;
652         encrypted_batch = nullptr;
653 
654         Lock();
655         Unlock(strWalletPassphrase);
656 
657         // If we are using descriptors, make new descriptors with a new seed
658         if (IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) && !IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET)) {
659             SetupDescriptorScriptPubKeyMans();
660         } else if (auto spk_man = GetLegacyScriptPubKeyMan()) {
661             // if we are using HD, replace the HD seed with a new one
662             if (spk_man->IsHDEnabled()) {
663                 if (!spk_man->SetupGeneration(true)) {
664                     return false;
665                 }
666             }
667         }
668         Lock();
669 
670         // Need to completely rewrite the wallet file; if we don't, bdb might keep
671         // bits of the unencrypted private key in slack space in the database file.
672         database->Rewrite();
673 
674         // BDB seems to have a bad habit of writing old data into
675         // slack space in .dat files; that is bad if the old data is
676         // unencrypted private keys. So:
677         database->ReloadDbEnv();
678 
679     }
680     NotifyStatusChanged(this);
681 
682     return true;
683 }
684 
ReorderTransactions()685 DBErrors CWallet::ReorderTransactions()
686 {
687     LOCK(cs_wallet);
688     WalletBatch batch(*database);
689 
690     // Old wallets didn't have any defined order for transactions
691     // Probably a bad idea to change the output of this
692 
693     // First: get all CWalletTx into a sorted-by-time multimap.
694     typedef std::multimap<int64_t, CWalletTx*> TxItems;
695     TxItems txByTime;
696 
697     for (auto& entry : mapWallet)
698     {
699         CWalletTx* wtx = &entry.second;
700         txByTime.insert(std::make_pair(wtx->nTimeReceived, wtx));
701     }
702 
703     nOrderPosNext = 0;
704     std::vector<int64_t> nOrderPosOffsets;
705     for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it)
706     {
707         CWalletTx *const pwtx = (*it).second;
708         int64_t& nOrderPos = pwtx->nOrderPos;
709 
710         if (nOrderPos == -1)
711         {
712             nOrderPos = nOrderPosNext++;
713             nOrderPosOffsets.push_back(nOrderPos);
714 
715             if (!batch.WriteTx(*pwtx))
716                 return DBErrors::LOAD_FAIL;
717         }
718         else
719         {
720             int64_t nOrderPosOff = 0;
721             for (const int64_t& nOffsetStart : nOrderPosOffsets)
722             {
723                 if (nOrderPos >= nOffsetStart)
724                     ++nOrderPosOff;
725             }
726             nOrderPos += nOrderPosOff;
727             nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
728 
729             if (!nOrderPosOff)
730                 continue;
731 
732             // Since we're changing the order, write it back
733             if (!batch.WriteTx(*pwtx))
734                 return DBErrors::LOAD_FAIL;
735         }
736     }
737     batch.WriteOrderPosNext(nOrderPosNext);
738 
739     return DBErrors::LOAD_OK;
740 }
741 
IncOrderPosNext(WalletBatch * batch)742 int64_t CWallet::IncOrderPosNext(WalletBatch* batch)
743 {
744     AssertLockHeld(cs_wallet);
745     int64_t nRet = nOrderPosNext++;
746     if (batch) {
747         batch->WriteOrderPosNext(nOrderPosNext);
748     } else {
749         WalletBatch(*database).WriteOrderPosNext(nOrderPosNext);
750     }
751     return nRet;
752 }
753 
MarkDirty()754 void CWallet::MarkDirty()
755 {
756     {
757         LOCK(cs_wallet);
758         for (std::pair<const uint256, CWalletTx>& item : mapWallet)
759             item.second.MarkDirty();
760     }
761 }
762 
MarkReplaced(const uint256 & originalHash,const uint256 & newHash)763 bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
764 {
765     LOCK(cs_wallet);
766 
767     auto mi = mapWallet.find(originalHash);
768 
769     // There is a bug if MarkReplaced is not called on an existing wallet transaction.
770     assert(mi != mapWallet.end());
771 
772     CWalletTx& wtx = (*mi).second;
773 
774     // Ensure for now that we're not overwriting data
775     assert(wtx.mapValue.count("replaced_by_txid") == 0);
776 
777     wtx.mapValue["replaced_by_txid"] = newHash.ToString();
778 
779     WalletBatch batch(*database);
780 
781     bool success = true;
782     if (!batch.WriteTx(wtx)) {
783         WalletLogPrintf("%s: Updating batch tx %s failed\n", __func__, wtx.GetHash().ToString());
784         success = false;
785     }
786 
787     NotifyTransactionChanged(this, originalHash, CT_UPDATED);
788 
789     return success;
790 }
791 
SetSpentKeyState(WalletBatch & batch,const uint256 & hash,unsigned int n,bool used,std::set<CTxDestination> & tx_destinations)792 void CWallet::SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations)
793 {
794     AssertLockHeld(cs_wallet);
795     const CWalletTx* srctx = GetWalletTx(hash);
796     if (!srctx) return;
797 
798     CTxDestination dst;
799     if (ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst)) {
800         if (IsMine(dst)) {
801             if (used && !GetDestData(dst, "used", nullptr)) {
802                 if (AddDestData(batch, dst, "used", "p")) { // p for "present", opposite of absent (null)
803                     tx_destinations.insert(dst);
804                 }
805             } else if (!used && GetDestData(dst, "used", nullptr)) {
806                 EraseDestData(batch, dst, "used");
807             }
808         }
809     }
810 }
811 
IsSpentKey(const uint256 & hash,unsigned int n) const812 bool CWallet::IsSpentKey(const uint256& hash, unsigned int n) const
813 {
814     AssertLockHeld(cs_wallet);
815     const CWalletTx* srctx = GetWalletTx(hash);
816     if (srctx) {
817         assert(srctx->tx->vout.size() > n);
818         CTxDestination dest;
819         if (!ExtractDestination(srctx->tx->vout[n].scriptPubKey, dest)) {
820             return false;
821         }
822         if (GetDestData(dest, "used", nullptr)) {
823             return true;
824         }
825         if (IsLegacy()) {
826             LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
827             assert(spk_man != nullptr);
828             for (const auto& keyid : GetAffectedKeys(srctx->tx->vout[n].scriptPubKey, *spk_man)) {
829                 WitnessV0KeyHash wpkh_dest(keyid);
830                 if (GetDestData(wpkh_dest, "used", nullptr)) {
831                     return true;
832                 }
833                 ScriptHash sh_wpkh_dest(GetScriptForDestination(wpkh_dest));
834                 if (GetDestData(sh_wpkh_dest, "used", nullptr)) {
835                     return true;
836                 }
837                 PKHash pkh_dest(keyid);
838                 if (GetDestData(pkh_dest, "used", nullptr)) {
839                     return true;
840                 }
841             }
842         }
843     }
844     return false;
845 }
846 
AddToWallet(CTransactionRef tx,const CWalletTx::Confirmation & confirm,const UpdateWalletTxFn & update_wtx,bool fFlushOnClose)847 CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation& confirm, const UpdateWalletTxFn& update_wtx, bool fFlushOnClose)
848 {
849     LOCK(cs_wallet);
850 
851     WalletBatch batch(*database, fFlushOnClose);
852 
853     uint256 hash = tx->GetHash();
854 
855     if (IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) {
856         // Mark used destinations
857         std::set<CTxDestination> tx_destinations;
858 
859         for (const CTxIn& txin : tx->vin) {
860             const COutPoint& op = txin.prevout;
861             SetSpentKeyState(batch, op.hash, op.n, true, tx_destinations);
862         }
863 
864         MarkDestinationsDirty(tx_destinations);
865     }
866 
867     // Inserts only if not already there, returns tx inserted or tx found
868     auto ret = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(this, tx));
869     CWalletTx& wtx = (*ret.first).second;
870     bool fInsertedNew = ret.second;
871     bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew);
872     if (fInsertedNew) {
873         wtx.m_confirm = confirm;
874         wtx.nTimeReceived = chain().getAdjustedTime();
875         wtx.nOrderPos = IncOrderPosNext(&batch);
876         wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
877         wtx.nTimeSmart = ComputeTimeSmart(wtx);
878         AddToSpends(hash);
879     }
880 
881     if (!fInsertedNew)
882     {
883         if (confirm.status != wtx.m_confirm.status) {
884             wtx.m_confirm.status = confirm.status;
885             wtx.m_confirm.nIndex = confirm.nIndex;
886             wtx.m_confirm.hashBlock = confirm.hashBlock;
887             wtx.m_confirm.block_height = confirm.block_height;
888             fUpdated = true;
889         } else {
890             assert(wtx.m_confirm.nIndex == confirm.nIndex);
891             assert(wtx.m_confirm.hashBlock == confirm.hashBlock);
892             assert(wtx.m_confirm.block_height == confirm.block_height);
893         }
894         // If we have a witness-stripped version of this transaction, and we
895         // see a new version with a witness, then we must be upgrading a pre-segwit
896         // wallet.  Store the new version of the transaction with the witness,
897         // as the stripped-version must be invalid.
898         // TODO: Store all versions of the transaction, instead of just one.
899         if (tx->HasWitness() && !wtx.tx->HasWitness()) {
900             wtx.SetTx(tx);
901             fUpdated = true;
902         }
903     }
904 
905     //// debug print
906     WalletLogPrintf("AddToWallet %s  %s%s\n", hash.ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
907 
908     // Write to disk
909     if (fInsertedNew || fUpdated)
910         if (!batch.WriteTx(wtx))
911             return nullptr;
912 
913     // Break debit/credit balance caches:
914     wtx.MarkDirty();
915 
916     // Notify UI of new or updated transaction
917     NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
918 
919 #if HAVE_SYSTEM
920     // notify an external script when a wallet transaction comes in or is updated
921     std::string strCmd = gArgs.GetArg("-walletnotify", "");
922 
923     if (!strCmd.empty())
924     {
925         boost::replace_all(strCmd, "%s", hash.GetHex());
926 #ifndef WIN32
927         // Substituting the wallet name isn't currently supported on windows
928         // because windows shell escaping has not been implemented yet:
929         // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-537384875
930         // A few ways it could be implemented in the future are described in:
931         // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-461288094
932         boost::replace_all(strCmd, "%w", ShellEscape(GetName()));
933 #endif
934         std::thread t(runCommand, strCmd);
935         t.detach(); // thread runs free
936     }
937 #endif
938 
939     return &wtx;
940 }
941 
LoadToWallet(const uint256 & hash,const UpdateWalletTxFn & fill_wtx)942 bool CWallet::LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx)
943 {
944     const auto& ins = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(this, nullptr));
945     CWalletTx& wtx = ins.first->second;
946     if (!fill_wtx(wtx, ins.second)) {
947         return false;
948     }
949     // If wallet doesn't have a chain (e.g wallet-tool), don't bother to update txn.
950     if (HaveChain()) {
951         Optional<int> block_height = chain().getBlockHeight(wtx.m_confirm.hashBlock);
952         if (block_height) {
953             // Update cached block height variable since it not stored in the
954             // serialized transaction.
955             wtx.m_confirm.block_height = *block_height;
956         } else if (wtx.isConflicted() || wtx.isConfirmed()) {
957             // If tx block (or conflicting block) was reorged out of chain
958             // while the wallet was shutdown, change tx status to UNCONFIRMED
959             // and reset block height, hash, and index. ABANDONED tx don't have
960             // associated blocks and don't need to be updated. The case where a
961             // transaction was reorged out while online and then reconfirmed
962             // while offline is covered by the rescan logic.
963             wtx.setUnconfirmed();
964             wtx.m_confirm.hashBlock = uint256();
965             wtx.m_confirm.block_height = 0;
966             wtx.m_confirm.nIndex = 0;
967         }
968     }
969     if (/* insertion took place */ ins.second) {
970         wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
971     }
972     AddToSpends(hash);
973     for (const CTxIn& txin : wtx.tx->vin) {
974         auto it = mapWallet.find(txin.prevout.hash);
975         if (it != mapWallet.end()) {
976             CWalletTx& prevtx = it->second;
977             if (prevtx.isConflicted()) {
978                 MarkConflicted(prevtx.m_confirm.hashBlock, prevtx.m_confirm.block_height, wtx.GetHash());
979             }
980         }
981     }
982     return true;
983 }
984 
AddToWalletIfInvolvingMe(const CTransactionRef & ptx,CWalletTx::Confirmation confirm,bool fUpdate)985 bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, CWalletTx::Confirmation confirm, bool fUpdate)
986 {
987     const CTransaction& tx = *ptx;
988     {
989         AssertLockHeld(cs_wallet);
990 
991         if (!confirm.hashBlock.IsNull()) {
992             for (const CTxIn& txin : tx.vin) {
993                 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout);
994                 while (range.first != range.second) {
995                     if (range.first->second != tx.GetHash()) {
996                         WalletLogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), confirm.hashBlock.ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
997                         MarkConflicted(confirm.hashBlock, confirm.block_height, range.first->second);
998                     }
999                     range.first++;
1000                 }
1001             }
1002         }
1003 
1004         bool fExisted = mapWallet.count(tx.GetHash()) != 0;
1005         if (fExisted && !fUpdate) return false;
1006         if (fExisted || IsMine(tx) || IsFromMe(tx))
1007         {
1008             /* Check if any keys in the wallet keypool that were supposed to be unused
1009              * have appeared in a new transaction. If so, remove those keys from the keypool.
1010              * This can happen when restoring an old wallet backup that does not contain
1011              * the mostly recently created transactions from newer versions of the wallet.
1012              */
1013 
1014             // loop though all outputs
1015             for (const CTxOut& txout: tx.vout) {
1016                 for (const auto& spk_man_pair : m_spk_managers) {
1017                     spk_man_pair.second->MarkUnusedAddresses(txout.scriptPubKey);
1018                 }
1019             }
1020 
1021             // Block disconnection override an abandoned tx as unconfirmed
1022             // which means user may have to call abandontransaction again
1023             return AddToWallet(MakeTransactionRef(tx), confirm, /* update_wtx= */ nullptr, /* fFlushOnClose= */ false);
1024         }
1025     }
1026     return false;
1027 }
1028 
TransactionCanBeAbandoned(const uint256 & hashTx) const1029 bool CWallet::TransactionCanBeAbandoned(const uint256& hashTx) const
1030 {
1031     LOCK(cs_wallet);
1032     const CWalletTx* wtx = GetWalletTx(hashTx);
1033     return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain() == 0 && !wtx->InMempool();
1034 }
1035 
MarkInputsDirty(const CTransactionRef & tx)1036 void CWallet::MarkInputsDirty(const CTransactionRef& tx)
1037 {
1038     for (const CTxIn& txin : tx->vin) {
1039         auto it = mapWallet.find(txin.prevout.hash);
1040         if (it != mapWallet.end()) {
1041             it->second.MarkDirty();
1042         }
1043     }
1044 }
1045 
AbandonTransaction(const uint256 & hashTx)1046 bool CWallet::AbandonTransaction(const uint256& hashTx)
1047 {
1048     LOCK(cs_wallet);
1049 
1050     WalletBatch batch(*database);
1051 
1052     std::set<uint256> todo;
1053     std::set<uint256> done;
1054 
1055     // Can't mark abandoned if confirmed or in mempool
1056     auto it = mapWallet.find(hashTx);
1057     assert(it != mapWallet.end());
1058     CWalletTx& origtx = it->second;
1059     if (origtx.GetDepthInMainChain() != 0 || origtx.InMempool()) {
1060         return false;
1061     }
1062 
1063     todo.insert(hashTx);
1064 
1065     while (!todo.empty()) {
1066         uint256 now = *todo.begin();
1067         todo.erase(now);
1068         done.insert(now);
1069         auto it = mapWallet.find(now);
1070         assert(it != mapWallet.end());
1071         CWalletTx& wtx = it->second;
1072         int currentconfirm = wtx.GetDepthInMainChain();
1073         // If the orig tx was not in block, none of its spends can be
1074         assert(currentconfirm <= 0);
1075         // if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon}
1076         if (currentconfirm == 0 && !wtx.isAbandoned()) {
1077             // If the orig tx was not in block/mempool, none of its spends can be in mempool
1078             assert(!wtx.InMempool());
1079             wtx.setAbandoned();
1080             wtx.MarkDirty();
1081             batch.WriteTx(wtx);
1082             NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED);
1083             // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
1084             TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
1085             while (iter != mapTxSpends.end() && iter->first.hash == now) {
1086                 if (!done.count(iter->second)) {
1087                     todo.insert(iter->second);
1088                 }
1089                 iter++;
1090             }
1091             // If a transaction changes 'conflicted' state, that changes the balance
1092             // available of the outputs it spends. So force those to be recomputed
1093             MarkInputsDirty(wtx.tx);
1094         }
1095     }
1096 
1097     return true;
1098 }
1099 
MarkConflicted(const uint256 & hashBlock,int conflicting_height,const uint256 & hashTx)1100 void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, const uint256& hashTx)
1101 {
1102     LOCK(cs_wallet);
1103 
1104     int conflictconfirms = (m_last_block_processed_height - conflicting_height + 1) * -1;
1105     // If number of conflict confirms cannot be determined, this means
1106     // that the block is still unknown or not yet part of the main chain,
1107     // for example when loading the wallet during a reindex. Do nothing in that
1108     // case.
1109     if (conflictconfirms >= 0)
1110         return;
1111 
1112     // Do not flush the wallet here for performance reasons
1113     WalletBatch batch(*database, false);
1114 
1115     std::set<uint256> todo;
1116     std::set<uint256> done;
1117 
1118     todo.insert(hashTx);
1119 
1120     while (!todo.empty()) {
1121         uint256 now = *todo.begin();
1122         todo.erase(now);
1123         done.insert(now);
1124         auto it = mapWallet.find(now);
1125         assert(it != mapWallet.end());
1126         CWalletTx& wtx = it->second;
1127         int currentconfirm = wtx.GetDepthInMainChain();
1128         if (conflictconfirms < currentconfirm) {
1129             // Block is 'more conflicted' than current confirm; update.
1130             // Mark transaction as conflicted with this block.
1131             wtx.m_confirm.nIndex = 0;
1132             wtx.m_confirm.hashBlock = hashBlock;
1133             wtx.m_confirm.block_height = conflicting_height;
1134             wtx.setConflicted();
1135             wtx.MarkDirty();
1136             batch.WriteTx(wtx);
1137             // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
1138             TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
1139             while (iter != mapTxSpends.end() && iter->first.hash == now) {
1140                  if (!done.count(iter->second)) {
1141                      todo.insert(iter->second);
1142                  }
1143                  iter++;
1144             }
1145             // If a transaction changes 'conflicted' state, that changes the balance
1146             // available of the outputs it spends. So force those to be recomputed
1147             MarkInputsDirty(wtx.tx);
1148         }
1149     }
1150 }
1151 
SyncTransaction(const CTransactionRef & ptx,CWalletTx::Confirmation confirm,bool update_tx)1152 void CWallet::SyncTransaction(const CTransactionRef& ptx, CWalletTx::Confirmation confirm, bool update_tx)
1153 {
1154     if (!AddToWalletIfInvolvingMe(ptx, confirm, update_tx))
1155         return; // Not one of ours
1156 
1157     // If a transaction changes 'conflicted' state, that changes the balance
1158     // available of the outputs it spends. So force those to be
1159     // recomputed, also:
1160     MarkInputsDirty(ptx);
1161 }
1162 
transactionAddedToMempool(const CTransactionRef & tx,uint64_t mempool_sequence)1163 void CWallet::transactionAddedToMempool(const CTransactionRef& tx, uint64_t mempool_sequence) {
1164     LOCK(cs_wallet);
1165     SyncTransaction(tx, {CWalletTx::Status::UNCONFIRMED, /* block height */ 0, /* block hash */ {}, /* index */ 0});
1166 
1167     auto it = mapWallet.find(tx->GetHash());
1168     if (it != mapWallet.end()) {
1169         it->second.fInMempool = true;
1170     }
1171 }
1172 
transactionRemovedFromMempool(const CTransactionRef & tx,MemPoolRemovalReason reason,uint64_t mempool_sequence)1173 void CWallet::transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {
1174     LOCK(cs_wallet);
1175     auto it = mapWallet.find(tx->GetHash());
1176     if (it != mapWallet.end()) {
1177         it->second.fInMempool = false;
1178     }
1179     // Handle transactions that were removed from the mempool because they
1180     // conflict with transactions in a newly connected block.
1181     if (reason == MemPoolRemovalReason::CONFLICT) {
1182         // Call SyncNotifications, so external -walletnotify notifications will
1183         // be triggered for these transactions. Set Status::UNCONFIRMED instead
1184         // of Status::CONFLICTED for a few reasons:
1185         //
1186         // 1. The transactionRemovedFromMempool callback does not currently
1187         //    provide the conflicting block's hash and height, and for backwards
1188         //    compatibility reasons it may not be not safe to store conflicted
1189         //    wallet transactions with a null block hash. See
1190         //    https://github.com/bitcoin/bitcoin/pull/18600#discussion_r420195993.
1191         // 2. For most of these transactions, the wallet's internal conflict
1192         //    detection in the blockConnected handler will subsequently call
1193         //    MarkConflicted and update them with CONFLICTED status anyway. This
1194         //    applies to any wallet transaction that has inputs spent in the
1195         //    block, or that has ancestors in the wallet with inputs spent by
1196         //    the block.
1197         // 3. Longstanding behavior since the sync implementation in
1198         //    https://github.com/bitcoin/bitcoin/pull/9371 and the prior sync
1199         //    implementation before that was to mark these transactions
1200         //    unconfirmed rather than conflicted.
1201         //
1202         // Nothing described above should be seen as an unchangeable requirement
1203         // when improving this code in the future. The wallet's heuristics for
1204         // distinguishing between conflicted and unconfirmed transactions are
1205         // imperfect, and could be improved in general, see
1206         // https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Wallet-Transaction-Conflict-Tracking
1207         SyncTransaction(tx, {CWalletTx::Status::UNCONFIRMED, /* block height */ 0, /* block hash */ {}, /* index */ 0});
1208     }
1209 }
1210 
blockConnected(const CBlock & block,int height)1211 void CWallet::blockConnected(const CBlock& block, int height)
1212 {
1213     const uint256& block_hash = block.GetHash();
1214     LOCK(cs_wallet);
1215 
1216     m_last_block_processed_height = height;
1217     m_last_block_processed = block_hash;
1218     for (size_t index = 0; index < block.vtx.size(); index++) {
1219         SyncTransaction(block.vtx[index], {CWalletTx::Status::CONFIRMED, height, block_hash, (int)index});
1220         transactionRemovedFromMempool(block.vtx[index], MemPoolRemovalReason::BLOCK, 0 /* mempool_sequence */);
1221     }
1222 }
1223 
blockDisconnected(const CBlock & block,int height)1224 void CWallet::blockDisconnected(const CBlock& block, int height)
1225 {
1226     LOCK(cs_wallet);
1227 
1228     // At block disconnection, this will change an abandoned transaction to
1229     // be unconfirmed, whether or not the transaction is added back to the mempool.
1230     // User may have to call abandontransaction again. It may be addressed in the
1231     // future with a stickier abandoned state or even removing abandontransaction call.
1232     m_last_block_processed_height = height - 1;
1233     m_last_block_processed = block.hashPrevBlock;
1234     for (const CTransactionRef& ptx : block.vtx) {
1235         SyncTransaction(ptx, {CWalletTx::Status::UNCONFIRMED, /* block height */ 0, /* block hash */ {}, /* index */ 0});
1236     }
1237 }
1238 
updatedBlockTip()1239 void CWallet::updatedBlockTip()
1240 {
1241     m_best_block_time = GetTime();
1242 }
1243 
1244 
BlockUntilSyncedToCurrentChain() const1245 void CWallet::BlockUntilSyncedToCurrentChain() const {
1246     AssertLockNotHeld(cs_wallet);
1247     // Skip the queue-draining stuff if we know we're caught up with
1248     // ::ChainActive().Tip(), otherwise put a callback in the validation interface queue and wait
1249     // for the queue to drain enough to execute it (indicating we are caught up
1250     // at least with the time we entered this function).
1251     uint256 last_block_hash = WITH_LOCK(cs_wallet, return m_last_block_processed);
1252     chain().waitForNotificationsIfTipChanged(last_block_hash);
1253 }
1254 
1255 
IsMine(const CTxIn & txin) const1256 isminetype CWallet::IsMine(const CTxIn &txin) const
1257 {
1258     AssertLockHeld(cs_wallet);
1259     std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1260     if (mi != mapWallet.end())
1261     {
1262         const CWalletTx& prev = (*mi).second;
1263         if (txin.prevout.n < prev.tx->vout.size())
1264             return IsMine(prev.tx->vout[txin.prevout.n]);
1265     }
1266     return ISMINE_NO;
1267 }
1268 
1269 // Note that this function doesn't distinguish between a 0-valued input,
1270 // and a not-"is mine" (according to the filter) input.
GetDebit(const CTxIn & txin,const isminefilter & filter) const1271 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
1272 {
1273     {
1274         LOCK(cs_wallet);
1275         std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1276         if (mi != mapWallet.end())
1277         {
1278             const CWalletTx& prev = (*mi).second;
1279             if (txin.prevout.n < prev.tx->vout.size())
1280             {
1281                 const CTxOut& prevout = prev.tx->vout[txin.prevout.n];
1282                 if (CNameScript::isNameScript(prevout.scriptPubKey))
1283                     return 0;
1284 
1285                 if (IsMine(prevout) & filter)
1286                     return prevout.nValue;
1287             }
1288         }
1289     }
1290     return 0;
1291 }
1292 
IsMine(const CTxOut & txout) const1293 isminetype CWallet::IsMine(const CTxOut& txout) const
1294 {
1295     AssertLockHeld(cs_wallet);
1296     return IsMine(txout.scriptPubKey);
1297 }
1298 
IsMine(const CTxDestination & dest) const1299 isminetype CWallet::IsMine(const CTxDestination& dest) const
1300 {
1301     AssertLockHeld(cs_wallet);
1302     return IsMine(GetScriptForDestination(dest));
1303 }
1304 
IsMine(const CScript & script) const1305 isminetype CWallet::IsMine(const CScript& script) const
1306 {
1307     AssertLockHeld(cs_wallet);
1308     isminetype result = ISMINE_NO;
1309     for (const auto& spk_man_pair : m_spk_managers) {
1310         result = std::max(result, spk_man_pair.second->IsMine(script));
1311     }
1312     return result;
1313 }
1314 
GetCredit(const CTxOut & txout,const isminefilter & filter) const1315 CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
1316 {
1317     if (!MoneyRange(txout.nValue))
1318         throw std::runtime_error(std::string(__func__) + ": value out of range");
1319     if (CNameScript::isNameScript (txout.scriptPubKey))
1320         return 0;
1321     LOCK(cs_wallet);
1322     return ((IsMine(txout) & filter) ? txout.nValue : 0);
1323 }
1324 
IsChange(const CTxOut & txout) const1325 bool CWallet::IsChange(const CTxOut& txout) const
1326 {
1327     return IsChange(txout.scriptPubKey);
1328 }
1329 
IsChange(const CScript & script) const1330 bool CWallet::IsChange(const CScript& script) const
1331 {
1332     // TODO: fix handling of 'change' outputs. The assumption is that any
1333     // payment to a script that is ours, but is not in the address book
1334     // is change. That assumption is likely to break when we implement multisignature
1335     // wallets that return change back into a multi-signature-protected address;
1336     // a better way of identifying which outputs are 'the send' and which are
1337     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
1338     // which output, if any, was change).
1339     AssertLockHeld(cs_wallet);
1340     if (IsMine(script))
1341     {
1342         CTxDestination address;
1343         if (!ExtractDestination(script, address))
1344             return true;
1345         if (!FindAddressBookEntry(address)) {
1346             return true;
1347         }
1348     }
1349     return false;
1350 }
1351 
GetChange(const CTxOut & txout) const1352 CAmount CWallet::GetChange(const CTxOut& txout) const
1353 {
1354     AssertLockHeld(cs_wallet);
1355     if (!MoneyRange(txout.nValue))
1356         throw std::runtime_error(std::string(__func__) + ": value out of range");
1357     return (IsChange(txout) ? txout.nValue : 0);
1358 }
1359 
IsMine(const CTransaction & tx) const1360 bool CWallet::IsMine(const CTransaction& tx) const
1361 {
1362     AssertLockHeld(cs_wallet);
1363     for (const CTxOut& txout : tx.vout)
1364         if (IsMine(txout))
1365             return true;
1366     return false;
1367 }
1368 
IsFromMe(const CTransaction & tx) const1369 bool CWallet::IsFromMe(const CTransaction& tx) const
1370 {
1371     return (GetDebit(tx, ISMINE_ALL) > 0);
1372 }
1373 
GetDebit(const CTransaction & tx,const isminefilter & filter) const1374 CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
1375 {
1376     CAmount nDebit = 0;
1377     for (const CTxIn& txin : tx.vin)
1378     {
1379         nDebit += GetDebit(txin, filter);
1380         if (!MoneyRange(nDebit))
1381             throw std::runtime_error(std::string(__func__) + ": value out of range");
1382     }
1383     return nDebit;
1384 }
1385 
IsAllFromMe(const CTransaction & tx,const isminefilter & filter) const1386 bool CWallet::IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const
1387 {
1388     LOCK(cs_wallet);
1389 
1390     for (const CTxIn& txin : tx.vin)
1391     {
1392         auto mi = mapWallet.find(txin.prevout.hash);
1393         if (mi == mapWallet.end())
1394             return false; // any unknown inputs can't be from us
1395 
1396         const CWalletTx& prev = (*mi).second;
1397 
1398         if (txin.prevout.n >= prev.tx->vout.size())
1399             return false; // invalid input!
1400 
1401         if (!(IsMine(prev.tx->vout[txin.prevout.n]) & filter))
1402             return false;
1403     }
1404     return true;
1405 }
1406 
GetCredit(const CTransaction & tx,const isminefilter & filter) const1407 CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
1408 {
1409     CAmount nCredit = 0;
1410     for (const CTxOut& txout : tx.vout)
1411     {
1412         nCredit += GetCredit(txout, filter);
1413         if (!MoneyRange(nCredit))
1414             throw std::runtime_error(std::string(__func__) + ": value out of range");
1415     }
1416     return nCredit;
1417 }
1418 
GetChange(const CTransaction & tx) const1419 CAmount CWallet::GetChange(const CTransaction& tx) const
1420 {
1421     LOCK(cs_wallet);
1422     CAmount nChange = 0;
1423     for (const CTxOut& txout : tx.vout)
1424     {
1425         nChange += GetChange(txout);
1426         if (!MoneyRange(nChange))
1427             throw std::runtime_error(std::string(__func__) + ": value out of range");
1428     }
1429     return nChange;
1430 }
1431 
IsHDEnabled() const1432 bool CWallet::IsHDEnabled() const
1433 {
1434     // All Active ScriptPubKeyMans must be HD for this to be true
1435     bool result = true;
1436     for (const auto& spk_man : GetActiveScriptPubKeyMans()) {
1437         result &= spk_man->IsHDEnabled();
1438     }
1439     return result;
1440 }
1441 
CanGetAddresses(bool internal) const1442 bool CWallet::CanGetAddresses(bool internal) const
1443 {
1444     LOCK(cs_wallet);
1445     if (m_spk_managers.empty()) return false;
1446     for (OutputType t : OUTPUT_TYPES) {
1447         auto spk_man = GetScriptPubKeyMan(t, internal);
1448         if (spk_man && spk_man->CanGetAddresses(internal)) {
1449             return true;
1450         }
1451     }
1452     return false;
1453 }
1454 
SetWalletFlag(uint64_t flags)1455 void CWallet::SetWalletFlag(uint64_t flags)
1456 {
1457     LOCK(cs_wallet);
1458     m_wallet_flags |= flags;
1459     if (!WalletBatch(*database).WriteWalletFlags(m_wallet_flags))
1460         throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1461 }
1462 
UnsetWalletFlag(uint64_t flag)1463 void CWallet::UnsetWalletFlag(uint64_t flag)
1464 {
1465     WalletBatch batch(*database);
1466     UnsetWalletFlagWithDB(batch, flag);
1467 }
1468 
UnsetWalletFlagWithDB(WalletBatch & batch,uint64_t flag)1469 void CWallet::UnsetWalletFlagWithDB(WalletBatch& batch, uint64_t flag)
1470 {
1471     LOCK(cs_wallet);
1472     m_wallet_flags &= ~flag;
1473     if (!batch.WriteWalletFlags(m_wallet_flags))
1474         throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1475 }
1476 
UnsetBlankWalletFlag(WalletBatch & batch)1477 void CWallet::UnsetBlankWalletFlag(WalletBatch& batch)
1478 {
1479     UnsetWalletFlagWithDB(batch, WALLET_FLAG_BLANK_WALLET);
1480 }
1481 
IsWalletFlagSet(uint64_t flag) const1482 bool CWallet::IsWalletFlagSet(uint64_t flag) const
1483 {
1484     return (m_wallet_flags & flag);
1485 }
1486 
LoadWalletFlags(uint64_t flags)1487 bool CWallet::LoadWalletFlags(uint64_t flags)
1488 {
1489     LOCK(cs_wallet);
1490     if (((flags & KNOWN_WALLET_FLAGS) >> 32) ^ (flags >> 32)) {
1491         // contains unknown non-tolerable wallet flags
1492         return false;
1493     }
1494     m_wallet_flags = flags;
1495 
1496     return true;
1497 }
1498 
AddWalletFlags(uint64_t flags)1499 bool CWallet::AddWalletFlags(uint64_t flags)
1500 {
1501     LOCK(cs_wallet);
1502     // We should never be writing unknown non-tolerable wallet flags
1503     assert(((flags & KNOWN_WALLET_FLAGS) >> 32) == (flags >> 32));
1504     if (!WalletBatch(*database).WriteWalletFlags(flags)) {
1505         throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1506     }
1507 
1508     return LoadWalletFlags(flags);
1509 }
1510 
GetTxTime() const1511 int64_t CWalletTx::GetTxTime() const
1512 {
1513     int64_t n = nTimeSmart;
1514     return n ? n : nTimeReceived;
1515 }
1516 
1517 // Helper for producing a max-sized low-S low-R signature (eg 71 bytes)
1518 // or a max-sized low-S signature (e.g. 72 bytes) if use_max_sig is true
DummySignInput(CTxIn & tx_in,const CTxOut & txout,bool use_max_sig) const1519 bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig) const
1520 {
1521     // Fill in dummy signatures for fee calculation.
1522     const CScript& scriptPubKey = txout.scriptPubKey;
1523     SignatureData sigdata;
1524 
1525     std::unique_ptr<SigningProvider> provider = GetSolvingProvider(scriptPubKey);
1526     if (!provider) {
1527         // We don't know about this scriptpbuKey;
1528         return false;
1529     }
1530 
1531     if (!ProduceSignature(*provider, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata)) {
1532         return false;
1533     }
1534     UpdateInput(tx_in, sigdata);
1535     return true;
1536 }
1537 
1538 // Helper for producing a bunch of max-sized low-S low-R signatures (eg 71 bytes)
DummySignTx(CMutableTransaction & txNew,const std::vector<CTxOut> & txouts,bool use_max_sig) const1539 bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, bool use_max_sig) const
1540 {
1541     // Fill in dummy signatures for fee calculation.
1542     int nIn = 0;
1543     for (const auto& txout : txouts)
1544     {
1545         if (!DummySignInput(txNew.vin[nIn], txout, use_max_sig)) {
1546             return false;
1547         }
1548 
1549         nIn++;
1550     }
1551     return true;
1552 }
1553 
ImportScripts(const std::set<CScript> scripts,int64_t timestamp)1554 bool CWallet::ImportScripts(const std::set<CScript> scripts, int64_t timestamp)
1555 {
1556     auto spk_man = GetLegacyScriptPubKeyMan();
1557     if (!spk_man) {
1558         return false;
1559     }
1560     LOCK(spk_man->cs_KeyStore);
1561     return spk_man->ImportScripts(scripts, timestamp);
1562 }
1563 
ImportPrivKeys(const std::map<CKeyID,CKey> & privkey_map,const int64_t timestamp)1564 bool CWallet::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1565 {
1566     auto spk_man = GetLegacyScriptPubKeyMan();
1567     if (!spk_man) {
1568         return false;
1569     }
1570     LOCK(spk_man->cs_KeyStore);
1571     return spk_man->ImportPrivKeys(privkey_map, timestamp);
1572 }
1573 
ImportPubKeys(const std::vector<CKeyID> & ordered_pubkeys,const std::map<CKeyID,CPubKey> & pubkey_map,const std::map<CKeyID,std::pair<CPubKey,KeyOriginInfo>> & key_origins,const bool add_keypool,const bool internal,const int64_t timestamp)1574 bool CWallet::ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp)
1575 {
1576     auto spk_man = GetLegacyScriptPubKeyMan();
1577     if (!spk_man) {
1578         return false;
1579     }
1580     LOCK(spk_man->cs_KeyStore);
1581     return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins, add_keypool, internal, timestamp);
1582 }
1583 
ImportScriptPubKeys(const std::string & label,const std::set<CScript> & script_pub_keys,const bool have_solving_data,const bool apply_label,const int64_t timestamp)1584 bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set<CScript>& script_pub_keys, const bool have_solving_data, const bool apply_label, const int64_t timestamp)
1585 {
1586     auto spk_man = GetLegacyScriptPubKeyMan();
1587     if (!spk_man) {
1588         return false;
1589     }
1590     LOCK(spk_man->cs_KeyStore);
1591     if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data, timestamp)) {
1592         return false;
1593     }
1594     if (apply_label) {
1595         WalletBatch batch(*database);
1596         for (const CScript& script : script_pub_keys) {
1597             CTxDestination dest;
1598             ExtractDestination(script, dest);
1599             if (IsValidDestination(dest)) {
1600                 SetAddressBookWithDB(batch, dest, label, "receive");
1601             }
1602         }
1603     }
1604     return true;
1605 }
1606 
CalculateMaximumSignedTxSize(const CTransaction & tx,const CWallet * wallet,bool use_max_sig)1607 int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
1608 {
1609     std::vector<CTxOut> txouts;
1610     for (const CTxIn& input : tx.vin) {
1611         const auto mi = wallet->mapWallet.find(input.prevout.hash);
1612         // Can not estimate size without knowing the input details
1613         if (mi == wallet->mapWallet.end()) {
1614             return -1;
1615         }
1616         assert(input.prevout.n < mi->second.tx->vout.size());
1617         txouts.emplace_back(mi->second.tx->vout[input.prevout.n]);
1618     }
1619     return CalculateMaximumSignedTxSize(tx, wallet, txouts, use_max_sig);
1620 }
1621 
1622 // txouts needs to be in the order of tx.vin
CalculateMaximumSignedTxSize(const CTransaction & tx,const CWallet * wallet,const std::vector<CTxOut> & txouts,bool use_max_sig)1623 int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, bool use_max_sig)
1624 {
1625     CMutableTransaction txNew(tx);
1626     if (!wallet->DummySignTx(txNew, txouts, use_max_sig)) {
1627         return -1;
1628     }
1629     return GetVirtualTransactionSize(CTransaction(txNew));
1630 }
1631 
CalculateMaximumSignedInputSize(const CTxOut & txout,const CWallet * wallet,bool use_max_sig)1632 int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* wallet, bool use_max_sig)
1633 {
1634     CMutableTransaction txn;
1635     txn.vin.push_back(CTxIn(COutPoint()));
1636     if (!wallet->DummySignInput(txn.vin[0], txout, use_max_sig)) {
1637         return -1;
1638     }
1639     return GetVirtualTransactionInputSize(txn.vin[0]);
1640 }
1641 
GetAmounts(std::list<COutputEntry> & listReceived,std::list<COutputEntry> & listSent,CAmount & nFee,const isminefilter & filter) const1642 void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
1643                            std::list<COutputEntry>& listSent, CAmount& nFee, const isminefilter& filter) const
1644 {
1645     nFee = 0;
1646     listReceived.clear();
1647     listSent.clear();
1648 
1649     // Compute fee:
1650     CAmount nDebit = GetDebit(filter);
1651     if (nDebit > 0) // debit>0 means we signed/sent this transaction
1652     {
1653         CAmount nValueOut = tx->GetValueOut(true);
1654         nFee = nDebit - nValueOut;
1655     }
1656 
1657     LOCK(pwallet->cs_wallet);
1658     // Sent/received.
1659     for (unsigned int i = 0; i < tx->vout.size(); ++i)
1660     {
1661         const CTxOut& txout = tx->vout[i];
1662         isminetype fIsMine = pwallet->IsMine(txout);
1663         const CNameScript nameOp(txout.scriptPubKey);
1664         // Only need to handle txouts if AT LEAST one of these is true:
1665         //   1) they debit from us (sent)
1666         //   2) the output is to us (received)
1667         if (nDebit > 0)
1668         {
1669             // Don't report 'change' txouts, but keep names in all cases
1670             if (pwallet->IsChange(txout) && !nameOp.isNameOp())
1671                 continue;
1672         }
1673         else if (!(fIsMine & filter))
1674             continue;
1675 
1676         // In either case, we need to get the destination address
1677         CTxDestination address;
1678 
1679         if (!ExtractDestination(txout.scriptPubKey, address) && !txout.scriptPubKey.IsUnspendable())
1680         {
1681             pwallet->WalletLogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
1682                                     this->GetHash().ToString());
1683             address = CNoDestination();
1684         }
1685 
1686         COutputEntry output = {address, "", txout.nValue, (int)i};
1687 
1688         // If we have a name script, set the "name" parameter.
1689         if (nameOp.isNameOp())
1690         {
1691             if (nameOp.isAnyUpdate())
1692                 output.nameOp = "update: " + EncodeNameForMessage(nameOp.getOpName());
1693             else
1694                 output.nameOp = "new: " + HexStr(nameOp.getOpHash());
1695             output.amount = 0;
1696         }
1697 
1698         // If we are debited by the transaction, add the output as a "sent" entry
1699         if (nDebit > 0)
1700             listSent.push_back(output);
1701 
1702         // If we are receiving the output, add it as a "received" entry
1703         // For names, only do this if we did not also add it as "sent"
1704         if ((fIsMine & filter)
1705             && (!nameOp.isNameOp() || !(nDebit > 0)))
1706             listReceived.push_back(output);
1707     }
1708 
1709 }
1710 
1711 /**
1712  * Scan active chain for relevant transactions after importing keys. This should
1713  * be called whenever new keys are added to the wallet, with the oldest key
1714  * creation time.
1715  *
1716  * @return Earliest timestamp that could be successfully scanned from. Timestamp
1717  * returned will be higher than startTime if relevant blocks could not be read.
1718  */
RescanFromTime(int64_t startTime,const WalletRescanReserver & reserver,bool update)1719 int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update)
1720 {
1721     // Find starting block. May be null if nCreateTime is greater than the
1722     // highest blockchain timestamp, in which case there is nothing that needs
1723     // to be scanned.
1724     int start_height = 0;
1725     uint256 start_block;
1726     bool start = chain().findFirstBlockWithTimeAndHeight(startTime - TIMESTAMP_WINDOW, 0, FoundBlock().hash(start_block).height(start_height));
1727     WalletLogPrintf("%s: Rescanning last %i blocks\n", __func__, start ? WITH_LOCK(cs_wallet, return GetLastBlockHeight()) - start_height + 1 : 0);
1728 
1729     if (start) {
1730         // TODO: this should take into account failure by ScanResult::USER_ABORT
1731         ScanResult result = ScanForWalletTransactions(start_block, start_height, {} /* max_height */, reserver, update);
1732         if (result.status == ScanResult::FAILURE) {
1733             int64_t time_max;
1734             CHECK_NONFATAL(chain().findBlock(result.last_failed_block, FoundBlock().maxTime(time_max)));
1735             return time_max + TIMESTAMP_WINDOW + 1;
1736         }
1737     }
1738     return startTime;
1739 }
1740 
1741 /**
1742  * Scan the block chain (starting in start_block) for transactions
1743  * from or to us. If fUpdate is true, found transactions that already
1744  * exist in the wallet will be updated.
1745  *
1746  * @param[in] start_block Scan starting block. If block is not on the active
1747  *                        chain, the scan will return SUCCESS immediately.
1748  * @param[in] start_height Height of start_block
1749  * @param[in] max_height  Optional max scanning height. If unset there is
1750  *                        no maximum and scanning can continue to the tip
1751  *
1752  * @return ScanResult returning scan information and indicating success or
1753  *         failure. Return status will be set to SUCCESS if scan was
1754  *         successful. FAILURE if a complete rescan was not possible (due to
1755  *         pruning or corruption). USER_ABORT if the rescan was aborted before
1756  *         it could complete.
1757  *
1758  * @pre Caller needs to make sure start_block (and the optional stop_block) are on
1759  * the main chain after to the addition of any new keys you want to detect
1760  * transactions for.
1761  */
ScanForWalletTransactions(const uint256 & start_block,int start_height,Optional<int> max_height,const WalletRescanReserver & reserver,bool fUpdate)1762 CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_block, int start_height, Optional<int> max_height, const WalletRescanReserver& reserver, bool fUpdate)
1763 {
1764     int64_t nNow = GetTime();
1765     int64_t start_time = GetTimeMillis();
1766 
1767     assert(reserver.isReserved());
1768 
1769     uint256 block_hash = start_block;
1770     ScanResult result;
1771 
1772     WalletLogPrintf("Rescan started from block %s...\n", start_block.ToString());
1773 
1774     fAbortRescan = false;
1775     ShowProgress(strprintf("%s " + _("Rescanning...").translated, GetDisplayName()), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
1776     uint256 tip_hash = WITH_LOCK(cs_wallet, return GetLastBlockHash());
1777     uint256 end_hash = tip_hash;
1778     if (max_height) chain().findAncestorByHeight(tip_hash, *max_height, FoundBlock().hash(end_hash));
1779     double progress_begin = chain().guessVerificationProgress(block_hash);
1780     double progress_end = chain().guessVerificationProgress(end_hash);
1781     double progress_current = progress_begin;
1782     int block_height = start_height;
1783     while (!fAbortRescan && !chain().shutdownRequested()) {
1784         if (progress_end - progress_begin > 0.0) {
1785             m_scanning_progress = (progress_current - progress_begin) / (progress_end - progress_begin);
1786         } else { // avoid divide-by-zero for single block scan range (i.e. start and stop hashes are equal)
1787             m_scanning_progress = 0;
1788         }
1789         if (block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
1790             ShowProgress(strprintf("%s " + _("Rescanning...").translated, GetDisplayName()), std::max(1, std::min(99, (int)(m_scanning_progress * 100))));
1791         }
1792         if (GetTime() >= nNow + 60) {
1793             nNow = GetTime();
1794             WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", block_height, progress_current);
1795         }
1796 
1797         CBlock block;
1798         bool next_block;
1799         uint256 next_block_hash;
1800         bool reorg = false;
1801         if (chain().findBlock(block_hash, FoundBlock().data(block)) && !block.IsNull()) {
1802             LOCK(cs_wallet);
1803             next_block = chain().findNextBlock(block_hash, block_height, FoundBlock().hash(next_block_hash), &reorg);
1804             if (reorg) {
1805                 // Abort scan if current block is no longer active, to prevent
1806                 // marking transactions as coming from the wrong block.
1807                 // TODO: This should return success instead of failure, see
1808                 // https://github.com/bitcoin/bitcoin/pull/14711#issuecomment-458342518
1809                 result.last_failed_block = block_hash;
1810                 result.status = ScanResult::FAILURE;
1811                 break;
1812             }
1813             for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
1814                 SyncTransaction(block.vtx[posInBlock], {CWalletTx::Status::CONFIRMED, block_height, block_hash, (int)posInBlock}, fUpdate);
1815             }
1816             // scan succeeded, record block as most recent successfully scanned
1817             result.last_scanned_block = block_hash;
1818             result.last_scanned_height = block_height;
1819         } else {
1820             // could not scan block, keep scanning but record this block as the most recent failure
1821             result.last_failed_block = block_hash;
1822             result.status = ScanResult::FAILURE;
1823             next_block = chain().findNextBlock(block_hash, block_height, FoundBlock().hash(next_block_hash), &reorg);
1824         }
1825         if (max_height && block_height >= *max_height) {
1826             break;
1827         }
1828         {
1829             if (!next_block || reorg) {
1830                 // break successfully when rescan has reached the tip, or
1831                 // previous block is no longer on the chain due to a reorg
1832                 break;
1833             }
1834 
1835             // increment block and verification progress
1836             block_hash = next_block_hash;
1837             ++block_height;
1838             progress_current = chain().guessVerificationProgress(block_hash);
1839 
1840             // handle updated tip hash
1841             const uint256 prev_tip_hash = tip_hash;
1842             tip_hash = WITH_LOCK(cs_wallet, return GetLastBlockHash());
1843             if (!max_height && prev_tip_hash != tip_hash) {
1844                 // in case the tip has changed, update progress max
1845                 progress_end = chain().guessVerificationProgress(tip_hash);
1846             }
1847         }
1848     }
1849     ShowProgress(strprintf("%s " + _("Rescanning...").translated, GetDisplayName()), 100); // hide progress dialog in GUI
1850     if (block_height && fAbortRescan) {
1851         WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", block_height, progress_current);
1852         result.status = ScanResult::USER_ABORT;
1853     } else if (block_height && chain().shutdownRequested()) {
1854         WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height, progress_current);
1855         result.status = ScanResult::USER_ABORT;
1856     } else {
1857         WalletLogPrintf("Rescan completed in %15dms\n", GetTimeMillis() - start_time);
1858     }
1859     return result;
1860 }
1861 
ReacceptWalletTransactions()1862 void CWallet::ReacceptWalletTransactions()
1863 {
1864     // If transactions aren't being broadcasted, don't let them into local mempool either
1865     if (!fBroadcastTransactions)
1866         return;
1867     std::map<int64_t, CWalletTx*> mapSorted;
1868 
1869     // Sort pending wallet transactions based on their initial wallet insertion order
1870     for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
1871         const uint256& wtxid = item.first;
1872         CWalletTx& wtx = item.second;
1873         assert(wtx.GetHash() == wtxid);
1874 
1875         int nDepth = wtx.GetDepthInMainChain();
1876 
1877         if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) {
1878             mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
1879         }
1880     }
1881 
1882     // Try to add wallet transactions to memory pool
1883     for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
1884         CWalletTx& wtx = *(item.second);
1885         std::string unused_err_string;
1886         wtx.SubmitMemoryPoolAndRelay(unused_err_string, false);
1887     }
1888 }
1889 
SubmitMemoryPoolAndRelay(std::string & err_string,bool relay)1890 bool CWalletTx::SubmitMemoryPoolAndRelay(std::string& err_string, bool relay)
1891 {
1892     // Can't relay if wallet is not broadcasting
1893     if (!pwallet->GetBroadcastTransactions()) return false;
1894     // Don't relay abandoned transactions
1895     if (isAbandoned()) return false;
1896     // Don't try to submit coinbase transactions. These would fail anyway but would
1897     // cause log spam.
1898     if (IsCoinBase()) return false;
1899     // Don't try to submit conflicted or confirmed transactions.
1900     if (GetDepthInMainChain() != 0) return false;
1901 
1902     // Submit transaction to mempool for relay
1903     pwallet->WalletLogPrintf("Submitting wtx %s to mempool for relay\n", GetHash().ToString());
1904     // We must set fInMempool here - while it will be re-set to true by the
1905     // entered-mempool callback, if we did not there would be a race where a
1906     // user could call sendmoney in a loop and hit spurious out of funds errors
1907     // because we think that this newly generated transaction's change is
1908     // unavailable as we're not yet aware that it is in the mempool.
1909     //
1910     // Irrespective of the failure reason, un-marking fInMempool
1911     // out-of-order is incorrect - it should be unmarked when
1912     // TransactionRemovedFromMempool fires.
1913     bool ret = pwallet->chain().broadcastTransaction(tx, pwallet->m_default_max_tx_fee, relay, err_string);
1914     fInMempool |= ret;
1915     return ret;
1916 }
1917 
GetConflicts() const1918 std::set<uint256> CWalletTx::GetConflicts() const
1919 {
1920     std::set<uint256> result;
1921     if (pwallet != nullptr)
1922     {
1923         uint256 myHash = GetHash();
1924         result = pwallet->GetConflicts(myHash);
1925         result.erase(myHash);
1926     }
1927     return result;
1928 }
1929 
GetCachableAmount(AmountType type,const isminefilter & filter,bool recalculate) const1930 CAmount CWalletTx::GetCachableAmount(AmountType type, const isminefilter& filter, bool recalculate) const
1931 {
1932     auto& amount = m_amounts[type];
1933     if (recalculate || !amount.m_cached[filter]) {
1934         amount.Set(filter, type == DEBIT ? pwallet->GetDebit(*tx, filter) : pwallet->GetCredit(*tx, filter));
1935         m_is_cache_empty = false;
1936     }
1937     return amount.m_value[filter];
1938 }
1939 
GetDebit(const isminefilter & filter) const1940 CAmount CWalletTx::GetDebit(const isminefilter& filter) const
1941 {
1942     if (tx->vin.empty())
1943         return 0;
1944 
1945     CAmount debit = 0;
1946     if (filter & ISMINE_SPENDABLE) {
1947         debit += GetCachableAmount(DEBIT, ISMINE_SPENDABLE);
1948     }
1949     if (filter & ISMINE_WATCH_ONLY) {
1950         debit += GetCachableAmount(DEBIT, ISMINE_WATCH_ONLY);
1951     }
1952     return debit;
1953 }
1954 
GetCredit(const isminefilter & filter) const1955 CAmount CWalletTx::GetCredit(const isminefilter& filter) const
1956 {
1957     // Must wait until coinbase is safely deep enough in the chain before valuing it
1958     if (IsImmatureCoinBase())
1959         return 0;
1960 
1961     CAmount credit = 0;
1962     if (filter & ISMINE_SPENDABLE) {
1963         // GetBalance can assume transactions in mapWallet won't change
1964         credit += GetCachableAmount(CREDIT, ISMINE_SPENDABLE);
1965     }
1966     if (filter & ISMINE_WATCH_ONLY) {
1967         credit += GetCachableAmount(CREDIT, ISMINE_WATCH_ONLY);
1968     }
1969     return credit;
1970 }
1971 
GetImmatureCredit(bool fUseCache) const1972 CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
1973 {
1974     if (IsImmatureCoinBase() && IsInMainChain()) {
1975         return GetCachableAmount(IMMATURE_CREDIT, ISMINE_SPENDABLE, !fUseCache);
1976     }
1977 
1978     return 0;
1979 }
1980 
GetAvailableCredit(bool fUseCache,const isminefilter & filter) const1981 CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter) const
1982 {
1983     if (pwallet == nullptr)
1984         return 0;
1985 
1986     // Avoid caching ismine for NO or ALL cases (could remove this check and simplify in the future).
1987     bool allow_cache = (filter & ISMINE_ALL) && (filter & ISMINE_ALL) != ISMINE_ALL;
1988 
1989     // Must wait until coinbase is safely deep enough in the chain before valuing it
1990     if (IsImmatureCoinBase())
1991         return 0;
1992 
1993     if (fUseCache && allow_cache && m_amounts[AVAILABLE_CREDIT].m_cached[filter]) {
1994         return m_amounts[AVAILABLE_CREDIT].m_value[filter];
1995     }
1996 
1997     bool allow_used_addresses = (filter & ISMINE_USED) || !pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
1998     CAmount nCredit = 0;
1999     uint256 hashTx = GetHash();
2000     for (unsigned int i = 0; i < tx->vout.size(); i++)
2001     {
2002         if (!pwallet->IsSpent(hashTx, i) && (allow_used_addresses || !pwallet->IsSpentKey(hashTx, i))) {
2003             const CTxOut &txout = tx->vout[i];
2004             nCredit += pwallet->GetCredit(txout, filter);
2005             if (!MoneyRange(nCredit))
2006                 throw std::runtime_error(std::string(__func__) + " : value out of range");
2007         }
2008     }
2009 
2010     if (allow_cache) {
2011         m_amounts[AVAILABLE_CREDIT].Set(filter, nCredit);
2012         m_is_cache_empty = false;
2013     }
2014 
2015     return nCredit;
2016 }
2017 
GetImmatureWatchOnlyCredit(const bool fUseCache) const2018 CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool fUseCache) const
2019 {
2020     if (IsImmatureCoinBase() && IsInMainChain()) {
2021         return GetCachableAmount(IMMATURE_CREDIT, ISMINE_WATCH_ONLY, !fUseCache);
2022     }
2023 
2024     return 0;
2025 }
2026 
GetChange() const2027 CAmount CWalletTx::GetChange() const
2028 {
2029     if (fChangeCached)
2030         return nChangeCached;
2031     nChangeCached = pwallet->GetChange(*tx);
2032     fChangeCached = true;
2033     return nChangeCached;
2034 }
2035 
InMempool() const2036 bool CWalletTx::InMempool() const
2037 {
2038     return fInMempool;
2039 }
2040 
IsTrusted() const2041 bool CWalletTx::IsTrusted() const
2042 {
2043     std::set<uint256> trusted_parents;
2044     LOCK(pwallet->cs_wallet);
2045     return pwallet->IsTrusted(*this, trusted_parents);
2046 }
2047 
IsTrusted(const CWalletTx & wtx,std::set<uint256> & trusted_parents) const2048 bool CWallet::IsTrusted(const CWalletTx& wtx, std::set<uint256>& trusted_parents) const
2049 {
2050     AssertLockHeld(cs_wallet);
2051     // Quick answer in most cases
2052     if (!chain().checkFinalTx(*wtx.tx)) return false;
2053     int nDepth = wtx.GetDepthInMainChain();
2054     if (nDepth >= 1) return true;
2055     if (nDepth < 0) return false;
2056     // using wtx's cached debit
2057     if (!m_spend_zero_conf_change || !wtx.IsFromMe(ISMINE_ALL)) return false;
2058 
2059     // Don't trust unconfirmed transactions from us unless they are in the mempool.
2060     if (!wtx.InMempool()) return false;
2061 
2062     // Trusted if all inputs are from us and are in the mempool:
2063     for (const CTxIn& txin : wtx.tx->vin)
2064     {
2065         // Transactions not sent by us: not trusted
2066         const CWalletTx* parent = GetWalletTx(txin.prevout.hash);
2067         if (parent == nullptr) return false;
2068         const CTxOut& parentOut = parent->tx->vout[txin.prevout.n];
2069         // Check that this specific input being spent is trusted
2070         if (IsMine(parentOut) != ISMINE_SPENDABLE) return false;
2071         // If we've already trusted this parent, continue
2072         if (trusted_parents.count(parent->GetHash())) continue;
2073         // Recurse to check that the parent is also trusted
2074         if (!IsTrusted(*parent, trusted_parents)) return false;
2075         trusted_parents.insert(parent->GetHash());
2076     }
2077     return true;
2078 }
2079 
IsEquivalentTo(const CWalletTx & _tx) const2080 bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
2081 {
2082         CMutableTransaction tx1 {*this->tx};
2083         CMutableTransaction tx2 {*_tx.tx};
2084         for (auto& txin : tx1.vin) txin.scriptSig = CScript();
2085         for (auto& txin : tx2.vin) txin.scriptSig = CScript();
2086         return CTransaction(tx1) == CTransaction(tx2);
2087 }
2088 
2089 // Rebroadcast transactions from the wallet. We do this on a random timer
2090 // to slightly obfuscate which transactions come from our wallet.
2091 //
2092 // Ideally, we'd only resend transactions that we think should have been
2093 // mined in the most recent block. Any transaction that wasn't in the top
2094 // blockweight of transactions in the mempool shouldn't have been mined,
2095 // and so is probably just sitting in the mempool waiting to be confirmed.
2096 // Rebroadcasting does nothing to speed up confirmation and only damages
2097 // privacy.
ResendWalletTransactions()2098 void CWallet::ResendWalletTransactions()
2099 {
2100     // During reindex, importing and IBD, old wallet transactions become
2101     // unconfirmed. Don't resend them as that would spam other nodes.
2102     if (!chain().isReadyToBroadcast()) return;
2103 
2104     // Do this infrequently and randomly to avoid giving away
2105     // that these are our transactions.
2106     if (GetTime() < nNextResend || !fBroadcastTransactions) return;
2107     bool fFirst = (nNextResend == 0);
2108     // resend 12-36 hours from now, ~1 day on average.
2109     nNextResend = GetTime() + (12 * 60 * 60) + GetRand(24 * 60 * 60);
2110     if (fFirst) return;
2111 
2112     int submitted_tx_count = 0;
2113 
2114     { // cs_wallet scope
2115         LOCK(cs_wallet);
2116 
2117         // Relay transactions
2118         for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
2119             CWalletTx& wtx = item.second;
2120             // Attempt to rebroadcast all txes more than 5 minutes older than
2121             // the last block. SubmitMemoryPoolAndRelay() will not rebroadcast
2122             // any confirmed or conflicting txs.
2123             if (wtx.nTimeReceived > m_best_block_time - 5 * 60) continue;
2124             std::string unused_err_string;
2125             if (wtx.SubmitMemoryPoolAndRelay(unused_err_string, true)) ++submitted_tx_count;
2126         }
2127     } // cs_wallet
2128 
2129     if (submitted_tx_count > 0) {
2130         WalletLogPrintf("%s: resubmit %u unconfirmed transactions\n", __func__, submitted_tx_count);
2131     }
2132 }
2133 
2134 /** @} */ // end of mapWallet
2135 
MaybeResendWalletTxs()2136 void MaybeResendWalletTxs()
2137 {
2138     for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
2139         pwallet->ResendWalletTransactions();
2140     }
2141 }
2142 
2143 
2144 /** @defgroup Actions
2145  *
2146  * @{
2147  */
2148 
2149 
GetBalance(const int min_depth,bool avoid_reuse) const2150 CWallet::Balance CWallet::GetBalance(const int min_depth, bool avoid_reuse) const
2151 {
2152     Balance ret;
2153     isminefilter reuse_filter = avoid_reuse ? ISMINE_NO : ISMINE_USED;
2154     {
2155         LOCK(cs_wallet);
2156         std::set<uint256> trusted_parents;
2157         for (const auto& entry : mapWallet)
2158         {
2159             const CWalletTx& wtx = entry.second;
2160             const bool is_trusted{IsTrusted(wtx, trusted_parents)};
2161             const int tx_depth{wtx.GetDepthInMainChain()};
2162             const CAmount tx_credit_mine{wtx.GetAvailableCredit(/* fUseCache */ true, ISMINE_SPENDABLE | reuse_filter)};
2163             const CAmount tx_credit_watchonly{wtx.GetAvailableCredit(/* fUseCache */ true, ISMINE_WATCH_ONLY | reuse_filter)};
2164             if (is_trusted && tx_depth >= min_depth) {
2165                 ret.m_mine_trusted += tx_credit_mine;
2166                 ret.m_watchonly_trusted += tx_credit_watchonly;
2167             }
2168             if (!is_trusted && tx_depth == 0 && wtx.InMempool()) {
2169                 ret.m_mine_untrusted_pending += tx_credit_mine;
2170                 ret.m_watchonly_untrusted_pending += tx_credit_watchonly;
2171             }
2172             ret.m_mine_immature += wtx.GetImmatureCredit();
2173             ret.m_watchonly_immature += wtx.GetImmatureWatchOnlyCredit();
2174         }
2175     }
2176     return ret;
2177 }
2178 
GetAvailableBalance(const CCoinControl * coinControl) const2179 CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const
2180 {
2181     LOCK(cs_wallet);
2182 
2183     CAmount balance = 0;
2184     std::vector<COutput> vCoins;
2185     AvailableCoins(vCoins, true, coinControl);
2186     for (const COutput& out : vCoins) {
2187         if (out.fSpendable) {
2188             balance += out.tx->tx->vout[out.i].nValue;
2189         }
2190     }
2191     return balance;
2192 }
2193 
AvailableCoins(std::vector<COutput> & vCoins,bool fOnlySafe,const CCoinControl * coinControl,const CAmount & nMinimumAmount,const CAmount & nMaximumAmount,const CAmount & nMinimumSumAmount,const uint64_t nMaximumCount) const2194 void CWallet::AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe, const CCoinControl* coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount) const
2195 {
2196     AssertLockHeld(cs_wallet);
2197 
2198     vCoins.clear();
2199     CAmount nTotal = 0;
2200     // Either the WALLET_FLAG_AVOID_REUSE flag is not set (in which case we always allow), or we default to avoiding, and only in the case where
2201     // a coin control object is provided, and has the avoid address reuse flag set to false, do we allow already used addresses
2202     bool allow_used_addresses = !IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE) || (coinControl && !coinControl->m_avoid_address_reuse);
2203     const int min_depth = {coinControl ? coinControl->m_min_depth : DEFAULT_MIN_DEPTH};
2204     const int max_depth = {coinControl ? coinControl->m_max_depth : DEFAULT_MAX_DEPTH};
2205 
2206     std::set<uint256> trusted_parents;
2207     for (const auto& entry : mapWallet)
2208     {
2209         const uint256& wtxid = entry.first;
2210         const CWalletTx& wtx = entry.second;
2211 
2212         if (!chain().checkFinalTx(*wtx.tx)) {
2213             continue;
2214         }
2215 
2216         if (wtx.IsImmatureCoinBase())
2217             continue;
2218 
2219         int nDepth = wtx.GetDepthInMainChain();
2220         if (nDepth < 0)
2221             continue;
2222 
2223         // We should not consider coins which aren't at least in our mempool
2224         // It's possible for these to be conflicted via ancestors which we may never be able to detect
2225         if (nDepth == 0 && !wtx.InMempool())
2226             continue;
2227 
2228         bool safeTx = IsTrusted(wtx, trusted_parents);
2229 
2230         // We should not consider coins from transactions that are replacing
2231         // other transactions.
2232         //
2233         // Example: There is a transaction A which is replaced by bumpfee
2234         // transaction B. In this case, we want to prevent creation of
2235         // a transaction B' which spends an output of B.
2236         //
2237         // Reason: If transaction A were initially confirmed, transactions B
2238         // and B' would no longer be valid, so the user would have to create
2239         // a new transaction C to replace B'. However, in the case of a
2240         // one-block reorg, transactions B' and C might BOTH be accepted,
2241         // when the user only wanted one of them. Specifically, there could
2242         // be a 1-block reorg away from the chain where transactions A and C
2243         // were accepted to another chain where B, B', and C were all
2244         // accepted.
2245         if (nDepth == 0 && wtx.mapValue.count("replaces_txid")) {
2246             safeTx = false;
2247         }
2248 
2249         // Similarly, we should not consider coins from transactions that
2250         // have been replaced. In the example above, we would want to prevent
2251         // creation of a transaction A' spending an output of A, because if
2252         // transaction B were initially confirmed, conflicting with A and
2253         // A', we wouldn't want to the user to create a transaction D
2254         // intending to replace A', but potentially resulting in a scenario
2255         // where A, A', and D could all be accepted (instead of just B and
2256         // D, or just A and A' like the user would want).
2257         if (nDepth == 0 && wtx.mapValue.count("replaced_by_txid")) {
2258             safeTx = false;
2259         }
2260 
2261         if (fOnlySafe && !safeTx) {
2262             continue;
2263         }
2264 
2265         if (nDepth < min_depth || nDepth > max_depth) {
2266             continue;
2267         }
2268 
2269         for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
2270             // Only consider selected coins if add_inputs is false
2271             if (coinControl && !coinControl->m_add_inputs && !coinControl->IsSelected(COutPoint(entry.first, i))) {
2272                 continue;
2273             }
2274 
2275             if (wtx.tx->vout[i].nValue < nMinimumAmount || wtx.tx->vout[i].nValue > nMaximumAmount)
2276                 continue;
2277 
2278             if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsSelected(COutPoint(entry.first, i)))
2279                 continue;
2280 
2281             if (IsLockedCoin(entry.first, i))
2282                 continue;
2283 
2284             if (IsSpent(wtxid, i))
2285                 continue;
2286 
2287             isminetype mine = IsMine(wtx.tx->vout[i]);
2288 
2289             if (mine == ISMINE_NO) {
2290                 continue;
2291             }
2292 
2293             if (!allow_used_addresses && IsSpentKey(wtxid, i)) {
2294                 continue;
2295             }
2296 
2297             std::unique_ptr<SigningProvider> provider = GetSolvingProvider(wtx.tx->vout[i].scriptPubKey);
2298 
2299             bool solvable = provider ? IsSolvable(*provider, wtx.tx->vout[i].scriptPubKey) : false;
2300             bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
2301             if (CNameScript::isNameScript(wtx.tx->vout[i].scriptPubKey))
2302                 spendable = false;
2303 
2304             vCoins.push_back(COutput(&wtx, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly)));
2305 
2306             // Checks the sum amount of all UTXO's.
2307             if (nMinimumSumAmount != MAX_MONEY) {
2308                 nTotal += wtx.tx->vout[i].nValue;
2309 
2310                 if (nTotal >= nMinimumSumAmount) {
2311                     return;
2312                 }
2313             }
2314 
2315             // Checks the maximum number of UTXO's.
2316             if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) {
2317                 return;
2318             }
2319         }
2320     }
2321 }
2322 
ListCoins() const2323 std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins() const
2324 {
2325     AssertLockHeld(cs_wallet);
2326 
2327     std::map<CTxDestination, std::vector<COutput>> result;
2328     std::vector<COutput> availableCoins;
2329 
2330     AvailableCoins(availableCoins);
2331 
2332     for (const COutput& coin : availableCoins) {
2333         CTxDestination address;
2334         if ((coin.fSpendable || (IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && coin.fSolvable)) &&
2335             ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
2336             result[address].emplace_back(std::move(coin));
2337         }
2338     }
2339 
2340     std::vector<COutPoint> lockedCoins;
2341     ListLockedCoins(lockedCoins);
2342     // Include watch-only for LegacyScriptPubKeyMan wallets without private keys
2343     const bool include_watch_only = GetLegacyScriptPubKeyMan() && IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
2344     const isminetype is_mine_filter = include_watch_only ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE;
2345     for (const COutPoint& output : lockedCoins) {
2346         auto it = mapWallet.find(output.hash);
2347         if (it != mapWallet.end()) {
2348             int depth = it->second.GetDepthInMainChain();
2349             if (depth >= 0 && output.n < it->second.tx->vout.size() &&
2350                 IsMine(it->second.tx->vout[output.n]) == is_mine_filter
2351             ) {
2352                 CTxDestination address;
2353                 if (ExtractDestination(FindNonChangeParentOutput(*it->second.tx, output.n).scriptPubKey, address)) {
2354                     result[address].emplace_back(
2355                         &it->second, output.n, depth, true /* spendable */, true /* solvable */, false /* safe */);
2356                 }
2357             }
2358         }
2359     }
2360 
2361     return result;
2362 }
2363 
FindNonChangeParentOutput(const CTransaction & tx,int output) const2364 const CTxOut& CWallet::FindNonChangeParentOutput(const CTransaction& tx, int output) const
2365 {
2366     AssertLockHeld(cs_wallet);
2367     const CTransaction* ptx = &tx;
2368     int n = output;
2369     while (IsChange(ptx->vout[n]) && ptx->vin.size() > 0) {
2370         const COutPoint& prevout = ptx->vin[0].prevout;
2371         auto it = mapWallet.find(prevout.hash);
2372         if (it == mapWallet.end() || it->second.tx->vout.size() <= prevout.n ||
2373             !IsMine(it->second.tx->vout[prevout.n])) {
2374             break;
2375         }
2376         ptx = it->second.tx.get();
2377         n = prevout.n;
2378     }
2379     return ptx->vout[n];
2380 }
2381 
SelectCoinsMinConf(const CAmount & nTargetValue,const CoinEligibilityFilter & eligibility_filter,std::vector<OutputGroup> groups,std::set<CInputCoin> & setCoinsRet,CAmount & nValueRet,const CoinSelectionParams & coin_selection_params,bool & bnb_used) const2382 bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, std::vector<OutputGroup> groups,
2383                                  std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CoinSelectionParams& coin_selection_params, bool& bnb_used) const
2384 {
2385     setCoinsRet.clear();
2386     nValueRet = 0;
2387 
2388     std::vector<OutputGroup> utxo_pool;
2389     if (coin_selection_params.use_bnb) {
2390         // Get long term estimate
2391         FeeCalculation feeCalc;
2392         CCoinControl temp;
2393         temp.m_confirm_target = 1008;
2394         CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, &feeCalc);
2395 
2396         // Calculate cost of change
2397         CAmount cost_of_change = GetDiscardRate(*this).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size);
2398 
2399         // Filter by the min conf specs and add to utxo_pool and calculate effective value
2400         for (OutputGroup& group : groups) {
2401             if (!group.EligibleForSpending(eligibility_filter)) continue;
2402 
2403             if (coin_selection_params.m_subtract_fee_outputs) {
2404                 // Set the effective feerate to 0 as we don't want to use the effective value since the fees will be deducted from the output
2405                 group.SetFees(CFeeRate(0) /* effective_feerate */, long_term_feerate);
2406             } else {
2407                 group.SetFees(coin_selection_params.effective_fee, long_term_feerate);
2408             }
2409 
2410             OutputGroup pos_group = group.GetPositiveOnlyGroup();
2411             if (pos_group.effective_value > 0) utxo_pool.push_back(pos_group);
2412         }
2413         // Calculate the fees for things that aren't inputs
2414         CAmount not_input_fees = coin_selection_params.effective_fee.GetFee(coin_selection_params.tx_noinputs_size);
2415         bnb_used = true;
2416         return SelectCoinsBnB(utxo_pool, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
2417     } else {
2418         // Filter by the min conf specs and add to utxo_pool
2419         for (const OutputGroup& group : groups) {
2420             if (!group.EligibleForSpending(eligibility_filter)) continue;
2421             utxo_pool.push_back(group);
2422         }
2423         bnb_used = false;
2424         return KnapsackSolver(nTargetValue, utxo_pool, setCoinsRet, nValueRet);
2425     }
2426 }
2427 
SelectCoins(const std::vector<COutput> & vAvailableCoins,const CAmount & nTargetValue,std::set<CInputCoin> & setCoinsRet,CAmount & nValueRet,const CCoinControl & coin_control,CoinSelectionParams & coin_selection_params,bool & bnb_used) const2428 bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl& coin_control, CoinSelectionParams& coin_selection_params, bool& bnb_used) const
2429 {
2430     std::vector<COutput> vCoins(vAvailableCoins);
2431     CAmount value_to_select = nTargetValue;
2432 
2433     // Default to bnb was not used. If we use it, we set it later
2434     bnb_used = false;
2435 
2436     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
2437     if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs)
2438     {
2439         for (const COutput& out : vCoins)
2440         {
2441             if (!out.fSpendable)
2442                  continue;
2443             nValueRet += out.tx->tx->vout[out.i].nValue;
2444             setCoinsRet.insert(out.GetInputCoin());
2445         }
2446         return (nValueRet >= nTargetValue);
2447     }
2448 
2449     // calculate value from preset inputs and store them
2450     std::set<CInputCoin> setPresetCoins;
2451     CAmount nValueFromPresetInputs = 0;
2452 
2453     std::vector<COutPoint> vPresetInputs;
2454     coin_control.ListSelected(vPresetInputs);
2455     for (const COutPoint& outpoint : vPresetInputs)
2456     {
2457         std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
2458         if (it != mapWallet.end())
2459         {
2460             const CWalletTx& wtx = it->second;
2461             // Clearly invalid input, fail
2462             if (wtx.tx->vout.size() <= outpoint.n) {
2463                 return false;
2464             }
2465             // Just to calculate the marginal byte size
2466             CInputCoin coin(wtx.tx, outpoint.n, wtx.GetSpendSize(outpoint.n, false));
2467             nValueFromPresetInputs += coin.txout.nValue;
2468             if (coin.m_input_bytes <= 0) {
2469                 return false; // Not solvable, can't estimate size for fee
2470             }
2471             coin.effective_value = coin.txout.nValue - coin_selection_params.effective_fee.GetFee(coin.m_input_bytes);
2472             if (coin_selection_params.use_bnb) {
2473                 value_to_select -= coin.effective_value;
2474             } else {
2475                 value_to_select -= coin.txout.nValue;
2476             }
2477             setPresetCoins.insert(coin);
2478         } else {
2479             return false; // TODO: Allow non-wallet inputs
2480         }
2481     }
2482 
2483     // remove preset inputs from vCoins
2484     for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();)
2485     {
2486         if (setPresetCoins.count(it->GetInputCoin()))
2487             it = vCoins.erase(it);
2488         else
2489             ++it;
2490     }
2491 
2492     unsigned int limit_ancestor_count = 0;
2493     unsigned int limit_descendant_count = 0;
2494     chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
2495     size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
2496     size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
2497     bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS);
2498 
2499     // form groups from remaining coins; note that preset coins will not
2500     // automatically have their associated (same address) coins included
2501     if (coin_control.m_avoid_partial_spends && vCoins.size() > OUTPUT_GROUP_MAX_ENTRIES) {
2502         // Cases where we have 11+ outputs all pointing to the same destination may result in
2503         // privacy leaks as they will potentially be deterministically sorted. We solve that by
2504         // explicitly shuffling the outputs before processing
2505         Shuffle(vCoins.begin(), vCoins.end(), FastRandomContext());
2506     }
2507     std::vector<OutputGroup> groups = GroupOutputs(vCoins, !coin_control.m_avoid_partial_spends, max_ancestors);
2508 
2509     bool res = value_to_select <= 0 ||
2510         SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(1, 6, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2511         SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(1, 1, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2512         (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, 2), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2513         (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, std::min((size_t)4, max_ancestors/3), std::min((size_t)4, max_descendants/3)), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2514         (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2515         (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2516         (m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf(value_to_select, CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
2517 
2518     // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2519     util::insert(setCoinsRet, setPresetCoins);
2520 
2521     // add preset inputs to the total value selected
2522     nValueRet += nValueFromPresetInputs;
2523 
2524     return res;
2525 }
2526 
SignTransaction(CMutableTransaction & tx) const2527 bool CWallet::SignTransaction(CMutableTransaction& tx) const
2528 {
2529     AssertLockHeld(cs_wallet);
2530 
2531     // Build coins map
2532     std::map<COutPoint, Coin> coins;
2533     for (auto& input : tx.vin) {
2534         std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
2535         if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
2536             return false;
2537         }
2538         const CWalletTx& wtx = mi->second;
2539         coins[input.prevout] = Coin(wtx.tx->vout[input.prevout.n], wtx.m_confirm.block_height, wtx.IsCoinBase());
2540     }
2541     std::map<int, std::string> input_errors;
2542     return SignTransaction(tx, coins, SIGHASH_ALL, input_errors);
2543 }
2544 
SignTransaction(CMutableTransaction & tx,const std::map<COutPoint,Coin> & coins,int sighash,std::map<int,std::string> & input_errors) const2545 bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, std::string>& input_errors) const
2546 {
2547     // Try to sign with all ScriptPubKeyMans
2548     for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) {
2549         // spk_man->SignTransaction will return true if the transaction is complete,
2550         // so we can exit early and return true if that happens
2551         if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2552             return true;
2553         }
2554     }
2555 
2556     // At this point, one input was not fully signed otherwise we would have exited already
2557     return false;
2558 }
2559 
FillPSBT(PartiallySignedTransaction & psbtx,bool & complete,int sighash_type,bool sign,bool bip32derivs,size_t * n_signed) const2560 TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs, size_t * n_signed) const
2561 {
2562     if (n_signed) {
2563         *n_signed = 0;
2564     }
2565     LOCK(cs_wallet);
2566     // Get all of the previous transactions
2567     for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
2568         const CTxIn& txin = psbtx.tx->vin[i];
2569         PSBTInput& input = psbtx.inputs.at(i);
2570 
2571         if (PSBTInputSigned(input)) {
2572             continue;
2573         }
2574 
2575         // If we have no utxo, grab it from the wallet.
2576         if (!input.non_witness_utxo) {
2577             const uint256& txhash = txin.prevout.hash;
2578             const auto it = mapWallet.find(txhash);
2579             if (it != mapWallet.end()) {
2580                 const CWalletTx& wtx = it->second;
2581                 // We only need the non_witness_utxo, which is a superset of the witness_utxo.
2582                 //   The signing code will switch to the smaller witness_utxo if this is ok.
2583                 input.non_witness_utxo = wtx.tx;
2584             }
2585         }
2586     }
2587 
2588     // Fill in information from ScriptPubKeyMans
2589     for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) {
2590         int n_signed_this_spkm = 0;
2591         TransactionError res = spk_man->FillPSBT(psbtx, sighash_type, sign, bip32derivs, &n_signed_this_spkm);
2592         if (res != TransactionError::OK) {
2593             return res;
2594         }
2595 
2596         if (n_signed) {
2597             (*n_signed) += n_signed_this_spkm;
2598         }
2599     }
2600 
2601     // Complete if every input is now signed
2602     complete = true;
2603     for (const auto& input : psbtx.inputs) {
2604         complete &= PSBTInputSigned(input);
2605     }
2606 
2607     return TransactionError::OK;
2608 }
2609 
SignMessage(const std::string & message,const PKHash & pkhash,std::string & str_sig) const2610 SigningResult CWallet::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
2611 {
2612     SignatureData sigdata;
2613     CScript script_pub_key = GetScriptForDestination(pkhash);
2614     for (const auto& spk_man_pair : m_spk_managers) {
2615         if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
2616             return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
2617         }
2618     }
2619     return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
2620 }
2621 
FundTransaction(CMutableTransaction & tx,CAmount & nFeeRet,int & nChangePosInOut,bilingual_str & error,bool lockUnspents,const std::set<int> & setSubtractFeeFromOutputs,CCoinControl coinControl)2622 bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, bilingual_str& error, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl)
2623 {
2624     std::vector<CRecipient> vecSend;
2625 
2626     // Turn the txout set into a CRecipient vector.
2627     for (size_t idx = 0; idx < tx.vout.size(); idx++) {
2628         const CTxOut& txOut = tx.vout[idx];
2629         CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, setSubtractFeeFromOutputs.count(idx) == 1};
2630         vecSend.push_back(recipient);
2631     }
2632 
2633     coinControl.fAllowOtherInputs = true;
2634 
2635     for (const CTxIn& txin : tx.vin) {
2636         coinControl.Select(txin.prevout);
2637     }
2638 
2639     // Acquire the locks to prevent races to the new locked unspents between the
2640     // CreateTransaction call and LockCoin calls (when lockUnspents is true).
2641     LOCK(cs_wallet);
2642 
2643     CTransactionRef tx_new;
2644     FeeCalculation fee_calc_out;
2645     if (!CreateTransaction(vecSend, nullptr, tx_new, nFeeRet, nChangePosInOut, error, coinControl, fee_calc_out, false)) {
2646         return false;
2647     }
2648 
2649     if (nChangePosInOut != -1) {
2650         tx.vout.insert(tx.vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
2651     }
2652 
2653     // Copy output sizes from new transaction; they may have had the fee
2654     // subtracted from them.
2655     for (unsigned int idx = 0; idx < tx.vout.size(); idx++) {
2656         tx.vout[idx].nValue = tx_new->vout[idx].nValue;
2657     }
2658 
2659     // Add new txins while keeping original txin scriptSig/order.
2660     for (const CTxIn& txin : tx_new->vin) {
2661         if (!coinControl.IsSelected(txin.prevout)) {
2662             tx.vin.push_back(txin);
2663 
2664         }
2665         if (lockUnspents) {
2666             LockCoin(txin.prevout);
2667         }
2668 
2669     }
2670 
2671     return true;
2672 }
2673 
2674 bool
FindValueInNameInput(const CTxIn & nameInput,CAmount & value,const CWalletTx * & walletTx,bilingual_str & error) const2675 CWallet::FindValueInNameInput (const CTxIn& nameInput,
2676                                CAmount& value, const CWalletTx*& walletTx,
2677                                bilingual_str& error) const
2678 {
2679   walletTx = GetWalletTx (nameInput.prevout.hash);
2680   if (!walletTx)
2681     {
2682       error = _("Input tx not found in wallet");
2683       return false;
2684     }
2685 
2686   const CTxOut& output = walletTx->tx->vout[nameInput.prevout.n];
2687   if (IsMine (output) != ISMINE_SPENDABLE)
2688     {
2689       error = _("Input tx is not mine");
2690       return false;
2691     }
2692 
2693   if (!CNameScript::isNameScript (output.scriptPubKey))
2694     {
2695       error = _("Input tx is not a name operation");
2696       return false;
2697     }
2698 
2699   value = output.nValue;
2700   return true;
2701 }
2702 
IsCurrentForAntiFeeSniping(interfaces::Chain & chain,const uint256 & block_hash)2703 static bool IsCurrentForAntiFeeSniping(interfaces::Chain& chain, const uint256& block_hash)
2704 {
2705     if (chain.isInitialBlockDownload()) {
2706         return false;
2707     }
2708     constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60; // in seconds
2709     int64_t block_time;
2710     CHECK_NONFATAL(chain.findBlock(block_hash, FoundBlock().time(block_time)));
2711     if (block_time < (GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
2712         return false;
2713     }
2714     return true;
2715 }
2716 
2717 /**
2718  * Return a height-based locktime for new transactions (uses the height of the
2719  * current chain tip unless we are not synced with the current chain
2720  */
GetLocktimeForNewTransaction(interfaces::Chain & chain,const uint256 & block_hash,int block_height)2721 static uint32_t GetLocktimeForNewTransaction(interfaces::Chain& chain, const uint256& block_hash, int block_height)
2722 {
2723     uint32_t locktime;
2724     // Discourage fee sniping.
2725     //
2726     // For a large miner the value of the transactions in the best block and
2727     // the mempool can exceed the cost of deliberately attempting to mine two
2728     // blocks to orphan the current best block. By setting nLockTime such that
2729     // only the next block can include the transaction, we discourage this
2730     // practice as the height restricted and limited blocksize gives miners
2731     // considering fee sniping fewer options for pulling off this attack.
2732     //
2733     // A simple way to think about this is from the wallet's point of view we
2734     // always want the blockchain to move forward. By setting nLockTime this
2735     // way we're basically making the statement that we only want this
2736     // transaction to appear in the next block; we don't want to potentially
2737     // encourage reorgs by allowing transactions to appear at lower heights
2738     // than the next block in forks of the best chain.
2739     //
2740     // Of course, the subsidy is high enough, and transaction volume low
2741     // enough, that fee sniping isn't a problem yet, but by implementing a fix
2742     // now we ensure code won't be written that makes assumptions about
2743     // nLockTime that preclude a fix later.
2744     if (IsCurrentForAntiFeeSniping(chain, block_hash)) {
2745         locktime = block_height;
2746 
2747         // Secondly occasionally randomly pick a nLockTime even further back, so
2748         // that transactions that are delayed after signing for whatever reason,
2749         // e.g. high-latency mix networks and some CoinJoin implementations, have
2750         // better privacy.
2751         if (GetRandInt(10) == 0)
2752             locktime = std::max(0, (int)locktime - GetRandInt(100));
2753     } else {
2754         // If our chain is lagging behind, we can't discourage fee sniping nor help
2755         // the privacy of high-latency transactions. To avoid leaking a potentially
2756         // unique "nLockTime fingerprint", set nLockTime to a constant.
2757         locktime = 0;
2758     }
2759     assert(locktime < LOCKTIME_THRESHOLD);
2760     return locktime;
2761 }
2762 
TransactionChangeType(const Optional<OutputType> & change_type,const std::vector<CRecipient> & vecSend)2763 OutputType CWallet::TransactionChangeType(const Optional<OutputType>& change_type, const std::vector<CRecipient>& vecSend)
2764 {
2765     // If -changetype is specified, always use that change type.
2766     if (change_type) {
2767         return *change_type;
2768     }
2769 
2770     // if m_default_address_type is legacy, use legacy address as change (even
2771     // if some of the outputs are P2WPKH or P2WSH).
2772     if (m_default_address_type == OutputType::LEGACY) {
2773         return OutputType::LEGACY;
2774     }
2775 
2776     // if any destination is P2WPKH or P2WSH, use P2WPKH for the change
2777     // output.
2778     for (const auto& recipient : vecSend) {
2779         // Check if any destination contains a witness program:
2780         int witnessversion = 0;
2781         std::vector<unsigned char> witnessprogram;
2782         if (recipient.scriptPubKey.IsWitnessProgram(true, witnessversion, witnessprogram)) {
2783             return OutputType::BECH32;
2784         }
2785     }
2786 
2787     // else use m_default_address_type for change
2788     return m_default_address_type;
2789 }
2790 
CreateTransactionInternal(const std::vector<CRecipient> & vecSend,const CTxIn * withInput,CTransactionRef & tx,CAmount & nFeeRet,int & nChangePosInOut,bilingual_str & error,const CCoinControl & coin_control,FeeCalculation & fee_calc_out,bool sign)2791 bool CWallet::CreateTransactionInternal(
2792         const std::vector<CRecipient>& vecSend,
2793         const CTxIn* withInput,
2794         CTransactionRef& tx,
2795         CAmount& nFeeRet,
2796         int& nChangePosInOut,
2797         bilingual_str& error,
2798         const CCoinControl& coin_control,
2799         FeeCalculation& fee_calc_out,
2800         bool sign)
2801 {
2802     /* Initialise nFeeRet here so that SendMoney doesn't see an uninitialised
2803        value in case we error out earlier.  */
2804     nFeeRet = 0;
2805 
2806     CAmount nValue = 0;
2807     const OutputType change_type = TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : m_default_change_type, vecSend);
2808     ReserveDestination reservedest(this, change_type);
2809     int nChangePosRequest = nChangePosInOut;
2810     unsigned int nSubtractFeeFromAmount = 0;
2811     bool isNamecoin = false;
2812     for (const auto& recipient : vecSend)
2813     {
2814         if (nValue < 0 || recipient.nAmount < 0)
2815         {
2816             error = _("Transaction amounts must not be negative");
2817             return false;
2818         }
2819         nValue += recipient.nAmount;
2820 
2821         if (recipient.fSubtractFeeFromAmount)
2822             nSubtractFeeFromAmount++;
2823 
2824         if (CNameScript::isNameScript (recipient.scriptPubKey))
2825             isNamecoin = true;
2826     }
2827     if (vecSend.empty())
2828     {
2829         error = _("Transaction must have at least one recipient");
2830         return false;
2831     }
2832 
2833     /* If we have an input to include, find its value.  This value will be
2834        subtracted later on during coin selection, since the input is added
2835        additionally to the selected coins.  */
2836     CAmount nInputValue = 0;
2837     const CWalletTx* withInputTx = nullptr;
2838     if (withInput)
2839     {
2840         if (!FindValueInNameInput (*withInput, nInputValue, withInputTx, error))
2841             return false;
2842     }
2843 
2844     CMutableTransaction txNew;
2845     if (isNamecoin)
2846         txNew.SetNamecoin();
2847 
2848     FeeCalculation feeCalc;
2849     CAmount nFeeNeeded;
2850     int nBytes;
2851     {
2852         std::set<CInputCoin> setCoins;
2853         LOCK(cs_wallet);
2854         txNew.nLockTime = GetLocktimeForNewTransaction(chain(), GetLastBlockHash(), GetLastBlockHeight());
2855         {
2856             std::vector<COutput> vAvailableCoins;
2857             AvailableCoins(vAvailableCoins, true, &coin_control, 1, MAX_MONEY, MAX_MONEY, 0);
2858             CoinSelectionParams coin_selection_params; // Parameters for coin selection, init with dummy
2859 
2860             // Create change script that will be used if we need change
2861             // TODO: pass in scriptChange instead of reservedest so
2862             // change transaction isn't always pay-to-bitcoin-address
2863             CScript scriptChange;
2864 
2865             // coin control: send change to custom address
2866             if (!boost::get<CNoDestination>(&coin_control.destChange)) {
2867                 scriptChange = GetScriptForDestination(coin_control.destChange);
2868             } else { // no coin control: send change to newly generated address
2869                 // Note: We use a new key here to keep it from being obvious which side is the change.
2870                 //  The drawback is that by not reusing a previous key, the change may be lost if a
2871                 //  backup is restored, if the backup doesn't have the new private key for the change.
2872                 //  If we reused the old key, it would be possible to add code to look for and
2873                 //  rediscover unknown transactions that were written with keys of ours to recover
2874                 //  post-backup change.
2875 
2876                 // Reserve a new key pair from key pool. If it fails, provide a dummy
2877                 // destination in case we don't need change.
2878                 CTxDestination dest;
2879                 if (!reservedest.GetReservedDestination(dest, true)) {
2880                     error = _("Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.");
2881                 }
2882                 scriptChange = GetScriptForDestination(dest);
2883                 // A valid destination implies a change script (and
2884                 // vice-versa). An empty change script will abort later, if the
2885                 // change keypool ran out, but change is required.
2886                 CHECK_NONFATAL(IsValidDestination(dest) != scriptChange.empty());
2887             }
2888             CTxOut change_prototype_txout(0, scriptChange);
2889             coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
2890 
2891             CFeeRate discard_rate = GetDiscardRate(*this);
2892 
2893             // Get the fee rate to use effective values in coin selection
2894             CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, &feeCalc);
2895             // Do not, ever, assume that it's fine to change the fee rate if the user has explicitly
2896             // provided one
2897             if (coin_control.m_feerate && nFeeRateNeeded > *coin_control.m_feerate) {
2898                 error = strprintf(_("Fee rate (%s) is lower than the minimum fee rate setting (%s)"), coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), nFeeRateNeeded.ToString(FeeEstimateMode::SAT_VB));
2899                 return false;
2900             }
2901 
2902             nFeeRet = 0;
2903             bool pick_new_inputs = true;
2904             CAmount nValueIn = 0;
2905 
2906             // BnB selector is the only selector used when this is true.
2907             // That should only happen on the first pass through the loop.
2908             coin_selection_params.use_bnb = true;
2909             coin_selection_params.m_subtract_fee_outputs = nSubtractFeeFromAmount != 0; // If we are doing subtract fee from recipient, don't use effective values
2910             // Start with no fee and loop until there is enough fee
2911             while (true)
2912             {
2913                 nChangePosInOut = nChangePosRequest;
2914                 txNew.vin.clear();
2915                 txNew.vout.clear();
2916                 bool fFirst = true;
2917 
2918                 CAmount nValueToSelect = nValue - nInputValue;
2919                 if (nSubtractFeeFromAmount == 0)
2920                     nValueToSelect += nFeeRet;
2921 
2922                 // vouts to the payees
2923                 if (!coin_selection_params.m_subtract_fee_outputs) {
2924                     coin_selection_params.tx_noinputs_size = 11; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 output count, 1 witness overhead (dummy, flag, stack size)
2925                 }
2926                 for (const auto& recipient : vecSend)
2927                 {
2928                     CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
2929 
2930                     if (recipient.fSubtractFeeFromAmount)
2931                     {
2932                         assert(nSubtractFeeFromAmount != 0);
2933                         txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
2934 
2935                         if (fFirst) // first receiver pays the remainder not divisible by output count
2936                         {
2937                             fFirst = false;
2938                             txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
2939                         }
2940                     }
2941                     // Include the fee cost for outputs. Note this is only used for BnB right now
2942                     if (!coin_selection_params.m_subtract_fee_outputs) {
2943                         coin_selection_params.tx_noinputs_size += ::GetSerializeSize(txout, PROTOCOL_VERSION);
2944                     }
2945 
2946                     if (IsDust(txout, chain().relayDustFee()))
2947                     {
2948                         if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
2949                         {
2950                             if (txout.nValue < 0)
2951                                 error = _("The transaction amount is too small to pay the fee");
2952                             else
2953                                 error = _("The transaction amount is too small to send after the fee has been deducted");
2954                         }
2955                         else
2956                             error = _("Transaction amount too small");
2957                         return false;
2958                     }
2959                     txNew.vout.push_back(txout);
2960                 }
2961 
2962                 // Choose coins to use
2963                 bool bnb_used = false;
2964                 if (pick_new_inputs) {
2965                     nValueIn = 0;
2966                     setCoins.clear();
2967                     int change_spend_size = CalculateMaximumSignedInputSize(change_prototype_txout, this);
2968                     // If the wallet doesn't know how to sign change output, assume p2sh-p2wpkh
2969                     // as lower-bound to allow BnB to do it's thing
2970                     if (change_spend_size == -1) {
2971                         coin_selection_params.change_spend_size = DUMMY_NESTED_P2WPKH_INPUT_SIZE;
2972                     } else {
2973                         coin_selection_params.change_spend_size = (size_t)change_spend_size;
2974                     }
2975                     coin_selection_params.effective_fee = nFeeRateNeeded;
2976                     if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coin_control, coin_selection_params, bnb_used))
2977                     {
2978                         // If BnB was used, it was the first pass. No longer the first pass and continue loop with knapsack.
2979                         if (bnb_used) {
2980                             coin_selection_params.use_bnb = false;
2981                             continue;
2982                         }
2983                         else {
2984                             error = _("Insufficient funds");
2985                             return false;
2986                         }
2987                     }
2988                 } else {
2989                     bnb_used = false;
2990                 }
2991                 if (withInput)
2992                     setCoins.emplace(withInputTx->tx, withInput->prevout.n);
2993 
2994                 const CAmount nChange = nValueIn - nValueToSelect;
2995                 if (nChange > 0)
2996                 {
2997                     // Fill a vout to ourself
2998                     CTxOut newTxOut(nChange, scriptChange);
2999 
3000                     // Never create dust outputs; if we would, just
3001                     // add the dust to the fee.
3002                     // The nChange when BnB is used is always going to go to fees.
3003                     if (IsDust(newTxOut, discard_rate) || bnb_used)
3004                     {
3005                         nChangePosInOut = -1;
3006                         nFeeRet += nChange;
3007                     }
3008                     else
3009                     {
3010                         if (nChangePosInOut == -1)
3011                         {
3012                             // Insert change txn at random position:
3013                             nChangePosInOut = GetRandInt(txNew.vout.size()+1);
3014                         }
3015                         else if ((unsigned int)nChangePosInOut > txNew.vout.size())
3016                         {
3017                             error = _("Change index out of range");
3018                             return false;
3019                         }
3020 
3021                         std::vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosInOut;
3022                         txNew.vout.insert(position, newTxOut);
3023                     }
3024                 } else {
3025                     nChangePosInOut = -1;
3026                 }
3027 
3028                 // Dummy fill vin for maximum size estimation
3029                 //
3030                 for (const auto& coin : setCoins) {
3031                     txNew.vin.push_back(CTxIn(coin.outpoint,CScript()));
3032                 }
3033 
3034                 nBytes = CalculateMaximumSignedTxSize(CTransaction(txNew), this, coin_control.fAllowWatchOnly);
3035                 if (nBytes < 0) {
3036                     error = _("Signing transaction failed");
3037                     return false;
3038                 }
3039 
3040                 nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, &feeCalc);
3041                 if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) {
3042                     // eventually allow a fallback fee
3043                     error = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
3044                     return false;
3045                 }
3046 
3047                 if (nFeeRet >= nFeeNeeded) {
3048                     // Reduce fee to only the needed amount if possible. This
3049                     // prevents potential overpayment in fees if the coins
3050                     // selected to meet nFeeNeeded result in a transaction that
3051                     // requires less fee than the prior iteration.
3052 
3053                     // If we have no change and a big enough excess fee, then
3054                     // try to construct transaction again only without picking
3055                     // new inputs. We now know we only need the smaller fee
3056                     // (because of reduced tx size) and so we should add a
3057                     // change output. Only try this once.
3058                     if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
3059                         unsigned int tx_size_with_change = nBytes + coin_selection_params.change_output_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size
3060                         CAmount fee_needed_with_change = GetMinimumFee(*this, tx_size_with_change, coin_control, nullptr);
3061                         CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate);
3062                         if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
3063                             pick_new_inputs = false;
3064                             nFeeRet = fee_needed_with_change;
3065                             continue;
3066                         }
3067                     }
3068 
3069                     // If we have change output already, just increase it
3070                     if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3071                         CAmount extraFeePaid = nFeeRet - nFeeNeeded;
3072                         std::vector<CTxOut>::iterator change_position = txNew.vout.begin()+nChangePosInOut;
3073                         change_position->nValue += extraFeePaid;
3074                         nFeeRet -= extraFeePaid;
3075                     }
3076                     break; // Done, enough fee included.
3077                 }
3078                 else if (!pick_new_inputs) {
3079                     // This shouldn't happen, we should have had enough excess
3080                     // fee to pay for the new output and still meet nFeeNeeded
3081                     // Or we should have just subtracted fee from recipients and
3082                     // nFeeNeeded should not have changed
3083                     error = _("Transaction fee and change calculation failed");
3084                     return false;
3085                 }
3086 
3087                 // Try to reduce change to include necessary fee
3088                 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3089                     CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet;
3090                     std::vector<CTxOut>::iterator change_position = txNew.vout.begin()+nChangePosInOut;
3091                     // Only reduce change if remaining amount is still a large enough output.
3092                     if (change_position->nValue >= MIN_FINAL_CHANGE + additionalFeeNeeded) {
3093                         change_position->nValue -= additionalFeeNeeded;
3094                         nFeeRet += additionalFeeNeeded;
3095                         break; // Done, able to increase fee from change
3096                     }
3097                 }
3098 
3099                 // If subtracting fee from recipients, we now know what fee we
3100                 // need to subtract, we have no reason to reselect inputs
3101                 if (nSubtractFeeFromAmount > 0) {
3102                     pick_new_inputs = false;
3103                 }
3104 
3105                 // Include more fee and try again.
3106                 nFeeRet = nFeeNeeded;
3107                 coin_selection_params.use_bnb = false;
3108                 continue;
3109             }
3110 
3111             // Give up if change keypool ran out and change is required
3112             if (scriptChange.empty() && nChangePosInOut != -1) {
3113                 return false;
3114             }
3115         }
3116 
3117         // Shuffle selected coins and fill in final vin
3118         txNew.vin.clear();
3119         std::vector<CInputCoin> selected_coins(setCoins.begin(), setCoins.end());
3120         Shuffle(selected_coins.begin(), selected_coins.end(), FastRandomContext());
3121 
3122         // Note how the sequence number is set to non-maxint so that
3123         // the nLockTime set above actually works.
3124         //
3125         // BIP125 defines opt-in RBF as any nSequence < maxint-1, so
3126         // we use the highest possible value in that range (maxint-2)
3127         // to avoid conflicting with other possible uses of nSequence,
3128         // and in the spirit of "smallest possible change from prior
3129         // behavior."
3130         const uint32_t nSequence = coin_control.m_signal_bip125_rbf.get_value_or(m_signal_rbf) ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
3131         for (const auto& coin : selected_coins) {
3132             txNew.vin.push_back(CTxIn(coin.outpoint, CScript(), nSequence));
3133         }
3134 
3135         if (sign && !SignTransaction(txNew)) {
3136             error = _("Signing transaction failed");
3137             return false;
3138         }
3139 
3140         // Return the constructed transaction data.
3141         tx = MakeTransactionRef(std::move(txNew));
3142 
3143         // Limit size
3144         if (GetTransactionWeight(*tx) > MAX_STANDARD_TX_WEIGHT)
3145         {
3146             error = _("Transaction too large");
3147             return false;
3148         }
3149     }
3150 
3151     if (nFeeRet > m_default_max_tx_fee) {
3152         error = TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED);
3153         return false;
3154     }
3155 
3156     if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
3157         // Lastly, ensure this tx will pass the mempool's chain limits
3158         if (!chain().checkChainLimits(tx)) {
3159             error = _("Transaction has too long of a mempool chain");
3160             return false;
3161         }
3162     }
3163 
3164     // Before we return success, we assume any change key will be used to prevent
3165     // accidental re-use.
3166     reservedest.KeepDestination();
3167     fee_calc_out = feeCalc;
3168 
3169     WalletLogPrintf("Fee Calculation: Fee:%d Bytes:%u Needed:%d Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
3170               nFeeRet, nBytes, nFeeNeeded, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
3171               feeCalc.est.pass.start, feeCalc.est.pass.end,
3172               (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool) > 0.0 ? 100 * feeCalc.est.pass.withinTarget / (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool) : 0.0,
3173               feeCalc.est.pass.withinTarget, feeCalc.est.pass.totalConfirmed, feeCalc.est.pass.inMempool, feeCalc.est.pass.leftMempool,
3174               feeCalc.est.fail.start, feeCalc.est.fail.end,
3175               (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) > 0.0 ? 100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool) : 0.0,
3176               feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
3177     return true;
3178 }
3179 
CreateTransaction(const std::vector<CRecipient> & vecSend,const CTxIn * withInput,CTransactionRef & tx,CAmount & nFeeRet,int & nChangePosInOut,bilingual_str & error,const CCoinControl & coin_control,FeeCalculation & fee_calc_out,bool sign)3180 bool CWallet::CreateTransaction(
3181         const std::vector<CRecipient>& vecSend,
3182         const CTxIn* withInput,
3183         CTransactionRef& tx,
3184         CAmount& nFeeRet,
3185         int& nChangePosInOut,
3186         bilingual_str& error,
3187         const CCoinControl& coin_control,
3188         FeeCalculation& fee_calc_out,
3189         bool sign)
3190 {
3191     int nChangePosIn = nChangePosInOut;
3192     CTransactionRef tx2 = tx;
3193     bool res = CreateTransactionInternal(vecSend, withInput, tx, nFeeRet, nChangePosInOut, error, coin_control, fee_calc_out, sign);
3194     // try with avoidpartialspends unless it's enabled already
3195     if (res && nFeeRet > 0 /* 0 means non-functional fee rate estimation */ && m_max_aps_fee > -1 && !coin_control.m_avoid_partial_spends) {
3196         CCoinControl tmp_cc = coin_control;
3197         tmp_cc.m_avoid_partial_spends = true;
3198         CAmount nFeeRet2;
3199         int nChangePosInOut2 = nChangePosIn;
3200         bilingual_str error2; // fired and forgotten; if an error occurs, we discard the results
3201         if (CreateTransactionInternal(vecSend, withInput, tx2, nFeeRet2, nChangePosInOut2, error2, tmp_cc, fee_calc_out, sign)) {
3202             // if fee of this alternative one is within the range of the max fee, we use this one
3203             const bool use_aps = nFeeRet2 <= nFeeRet + m_max_aps_fee;
3204             WalletLogPrintf("Fee non-grouped = %lld, grouped = %lld, using %s\n", nFeeRet, nFeeRet2, use_aps ? "grouped" : "non-grouped");
3205             if (use_aps) {
3206                 tx = tx2;
3207                 nFeeRet = nFeeRet2;
3208                 nChangePosInOut = nChangePosInOut2;
3209             }
3210         }
3211     }
3212     return res;
3213 }
3214 
CommitTransaction(CTransactionRef tx,mapValue_t mapValue,std::vector<std::pair<std::string,std::string>> orderForm)3215 void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm)
3216 {
3217     LOCK(cs_wallet);
3218     WalletLogPrintf("CommitTransaction:\n%s", tx->ToString()); /* Continued */
3219 
3220     // Add tx to wallet, because if it has change it's also ours,
3221     // otherwise just for transaction history.
3222     AddToWallet(tx, {}, [&](CWalletTx& wtx, bool new_tx) {
3223         CHECK_NONFATAL(wtx.mapValue.empty());
3224         CHECK_NONFATAL(wtx.vOrderForm.empty());
3225         wtx.mapValue = std::move(mapValue);
3226         wtx.vOrderForm = std::move(orderForm);
3227         wtx.fTimeReceivedIsTxTime = true;
3228         wtx.fFromMe = true;
3229         return true;
3230     });
3231 
3232     // Notify that old coins are spent
3233     for (const CTxIn& txin : tx->vin) {
3234         CWalletTx &coin = mapWallet.at(txin.prevout.hash);
3235         coin.MarkDirty();
3236         NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
3237     }
3238 
3239     // Get the inserted-CWalletTx from mapWallet so that the
3240     // fInMempool flag is cached properly
3241     CWalletTx& wtx = mapWallet.at(tx->GetHash());
3242 
3243     if (!fBroadcastTransactions) {
3244         // Don't submit tx to the mempool
3245         return;
3246     }
3247 
3248     std::string err_string;
3249     if (!wtx.SubmitMemoryPoolAndRelay(err_string, true)) {
3250         WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
3251         // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
3252     }
3253 }
3254 
LoadWallet(bool & fFirstRunRet)3255 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
3256 {
3257     LOCK(cs_wallet);
3258 
3259     fFirstRunRet = false;
3260     DBErrors nLoadWalletRet = WalletBatch(*database).LoadWallet(this);
3261     if (nLoadWalletRet == DBErrors::NEED_REWRITE)
3262     {
3263         if (database->Rewrite("\x04pool"))
3264         {
3265             for (const auto& spk_man_pair : m_spk_managers) {
3266                 spk_man_pair.second->RewriteDB();
3267             }
3268         }
3269     }
3270 
3271     // This wallet is in its first run if there are no ScriptPubKeyMans and it isn't blank or no privkeys
3272     fFirstRunRet = m_spk_managers.empty() && !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
3273     if (fFirstRunRet) {
3274         assert(m_external_spk_managers.empty());
3275         assert(m_internal_spk_managers.empty());
3276     }
3277 
3278     if (nLoadWalletRet != DBErrors::LOAD_OK)
3279         return nLoadWalletRet;
3280 
3281     return DBErrors::LOAD_OK;
3282 }
3283 
ZapSelectTx(std::vector<uint256> & vHashIn,std::vector<uint256> & vHashOut)3284 DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
3285 {
3286     AssertLockHeld(cs_wallet);
3287     DBErrors nZapSelectTxRet = WalletBatch(*database).ZapSelectTx(vHashIn, vHashOut);
3288     for (const uint256& hash : vHashOut) {
3289         const auto& it = mapWallet.find(hash);
3290         wtxOrdered.erase(it->second.m_it_wtxOrdered);
3291         for (const auto& txin : it->second.tx->vin)
3292             mapTxSpends.erase(txin.prevout);
3293         mapWallet.erase(it);
3294         NotifyTransactionChanged(this, hash, CT_DELETED);
3295     }
3296 
3297     if (nZapSelectTxRet == DBErrors::NEED_REWRITE)
3298     {
3299         if (database->Rewrite("\x04pool"))
3300         {
3301             for (const auto& spk_man_pair : m_spk_managers) {
3302                 spk_man_pair.second->RewriteDB();
3303             }
3304         }
3305     }
3306 
3307     if (nZapSelectTxRet != DBErrors::LOAD_OK)
3308         return nZapSelectTxRet;
3309 
3310     MarkDirty();
3311 
3312     return DBErrors::LOAD_OK;
3313 }
3314 
SetAddressBookWithDB(WalletBatch & batch,const CTxDestination & address,const std::string & strName,const std::string & strPurpose)3315 bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3316 {
3317     bool fUpdated = false;
3318     bool is_mine;
3319     {
3320         LOCK(cs_wallet);
3321         std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find(address);
3322         fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
3323         m_address_book[address].SetLabel(strName);
3324         if (!strPurpose.empty()) /* update purpose only if requested */
3325             m_address_book[address].purpose = strPurpose;
3326         is_mine = IsMine(address) != ISMINE_NO;
3327     }
3328     NotifyAddressBookChanged(this, address, strName, is_mine,
3329                              strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
3330     if (!strPurpose.empty() && !batch.WritePurpose(EncodeDestination(address), strPurpose))
3331         return false;
3332     return batch.WriteName(EncodeDestination(address), strName);
3333 }
3334 
SetAddressBook(const CTxDestination & address,const std::string & strName,const std::string & strPurpose)3335 bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3336 {
3337     WalletBatch batch(*database);
3338     return SetAddressBookWithDB(batch, address, strName, strPurpose);
3339 }
3340 
DelAddressBook(const CTxDestination & address)3341 bool CWallet::DelAddressBook(const CTxDestination& address)
3342 {
3343     bool is_mine;
3344     WalletBatch batch(*database);
3345     {
3346         LOCK(cs_wallet);
3347         // If we want to delete receiving addresses, we need to take care that DestData "used" (and possibly newer DestData) gets preserved (and the "deleted" address transformed into a change entry instead of actually being deleted)
3348         // NOTE: This isn't a problem for sending addresses because they never have any DestData yet!
3349         // When adding new DestData, it should be considered here whether to retain or delete it (or move it?).
3350         if (IsMine(address)) {
3351             WalletLogPrintf("%s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n", __func__, PACKAGE_BUGREPORT);
3352             return false;
3353         }
3354         // Delete destdata tuples associated with address
3355         std::string strAddress = EncodeDestination(address);
3356         for (const std::pair<const std::string, std::string> &item : m_address_book[address].destdata)
3357         {
3358             batch.EraseDestData(strAddress, item.first);
3359         }
3360         m_address_book.erase(address);
3361         is_mine = IsMine(address) != ISMINE_NO;
3362     }
3363 
3364     NotifyAddressBookChanged(this, address, "", is_mine, "", CT_DELETED);
3365 
3366     batch.ErasePurpose(EncodeDestination(address));
3367     return batch.EraseName(EncodeDestination(address));
3368 }
3369 
KeypoolCountExternalKeys() const3370 size_t CWallet::KeypoolCountExternalKeys() const
3371 {
3372     AssertLockHeld(cs_wallet);
3373 
3374     unsigned int count = 0;
3375     for (auto spk_man : GetActiveScriptPubKeyMans()) {
3376         count += spk_man->KeypoolCountExternalKeys();
3377     }
3378 
3379     return count;
3380 }
3381 
GetKeyPoolSize() const3382 unsigned int CWallet::GetKeyPoolSize() const
3383 {
3384     AssertLockHeld(cs_wallet);
3385 
3386     unsigned int count = 0;
3387     for (auto spk_man : GetActiveScriptPubKeyMans()) {
3388         count += spk_man->GetKeyPoolSize();
3389     }
3390     return count;
3391 }
3392 
TopUpKeyPool(unsigned int kpSize)3393 bool CWallet::TopUpKeyPool(unsigned int kpSize)
3394 {
3395     LOCK(cs_wallet);
3396     bool res = true;
3397     for (auto spk_man : GetActiveScriptPubKeyMans()) {
3398         res &= spk_man->TopUp(kpSize);
3399     }
3400     return res;
3401 }
3402 
GetNewDestination(const OutputType type,const std::string label,CTxDestination & dest,std::string & error)3403 bool CWallet::GetNewDestination(const OutputType type, const std::string label, CTxDestination& dest, std::string& error)
3404 {
3405     LOCK(cs_wallet);
3406     error.clear();
3407     bool result = false;
3408     auto spk_man = GetScriptPubKeyMan(type, false /* internal */);
3409     if (spk_man) {
3410         spk_man->TopUp();
3411         result = spk_man->GetNewDestination(type, dest, error);
3412     } else {
3413         error = strprintf("Error: No %s addresses available.", FormatOutputType(type));
3414     }
3415     if (result) {
3416         SetAddressBook(dest, label, "receive");
3417     }
3418 
3419     return result;
3420 }
3421 
GetNewChangeDestination(const OutputType type,CTxDestination & dest,std::string & error)3422 bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& dest, std::string& error)
3423 {
3424     LOCK(cs_wallet);
3425     error.clear();
3426 
3427     ReserveDestination reservedest(this, type);
3428     if (!reservedest.GetReservedDestination(dest, true)) {
3429         error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
3430         return false;
3431     }
3432 
3433     reservedest.KeepDestination();
3434     return true;
3435 }
3436 
GetOldestKeyPoolTime() const3437 int64_t CWallet::GetOldestKeyPoolTime() const
3438 {
3439     LOCK(cs_wallet);
3440     int64_t oldestKey = std::numeric_limits<int64_t>::max();
3441     for (const auto& spk_man_pair : m_spk_managers) {
3442         oldestKey = std::min(oldestKey, spk_man_pair.second->GetOldestKeyPoolTime());
3443     }
3444     return oldestKey;
3445 }
3446 
MarkDestinationsDirty(const std::set<CTxDestination> & destinations)3447 void CWallet::MarkDestinationsDirty(const std::set<CTxDestination>& destinations) {
3448     for (auto& entry : mapWallet) {
3449         CWalletTx& wtx = entry.second;
3450         if (wtx.m_is_cache_empty) continue;
3451         for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
3452             CTxDestination dst;
3453             if (ExtractDestination(wtx.tx->vout[i].scriptPubKey, dst) && destinations.count(dst)) {
3454                 wtx.MarkDirty();
3455                 break;
3456             }
3457         }
3458     }
3459 }
3460 
GetAddressBalances() const3461 std::map<CTxDestination, CAmount> CWallet::GetAddressBalances() const
3462 {
3463     std::map<CTxDestination, CAmount> balances;
3464 
3465     {
3466         LOCK(cs_wallet);
3467         std::set<uint256> trusted_parents;
3468         for (const auto& walletEntry : mapWallet)
3469         {
3470             const CWalletTx& wtx = walletEntry.second;
3471 
3472             if (!IsTrusted(wtx, trusted_parents))
3473                 continue;
3474 
3475             if (wtx.IsImmatureCoinBase())
3476                 continue;
3477 
3478             int nDepth = wtx.GetDepthInMainChain();
3479             if (nDepth < (wtx.IsFromMe(ISMINE_ALL) ? 0 : 1))
3480                 continue;
3481 
3482             for (unsigned int i = 0; i < wtx.tx->vout.size(); i++)
3483             {
3484                 CTxDestination addr;
3485                 if (!IsMine(wtx.tx->vout[i]))
3486                     continue;
3487                 if(!ExtractDestination(wtx.tx->vout[i].scriptPubKey, addr))
3488                     continue;
3489 
3490                 CAmount n = IsSpent(walletEntry.first, i) ? 0 : wtx.tx->vout[i].nValue;
3491                 balances[addr] += n;
3492             }
3493         }
3494     }
3495 
3496     return balances;
3497 }
3498 
GetAddressGroupings() const3499 std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings() const
3500 {
3501     AssertLockHeld(cs_wallet);
3502     std::set< std::set<CTxDestination> > groupings;
3503     std::set<CTxDestination> grouping;
3504 
3505     for (const auto& walletEntry : mapWallet)
3506     {
3507         const CWalletTx& wtx = walletEntry.second;
3508 
3509         if (wtx.tx->vin.size() > 0)
3510         {
3511             bool any_mine = false;
3512             // group all input addresses with each other
3513             for (const CTxIn& txin : wtx.tx->vin)
3514             {
3515                 CTxDestination address;
3516                 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
3517                     continue;
3518                 if(!ExtractDestination(mapWallet.at(txin.prevout.hash).tx->vout[txin.prevout.n].scriptPubKey, address))
3519                     continue;
3520                 grouping.insert(address);
3521                 any_mine = true;
3522             }
3523 
3524             // group change with input addresses
3525             if (any_mine)
3526             {
3527                for (const CTxOut& txout : wtx.tx->vout)
3528                    if (IsChange(txout))
3529                    {
3530                        CTxDestination txoutAddr;
3531                        if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
3532                            continue;
3533                        grouping.insert(txoutAddr);
3534                    }
3535             }
3536             if (grouping.size() > 0)
3537             {
3538                 groupings.insert(grouping);
3539                 grouping.clear();
3540             }
3541         }
3542 
3543         // group lone addrs by themselves
3544         for (const auto& txout : wtx.tx->vout)
3545             if (IsMine(txout))
3546             {
3547                 CTxDestination address;
3548                 if(!ExtractDestination(txout.scriptPubKey, address))
3549                     continue;
3550                 grouping.insert(address);
3551                 groupings.insert(grouping);
3552                 grouping.clear();
3553             }
3554     }
3555 
3556     std::set< std::set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
3557     std::map< CTxDestination, std::set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
3558     for (std::set<CTxDestination> _grouping : groupings)
3559     {
3560         // make a set of all the groups hit by this new group
3561         std::set< std::set<CTxDestination>* > hits;
3562         std::map< CTxDestination, std::set<CTxDestination>* >::iterator it;
3563         for (const CTxDestination& address : _grouping)
3564             if ((it = setmap.find(address)) != setmap.end())
3565                 hits.insert((*it).second);
3566 
3567         // merge all hit groups into a new single group and delete old groups
3568         std::set<CTxDestination>* merged = new std::set<CTxDestination>(_grouping);
3569         for (std::set<CTxDestination>* hit : hits)
3570         {
3571             merged->insert(hit->begin(), hit->end());
3572             uniqueGroupings.erase(hit);
3573             delete hit;
3574         }
3575         uniqueGroupings.insert(merged);
3576 
3577         // update setmap
3578         for (const CTxDestination& element : *merged)
3579             setmap[element] = merged;
3580     }
3581 
3582     std::set< std::set<CTxDestination> > ret;
3583     for (const std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
3584     {
3585         ret.insert(*uniqueGrouping);
3586         delete uniqueGrouping;
3587     }
3588 
3589     return ret;
3590 }
3591 
GetLabelAddresses(const std::string & label) const3592 std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) const
3593 {
3594     LOCK(cs_wallet);
3595     std::set<CTxDestination> result;
3596     for (const std::pair<const CTxDestination, CAddressBookData>& item : m_address_book)
3597     {
3598         if (item.second.IsChange()) continue;
3599         const CTxDestination& address = item.first;
3600         const std::string& strName = item.second.GetLabel();
3601         if (strName == label)
3602             result.insert(address);
3603     }
3604     return result;
3605 }
3606 
GetReservedDestination(CTxDestination & dest,bool internal)3607 bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool internal)
3608 {
3609     m_spk_man = pwallet->GetScriptPubKeyMan(type, internal);
3610     if (!m_spk_man) {
3611         return false;
3612     }
3613 
3614 
3615     if (nIndex == -1)
3616     {
3617         m_spk_man->TopUp();
3618 
3619         CKeyPool keypool;
3620         if (!m_spk_man->GetReservedDestination(type, internal, address, nIndex, keypool)) {
3621             return false;
3622         }
3623         fInternal = keypool.fInternal;
3624     }
3625     dest = address;
3626     return true;
3627 }
3628 
KeepDestination()3629 void ReserveDestination::KeepDestination()
3630 {
3631     if (nIndex != -1) {
3632         m_spk_man->KeepDestination(nIndex, type);
3633     }
3634     nIndex = -1;
3635     address = CNoDestination();
3636 }
3637 
ReturnDestination()3638 void ReserveDestination::ReturnDestination()
3639 {
3640     if (nIndex != -1) {
3641         m_spk_man->ReturnDestination(nIndex, fInternal, address);
3642     }
3643     nIndex = -1;
3644     address = CNoDestination();
3645 }
3646 
LockCoin(const COutPoint & output)3647 void CWallet::LockCoin(const COutPoint& output)
3648 {
3649     AssertLockHeld(cs_wallet);
3650     setLockedCoins.insert(output);
3651 }
3652 
UnlockCoin(const COutPoint & output)3653 void CWallet::UnlockCoin(const COutPoint& output)
3654 {
3655     AssertLockHeld(cs_wallet);
3656     setLockedCoins.erase(output);
3657 }
3658 
UnlockAllCoins()3659 void CWallet::UnlockAllCoins()
3660 {
3661     AssertLockHeld(cs_wallet);
3662     setLockedCoins.clear();
3663 }
3664 
IsLockedCoin(uint256 hash,unsigned int n) const3665 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
3666 {
3667     AssertLockHeld(cs_wallet);
3668     COutPoint outpt(hash, n);
3669 
3670     return (setLockedCoins.count(outpt) > 0);
3671 }
3672 
ListLockedCoins(std::vector<COutPoint> & vOutpts) const3673 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const
3674 {
3675     AssertLockHeld(cs_wallet);
3676     for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
3677          it != setLockedCoins.end(); it++) {
3678         COutPoint outpt = (*it);
3679         vOutpts.push_back(outpt);
3680     }
3681 }
3682 
3683 /** @} */ // end of Actions
3684 
GetKeyBirthTimes(std::map<CKeyID,int64_t> & mapKeyBirth) const3685 void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const {
3686     AssertLockHeld(cs_wallet);
3687     mapKeyBirth.clear();
3688 
3689     LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
3690     assert(spk_man != nullptr);
3691     LOCK(spk_man->cs_KeyStore);
3692 
3693     // get birth times for keys with metadata
3694     for (const auto& entry : spk_man->mapKeyMetadata) {
3695         if (entry.second.nCreateTime) {
3696             mapKeyBirth[entry.first] = entry.second.nCreateTime;
3697         }
3698     }
3699 
3700     // map in which we'll infer heights of other keys
3701     std::map<CKeyID, const CWalletTx::Confirmation*> mapKeyFirstBlock;
3702     CWalletTx::Confirmation max_confirm;
3703     max_confirm.block_height = GetLastBlockHeight() > 144 ? GetLastBlockHeight() - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
3704     CHECK_NONFATAL(chain().findAncestorByHeight(GetLastBlockHash(), max_confirm.block_height, FoundBlock().hash(max_confirm.hashBlock)));
3705     for (const CKeyID &keyid : spk_man->GetKeys()) {
3706         if (mapKeyBirth.count(keyid) == 0)
3707             mapKeyFirstBlock[keyid] = &max_confirm;
3708     }
3709 
3710     // if there are no such keys, we're done
3711     if (mapKeyFirstBlock.empty())
3712         return;
3713 
3714     // find first block that affects those keys, if there are any left
3715     for (const auto& entry : mapWallet) {
3716         // iterate over all wallet transactions...
3717         const CWalletTx &wtx = entry.second;
3718         if (wtx.m_confirm.status == CWalletTx::CONFIRMED) {
3719             // ... which are already in a block
3720             for (const CTxOut &txout : wtx.tx->vout) {
3721                 // iterate over all their outputs
3722                 for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *spk_man)) {
3723                     // ... and all their affected keys
3724                     auto rit = mapKeyFirstBlock.find(keyid);
3725                     if (rit != mapKeyFirstBlock.end() && wtx.m_confirm.block_height < rit->second->block_height) {
3726                         rit->second = &wtx.m_confirm;
3727                     }
3728                 }
3729             }
3730         }
3731     }
3732 
3733     // Extract block timestamps for those keys
3734     for (const auto& entry : mapKeyFirstBlock) {
3735         int64_t block_time;
3736         CHECK_NONFATAL(chain().findBlock(entry.second->hashBlock, FoundBlock().time(block_time)));
3737         mapKeyBirth[entry.first] = block_time - TIMESTAMP_WINDOW; // block times can be 2h off
3738     }
3739 }
3740 
3741 /**
3742  * Compute smart timestamp for a transaction being added to the wallet.
3743  *
3744  * Logic:
3745  * - If sending a transaction, assign its timestamp to the current time.
3746  * - If receiving a transaction outside a block, assign its timestamp to the
3747  *   current time.
3748  * - If receiving a block with a future timestamp, assign all its (not already
3749  *   known) transactions' timestamps to the current time.
3750  * - If receiving a block with a past timestamp, before the most recent known
3751  *   transaction (that we care about), assign all its (not already known)
3752  *   transactions' timestamps to the same timestamp as that most-recent-known
3753  *   transaction.
3754  * - If receiving a block with a past timestamp, but after the most recent known
3755  *   transaction, assign all its (not already known) transactions' timestamps to
3756  *   the block time.
3757  *
3758  * For more information see CWalletTx::nTimeSmart,
3759  * https://bitcointalk.org/?topic=54527, or
3760  * https://github.com/bitcoin/bitcoin/pull/1393.
3761  */
ComputeTimeSmart(const CWalletTx & wtx) const3762 unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
3763 {
3764     unsigned int nTimeSmart = wtx.nTimeReceived;
3765     if (!wtx.isUnconfirmed() && !wtx.isAbandoned()) {
3766         int64_t blocktime;
3767         if (chain().findBlock(wtx.m_confirm.hashBlock, FoundBlock().time(blocktime))) {
3768             int64_t latestNow = wtx.nTimeReceived;
3769             int64_t latestEntry = 0;
3770 
3771             // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
3772             int64_t latestTolerated = latestNow + 300;
3773             const TxItems& txOrdered = wtxOrdered;
3774             for (auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
3775                 CWalletTx* const pwtx = it->second;
3776                 if (pwtx == &wtx) {
3777                     continue;
3778                 }
3779                 int64_t nSmartTime;
3780                 nSmartTime = pwtx->nTimeSmart;
3781                 if (!nSmartTime) {
3782                     nSmartTime = pwtx->nTimeReceived;
3783                 }
3784                 if (nSmartTime <= latestTolerated) {
3785                     latestEntry = nSmartTime;
3786                     if (nSmartTime > latestNow) {
3787                         latestNow = nSmartTime;
3788                     }
3789                     break;
3790                 }
3791             }
3792 
3793             nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
3794         } else {
3795             WalletLogPrintf("%s: found %s in block %s not in index\n", __func__, wtx.GetHash().ToString(), wtx.m_confirm.hashBlock.ToString());
3796         }
3797     }
3798     return nTimeSmart;
3799 }
3800 
AddDestData(WalletBatch & batch,const CTxDestination & dest,const std::string & key,const std::string & value)3801 bool CWallet::AddDestData(WalletBatch& batch, const CTxDestination &dest, const std::string &key, const std::string &value)
3802 {
3803     if (boost::get<CNoDestination>(&dest))
3804         return false;
3805 
3806     m_address_book[dest].destdata.insert(std::make_pair(key, value));
3807     return batch.WriteDestData(EncodeDestination(dest), key, value);
3808 }
3809 
EraseDestData(WalletBatch & batch,const CTxDestination & dest,const std::string & key)3810 bool CWallet::EraseDestData(WalletBatch& batch, const CTxDestination &dest, const std::string &key)
3811 {
3812     if (!m_address_book[dest].destdata.erase(key))
3813         return false;
3814     return batch.EraseDestData(EncodeDestination(dest), key);
3815 }
3816 
LoadDestData(const CTxDestination & dest,const std::string & key,const std::string & value)3817 void CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
3818 {
3819     m_address_book[dest].destdata.insert(std::make_pair(key, value));
3820 }
3821 
GetDestData(const CTxDestination & dest,const std::string & key,std::string * value) const3822 bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
3823 {
3824     std::map<CTxDestination, CAddressBookData>::const_iterator i = m_address_book.find(dest);
3825     if(i != m_address_book.end())
3826     {
3827         CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
3828         if(j != i->second.destdata.end())
3829         {
3830             if(value)
3831                 *value = j->second;
3832             return true;
3833         }
3834     }
3835     return false;
3836 }
3837 
GetDestValues(const std::string & prefix) const3838 std::vector<std::string> CWallet::GetDestValues(const std::string& prefix) const
3839 {
3840     std::vector<std::string> values;
3841     for (const auto& address : m_address_book) {
3842         for (const auto& data : address.second.destdata) {
3843             if (!data.first.compare(0, prefix.size(), prefix)) {
3844                 values.emplace_back(data.second);
3845             }
3846         }
3847     }
3848     return values;
3849 }
3850 
MakeWalletDatabase(const std::string & name,const DatabaseOptions & options,DatabaseStatus & status,bilingual_str & error_string)3851 std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string)
3852 {
3853     // Do some checking on wallet path. It should be either a:
3854     //
3855     // 1. Path where a directory can be created.
3856     // 2. Path to an existing directory.
3857     // 3. Path to a symlink to a directory.
3858     // 4. For backwards compatibility, the name of a data file in -walletdir.
3859     const fs::path& wallet_path = fs::absolute(name, GetWalletDir());
3860     fs::file_type path_type = fs::symlink_status(wallet_path).type();
3861     if (!(path_type == fs::file_not_found || path_type == fs::directory_file ||
3862           (path_type == fs::symlink_file && fs::is_directory(wallet_path)) ||
3863           (path_type == fs::regular_file && fs::path(name).filename() == name))) {
3864         error_string = Untranslated(strprintf(
3865               "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
3866               "database/log.?????????? files can be stored, a location where such a directory could be created, "
3867               "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
3868               name, GetWalletDir()));
3869         status = DatabaseStatus::FAILED_BAD_PATH;
3870         return nullptr;
3871     }
3872     return MakeDatabase(wallet_path, options, status, error_string);
3873 }
3874 
Create(interfaces::Chain & chain,const std::string & name,std::unique_ptr<WalletDatabase> database,uint64_t wallet_creation_flags,bilingual_str & error,std::vector<bilingual_str> & warnings)3875 std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings)
3876 {
3877     const std::string& walletFile = database->Filename();
3878 
3879     chain.initMessage(_("Loading wallet...").translated);
3880 
3881     int64_t nStart = GetTimeMillis();
3882     bool fFirstRun = true;
3883     // TODO: Can't use std::make_shared because we need a custom deleter but
3884     // should be possible to use std::allocate_shared.
3885     std::shared_ptr<CWallet> walletInstance(new CWallet(&chain, name, std::move(database)), ReleaseWallet);
3886     DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
3887     if (nLoadWalletRet != DBErrors::LOAD_OK) {
3888         if (nLoadWalletRet == DBErrors::CORRUPT) {
3889             error = strprintf(_("Error loading %s: Wallet corrupted"), walletFile);
3890             return nullptr;
3891         }
3892         else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
3893         {
3894             warnings.push_back(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
3895                                            " or address book entries might be missing or incorrect."),
3896                 walletFile));
3897         }
3898         else if (nLoadWalletRet == DBErrors::TOO_NEW) {
3899             error = strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, PACKAGE_NAME);
3900             return nullptr;
3901         }
3902         else if (nLoadWalletRet == DBErrors::NEED_REWRITE)
3903         {
3904             error = strprintf(_("Wallet needed to be rewritten: restart %s to complete"), PACKAGE_NAME);
3905             return nullptr;
3906         }
3907         else {
3908             error = strprintf(_("Error loading %s"), walletFile);
3909             return nullptr;
3910         }
3911     }
3912 
3913     if (fFirstRun)
3914     {
3915         // ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
3916         walletInstance->SetMinVersion(FEATURE_LATEST);
3917 
3918         walletInstance->AddWalletFlags(wallet_creation_flags);
3919 
3920         // Only create LegacyScriptPubKeyMan when not descriptor wallet
3921         if (!walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
3922             walletInstance->SetupLegacyScriptPubKeyMan();
3923         }
3924 
3925         if (!(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) {
3926             LOCK(walletInstance->cs_wallet);
3927             if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
3928                 walletInstance->SetupDescriptorScriptPubKeyMans();
3929                 // SetupDescriptorScriptPubKeyMans already calls SetupGeneration for us so we don't need to call SetupGeneration separately
3930             } else {
3931                 // Legacy wallets need SetupGeneration here.
3932                 for (auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
3933                     if (!spk_man->SetupGeneration()) {
3934                         error = _("Unable to generate initial keys");
3935                         return nullptr;
3936                     }
3937                 }
3938             }
3939         }
3940 
3941         walletInstance->chainStateFlushed(chain.getTipLocator());
3942     } else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
3943         // Make it impossible to disable private keys after creation
3944         error = strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile);
3945         return NULL;
3946     } else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
3947         for (auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
3948             if (spk_man->HavePrivateKeys()) {
3949                 warnings.push_back(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
3950                 break;
3951             }
3952         }
3953     }
3954 
3955     if (!gArgs.GetArg("-addresstype", "").empty()) {
3956         if (!ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
3957             error = strprintf(_("Unknown address type '%s'"), gArgs.GetArg("-addresstype", ""));
3958             return nullptr;
3959         }
3960     }
3961 
3962     if (!gArgs.GetArg("-changetype", "").empty()) {
3963         OutputType out_type;
3964         if (!ParseOutputType(gArgs.GetArg("-changetype", ""), out_type)) {
3965             error = strprintf(_("Unknown change type '%s'"), gArgs.GetArg("-changetype", ""));
3966             return nullptr;
3967         }
3968         walletInstance->m_default_change_type = out_type;
3969     }
3970 
3971     if (gArgs.IsArgSet("-mintxfee")) {
3972         CAmount n = 0;
3973         if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
3974             error = AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", ""));
3975             return nullptr;
3976         }
3977         if (n > HIGH_TX_FEE_PER_KB) {
3978             warnings.push_back(AmountHighWarn("-mintxfee") + Untranslated(" ") +
3979                                _("This is the minimum transaction fee you pay on every transaction."));
3980         }
3981         walletInstance->m_min_fee = CFeeRate(n);
3982     }
3983 
3984     if (gArgs.IsArgSet("-maxapsfee")) {
3985         const std::string max_aps_fee{gArgs.GetArg("-maxapsfee", "")};
3986         CAmount n = 0;
3987         if (max_aps_fee == "-1") {
3988             n = -1;
3989         } else if (!ParseMoney(max_aps_fee, n)) {
3990             error = AmountErrMsg("maxapsfee", max_aps_fee);
3991             return nullptr;
3992         }
3993         if (n > HIGH_APS_FEE) {
3994             warnings.push_back(AmountHighWarn("-maxapsfee") + Untranslated(" ") +
3995                               _("This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection."));
3996         }
3997         walletInstance->m_max_aps_fee = n;
3998     }
3999 
4000     if (gArgs.IsArgSet("-fallbackfee")) {
4001         CAmount nFeePerK = 0;
4002         if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
4003             error = strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", ""));
4004             return nullptr;
4005         }
4006         if (nFeePerK > HIGH_TX_FEE_PER_KB) {
4007             warnings.push_back(AmountHighWarn("-fallbackfee") + Untranslated(" ") +
4008                                _("This is the transaction fee you may pay when fee estimates are not available."));
4009         }
4010         walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
4011     }
4012     // Disable fallback fee in case value was set to 0, enable if non-null value
4013     walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
4014 
4015     if (gArgs.IsArgSet("-discardfee")) {
4016         CAmount nFeePerK = 0;
4017         if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
4018             error = strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", ""));
4019             return nullptr;
4020         }
4021         if (nFeePerK > HIGH_TX_FEE_PER_KB) {
4022             warnings.push_back(AmountHighWarn("-discardfee") + Untranslated(" ") +
4023                                _("This is the transaction fee you may discard if change is smaller than dust at this level"));
4024         }
4025         walletInstance->m_discard_rate = CFeeRate(nFeePerK);
4026     }
4027     if (gArgs.IsArgSet("-paytxfee")) {
4028         CAmount nFeePerK = 0;
4029         if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
4030             error = AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", ""));
4031             return nullptr;
4032         }
4033         if (nFeePerK > HIGH_TX_FEE_PER_KB) {
4034             warnings.push_back(AmountHighWarn("-paytxfee") + Untranslated(" ") +
4035                                _("This is the transaction fee you will pay if you send a transaction."));
4036         }
4037         walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
4038         if (walletInstance->m_pay_tx_fee < chain.relayMinFee()) {
4039             error = strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
4040                 gArgs.GetArg("-paytxfee", ""), chain.relayMinFee().ToString());
4041             return nullptr;
4042         }
4043     }
4044 
4045     if (gArgs.IsArgSet("-maxtxfee")) {
4046         CAmount nMaxFee = 0;
4047         if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) {
4048             error = AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", ""));
4049             return nullptr;
4050         }
4051         if (nMaxFee > HIGH_MAX_TX_FEE) {
4052             warnings.push_back(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
4053         }
4054         if (CFeeRate(nMaxFee, 1000) < chain.relayMinFee()) {
4055             error = strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
4056                 gArgs.GetArg("-maxtxfee", ""), chain.relayMinFee().ToString());
4057             return nullptr;
4058         }
4059         walletInstance->m_default_max_tx_fee = nMaxFee;
4060     }
4061 
4062     if (chain.relayMinFee().GetFeePerK() > HIGH_TX_FEE_PER_KB) {
4063         warnings.push_back(AmountHighWarn("-minrelaytxfee") + Untranslated(" ") +
4064                            _("The wallet will avoid paying less than the minimum relay fee."));
4065     }
4066 
4067     walletInstance->m_confirm_target = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
4068     walletInstance->m_spend_zero_conf_change = gArgs.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
4069     walletInstance->m_signal_rbf = gArgs.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
4070 
4071     walletInstance->WalletLogPrintf("Wallet completed loading in %15dms\n", GetTimeMillis() - nStart);
4072 
4073     // Try to top up keypool. No-op if the wallet is locked.
4074     walletInstance->TopUpKeyPool();
4075 
4076     LOCK(walletInstance->cs_wallet);
4077 
4078     // Register wallet with validationinterface. It's done before rescan to avoid
4079     // missing block connections between end of rescan and validation subscribing.
4080     // Because of wallet lock being hold, block connection notifications are going to
4081     // be pending on the validation-side until lock release. It's likely to have
4082     // block processing duplicata (if rescan block range overlaps with notification one)
4083     // but we guarantee at least than wallet state is correct after notifications delivery.
4084     // This is temporary until rescan and notifications delivery are unified under same
4085     // interface.
4086     walletInstance->m_chain_notifications_handler = walletInstance->chain().handleNotifications(walletInstance);
4087 
4088     int rescan_height = 0;
4089     if (!gArgs.GetBoolArg("-rescan", false))
4090     {
4091         WalletBatch batch(*walletInstance->database);
4092         CBlockLocator locator;
4093         if (batch.ReadBestBlock(locator)) {
4094             if (const Optional<int> fork_height = chain.findLocatorFork(locator)) {
4095                 rescan_height = *fork_height;
4096             }
4097         }
4098     }
4099 
4100     const Optional<int> tip_height = chain.getHeight();
4101     if (tip_height) {
4102         walletInstance->m_last_block_processed = chain.getBlockHash(*tip_height);
4103         walletInstance->m_last_block_processed_height = *tip_height;
4104     } else {
4105         walletInstance->m_last_block_processed.SetNull();
4106         walletInstance->m_last_block_processed_height = -1;
4107     }
4108 
4109     if (tip_height && *tip_height != rescan_height)
4110     {
4111         // We can't rescan beyond non-pruned blocks, stop and throw an error.
4112         // This might happen if a user uses an old wallet within a pruned node
4113         // or if they ran -disablewallet for a longer time, then decided to re-enable
4114         if (chain.havePruned()) {
4115             // Exit early and print an error.
4116             // If a block is pruned after this check, we will load the wallet,
4117             // but fail the rescan with a generic error.
4118             int block_height = *tip_height;
4119             while (block_height > 0 && chain.haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
4120                 --block_height;
4121             }
4122 
4123             if (rescan_height != block_height) {
4124                 error = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
4125                 return nullptr;
4126             }
4127         }
4128 
4129         chain.initMessage(_("Rescanning...").translated);
4130         walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
4131 
4132         // No need to read and scan block if block was created before
4133         // our wallet birthday (as adjusted for block time variability)
4134         // The way the 'time_first_key' is initialized is just a workaround for the gcc bug #47679 since version 4.6.0.
4135         Optional<int64_t> time_first_key = MakeOptional(false, int64_t());;
4136         for (auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
4137             int64_t time = spk_man->GetTimeFirstKey();
4138             if (!time_first_key || time < *time_first_key) time_first_key = time;
4139         }
4140         if (time_first_key) {
4141             if (Optional<int> first_block = chain.findFirstBlockWithTimeAndHeight(*time_first_key - TIMESTAMP_WINDOW, rescan_height, nullptr)) {
4142                 rescan_height = *first_block;
4143             }
4144         }
4145 
4146         {
4147             WalletRescanReserver reserver(*walletInstance);
4148             if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, {} /* max height */, reserver, true /* update */).status)) {
4149                 error = _("Failed to rescan the wallet during initialization");
4150                 return nullptr;
4151             }
4152         }
4153         walletInstance->chainStateFlushed(chain.getTipLocator());
4154         walletInstance->database->IncrementUpdateCounter();
4155     }
4156 
4157     {
4158         LOCK(cs_wallets);
4159         for (auto& load_wallet : g_load_wallet_fns) {
4160             load_wallet(interfaces::MakeWallet(walletInstance));
4161         }
4162     }
4163 
4164     walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
4165 
4166     {
4167         walletInstance->WalletLogPrintf("setKeyPool.size() = %u\n",      walletInstance->GetKeyPoolSize());
4168         walletInstance->WalletLogPrintf("mapWallet.size() = %u\n",       walletInstance->mapWallet.size());
4169         walletInstance->WalletLogPrintf("m_address_book.size() = %u\n",  walletInstance->m_address_book.size());
4170     }
4171 
4172     return walletInstance;
4173 }
4174 
FindAddressBookEntry(const CTxDestination & dest,bool allow_change) const4175 const CAddressBookData* CWallet::FindAddressBookEntry(const CTxDestination& dest, bool allow_change) const
4176 {
4177     const auto& address_book_it = m_address_book.find(dest);
4178     if (address_book_it == m_address_book.end()) return nullptr;
4179     if ((!allow_change) && address_book_it->second.IsChange()) {
4180         return nullptr;
4181     }
4182     return &address_book_it->second;
4183 }
4184 
UpgradeWallet(int version,bilingual_str & error)4185 bool CWallet::UpgradeWallet(int version, bilingual_str& error)
4186 {
4187     int prev_version = GetVersion();
4188     if (version == 0) {
4189         WalletLogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
4190         version = FEATURE_LATEST;
4191     } else {
4192         WalletLogPrintf("Allowing wallet upgrade up to %i\n", version);
4193     }
4194     if (version < prev_version)
4195     {
4196         error = _("Cannot downgrade wallet");
4197         return false;
4198     }
4199 
4200     LOCK(cs_wallet);
4201 
4202     // Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT
4203     if (!CanSupportFeature(FEATURE_HD_SPLIT) && version >= FEATURE_HD_SPLIT && version < FEATURE_PRE_SPLIT_KEYPOOL) {
4204         error = _("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use version 169900 or no version specified.");
4205         return false;
4206     }
4207 
4208     // Permanently upgrade to the version
4209     SetMinVersion(GetClosestWalletFeature(version));
4210 
4211     for (auto spk_man : GetActiveScriptPubKeyMans()) {
4212         if (!spk_man->Upgrade(prev_version, version, error)) {
4213             return false;
4214         }
4215     }
4216     return true;
4217 }
4218 
postInitProcess()4219 void CWallet::postInitProcess()
4220 {
4221     LOCK(cs_wallet);
4222 
4223     // Add wallet transactions that aren't already in a block to mempool
4224     // Do this here as mempool requires genesis block to be loaded
4225     ReacceptWalletTransactions();
4226 
4227     // Update wallet transactions with current mempool transactions.
4228     chain().requestMempoolTransactions(*this);
4229 }
4230 
BackupWallet(const std::string & strDest) const4231 bool CWallet::BackupWallet(const std::string& strDest) const
4232 {
4233     return database->Backup(strDest);
4234 }
4235 
CKeyPool()4236 CKeyPool::CKeyPool()
4237 {
4238     nTime = GetTime();
4239     fInternal = false;
4240     m_pre_split = false;
4241 }
4242 
CKeyPool(const CPubKey & vchPubKeyIn,bool internalIn)4243 CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn)
4244 {
4245     nTime = GetTime();
4246     vchPubKey = vchPubKeyIn;
4247     fInternal = internalIn;
4248     m_pre_split = false;
4249 }
4250 
GetDepthInMainChain() const4251 int CWalletTx::GetDepthInMainChain() const
4252 {
4253     assert(pwallet != nullptr);
4254     AssertLockHeld(pwallet->cs_wallet);
4255     if (isUnconfirmed() || isAbandoned()) return 0;
4256 
4257     return (pwallet->GetLastBlockHeight() - m_confirm.block_height + 1) * (isConflicted() ? -1 : 1);
4258 }
4259 
GetBlocksToMaturity() const4260 int CWalletTx::GetBlocksToMaturity() const
4261 {
4262     if (!IsCoinBase())
4263         return 0;
4264     int chain_depth = GetDepthInMainChain();
4265     assert(chain_depth >= 0); // coinbase tx should not be conflicted
4266     return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
4267 }
4268 
IsImmatureCoinBase() const4269 bool CWalletTx::IsImmatureCoinBase() const
4270 {
4271     // note GetBlocksToMaturity is 0 for non-coinbase tx
4272     return GetBlocksToMaturity() > 0;
4273 }
4274 
GroupOutputs(const std::vector<COutput> & outputs,bool single_coin,const size_t max_ancestors) const4275 std::vector<OutputGroup> CWallet::GroupOutputs(const std::vector<COutput>& outputs, bool single_coin, const size_t max_ancestors) const {
4276     std::vector<OutputGroup> groups;
4277     std::map<CTxDestination, OutputGroup> gmap;
4278     std::set<CTxDestination> full_groups;
4279 
4280     for (const auto& output : outputs) {
4281         if (output.fSpendable) {
4282             CTxDestination dst;
4283             CInputCoin input_coin = output.GetInputCoin();
4284 
4285             size_t ancestors, descendants;
4286             chain().getTransactionAncestry(output.tx->GetHash(), ancestors, descendants);
4287             if (!single_coin && ExtractDestination(output.tx->tx->vout[output.i].scriptPubKey, dst)) {
4288                 auto it = gmap.find(dst);
4289                 if (it != gmap.end()) {
4290                     // Limit output groups to no more than OUTPUT_GROUP_MAX_ENTRIES
4291                     // number of entries, to protect against inadvertently creating
4292                     // a too-large transaction when using -avoidpartialspends to
4293                     // prevent breaking consensus or surprising users with a very
4294                     // high amount of fees.
4295                     if (it->second.m_outputs.size() >= OUTPUT_GROUP_MAX_ENTRIES) {
4296                         groups.push_back(it->second);
4297                         it->second = OutputGroup{};
4298                         full_groups.insert(dst);
4299                     }
4300                     it->second.Insert(input_coin, output.nDepth, output.tx->IsFromMe(ISMINE_ALL), ancestors, descendants);
4301                 } else {
4302                     gmap[dst].Insert(input_coin, output.nDepth, output.tx->IsFromMe(ISMINE_ALL), ancestors, descendants);
4303                 }
4304             } else {
4305                 groups.emplace_back(input_coin, output.nDepth, output.tx->IsFromMe(ISMINE_ALL), ancestors, descendants);
4306             }
4307         }
4308     }
4309     if (!single_coin) {
4310         for (auto& it : gmap) {
4311             auto& group = it.second;
4312             if (full_groups.count(it.first) > 0) {
4313                 // Make this unattractive as we want coin selection to avoid it if possible
4314                 group.m_ancestors = max_ancestors - 1;
4315             }
4316             groups.push_back(group);
4317         }
4318     }
4319     return groups;
4320 }
4321 
IsCrypted() const4322 bool CWallet::IsCrypted() const
4323 {
4324     return HasEncryptionKeys();
4325 }
4326 
IsLocked() const4327 bool CWallet::IsLocked() const
4328 {
4329     if (!IsCrypted()) {
4330         return false;
4331     }
4332     LOCK(cs_wallet);
4333     return vMasterKey.empty();
4334 }
4335 
Lock()4336 bool CWallet::Lock()
4337 {
4338     if (!IsCrypted())
4339         return false;
4340 
4341     {
4342         LOCK(cs_wallet);
4343         vMasterKey.clear();
4344     }
4345 
4346     NotifyStatusChanged(this);
4347     return true;
4348 }
4349 
Unlock(const CKeyingMaterial & vMasterKeyIn,bool accept_no_keys)4350 bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys)
4351 {
4352     {
4353         LOCK(cs_wallet);
4354         for (const auto& spk_man_pair : m_spk_managers) {
4355             if (!spk_man_pair.second->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) {
4356                 return false;
4357             }
4358         }
4359         vMasterKey = vMasterKeyIn;
4360     }
4361     NotifyStatusChanged(this);
4362     return true;
4363 }
4364 
GetActiveScriptPubKeyMans() const4365 std::set<ScriptPubKeyMan*> CWallet::GetActiveScriptPubKeyMans() const
4366 {
4367     std::set<ScriptPubKeyMan*> spk_mans;
4368     for (bool internal : {false, true}) {
4369         for (OutputType t : OUTPUT_TYPES) {
4370             auto spk_man = GetScriptPubKeyMan(t, internal);
4371             if (spk_man) {
4372                 spk_mans.insert(spk_man);
4373             }
4374         }
4375     }
4376     return spk_mans;
4377 }
4378 
GetAllScriptPubKeyMans() const4379 std::set<ScriptPubKeyMan*> CWallet::GetAllScriptPubKeyMans() const
4380 {
4381     std::set<ScriptPubKeyMan*> spk_mans;
4382     for (const auto& spk_man_pair : m_spk_managers) {
4383         spk_mans.insert(spk_man_pair.second.get());
4384     }
4385     return spk_mans;
4386 }
4387 
GetScriptPubKeyMan(const OutputType & type,bool internal) const4388 ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(const OutputType& type, bool internal) const
4389 {
4390     const std::map<OutputType, ScriptPubKeyMan*>& spk_managers = internal ? m_internal_spk_managers : m_external_spk_managers;
4391     std::map<OutputType, ScriptPubKeyMan*>::const_iterator it = spk_managers.find(type);
4392     if (it == spk_managers.end()) {
4393         WalletLogPrintf("%s scriptPubKey Manager for output type %d does not exist\n", internal ? "Internal" : "External", static_cast<int>(type));
4394         return nullptr;
4395     }
4396     return it->second;
4397 }
4398 
GetScriptPubKeyMans(const CScript & script,SignatureData & sigdata) const4399 std::set<ScriptPubKeyMan*> CWallet::GetScriptPubKeyMans(const CScript& script, SignatureData& sigdata) const
4400 {
4401     std::set<ScriptPubKeyMan*> spk_mans;
4402     for (const auto& spk_man_pair : m_spk_managers) {
4403         if (spk_man_pair.second->CanProvide(script, sigdata)) {
4404             spk_mans.insert(spk_man_pair.second.get());
4405         }
4406     }
4407     return spk_mans;
4408 }
4409 
GetScriptPubKeyMan(const CScript & script) const4410 ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(const CScript& script) const
4411 {
4412     SignatureData sigdata;
4413     for (const auto& spk_man_pair : m_spk_managers) {
4414         if (spk_man_pair.second->CanProvide(script, sigdata)) {
4415             return spk_man_pair.second.get();
4416         }
4417     }
4418     return nullptr;
4419 }
4420 
GetScriptPubKeyMan(const uint256 & id) const4421 ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(const uint256& id) const
4422 {
4423     if (m_spk_managers.count(id) > 0) {
4424         return m_spk_managers.at(id).get();
4425     }
4426     return nullptr;
4427 }
4428 
GetSolvingProvider(const CScript & script) const4429 std::unique_ptr<SigningProvider> CWallet::GetSolvingProvider(const CScript& script) const
4430 {
4431     SignatureData sigdata;
4432     return GetSolvingProvider(script, sigdata);
4433 }
4434 
GetSolvingProvider(const CScript & script,SignatureData & sigdata) const4435 std::unique_ptr<SigningProvider> CWallet::GetSolvingProvider(const CScript& script, SignatureData& sigdata) const
4436 {
4437     for (const auto& spk_man_pair : m_spk_managers) {
4438         if (spk_man_pair.second->CanProvide(script, sigdata)) {
4439             return spk_man_pair.second->GetSolvingProvider(script);
4440         }
4441     }
4442     return nullptr;
4443 }
4444 
GetLegacyScriptPubKeyMan() const4445 LegacyScriptPubKeyMan* CWallet::GetLegacyScriptPubKeyMan() const
4446 {
4447     if (IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
4448         return nullptr;
4449     }
4450     // Legacy wallets only have one ScriptPubKeyMan which is a LegacyScriptPubKeyMan.
4451     // Everything in m_internal_spk_managers and m_external_spk_managers point to the same legacyScriptPubKeyMan.
4452     auto it = m_internal_spk_managers.find(OutputType::LEGACY);
4453     if (it == m_internal_spk_managers.end()) return nullptr;
4454     return dynamic_cast<LegacyScriptPubKeyMan*>(it->second);
4455 }
4456 
GetOrCreateLegacyScriptPubKeyMan()4457 LegacyScriptPubKeyMan* CWallet::GetOrCreateLegacyScriptPubKeyMan()
4458 {
4459     SetupLegacyScriptPubKeyMan();
4460     return GetLegacyScriptPubKeyMan();
4461 }
4462 
SetupLegacyScriptPubKeyMan()4463 void CWallet::SetupLegacyScriptPubKeyMan()
4464 {
4465     if (!m_internal_spk_managers.empty() || !m_external_spk_managers.empty() || !m_spk_managers.empty() || IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
4466         return;
4467     }
4468 
4469     auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new LegacyScriptPubKeyMan(*this));
4470     for (const auto& type : OUTPUT_TYPES) {
4471         m_internal_spk_managers[type] = spk_manager.get();
4472         m_external_spk_managers[type] = spk_manager.get();
4473     }
4474     m_spk_managers[spk_manager->GetID()] = std::move(spk_manager);
4475 }
4476 
GetEncryptionKey() const4477 const CKeyingMaterial& CWallet::GetEncryptionKey() const
4478 {
4479     return vMasterKey;
4480 }
4481 
HasEncryptionKeys() const4482 bool CWallet::HasEncryptionKeys() const
4483 {
4484     return !mapMasterKeys.empty();
4485 }
4486 
ConnectScriptPubKeyManNotifiers()4487 void CWallet::ConnectScriptPubKeyManNotifiers()
4488 {
4489     for (const auto& spk_man : GetActiveScriptPubKeyMans()) {
4490         spk_man->NotifyWatchonlyChanged.connect(NotifyWatchonlyChanged);
4491         spk_man->NotifyCanGetAddressesChanged.connect(NotifyCanGetAddressesChanged);
4492     }
4493 }
4494 
LoadDescriptorScriptPubKeyMan(uint256 id,WalletDescriptor & desc)4495 void CWallet::LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor& desc)
4496 {
4497     auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, desc));
4498     m_spk_managers[id] = std::move(spk_manager);
4499 }
4500 
SetupDescriptorScriptPubKeyMans()4501 void CWallet::SetupDescriptorScriptPubKeyMans()
4502 {
4503     AssertLockHeld(cs_wallet);
4504 
4505     // Make a seed
4506     CKey seed_key;
4507     seed_key.MakeNewKey(true);
4508     CPubKey seed = seed_key.GetPubKey();
4509     assert(seed_key.VerifyPubKey(seed));
4510 
4511     // Get the extended key
4512     CExtKey master_key;
4513     master_key.SetSeed(seed_key.begin(), seed_key.size());
4514 
4515     for (bool internal : {false, true}) {
4516         for (OutputType t : OUTPUT_TYPES) {
4517             auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, internal));
4518             if (IsCrypted()) {
4519                 if (IsLocked()) {
4520                     throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors");
4521                 }
4522                 if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey, nullptr)) {
4523                     throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors");
4524                 }
4525             }
4526             spk_manager->SetupDescriptorGeneration(master_key, t);
4527             uint256 id = spk_manager->GetID();
4528             m_spk_managers[id] = std::move(spk_manager);
4529             AddActiveScriptPubKeyMan(id, t, internal);
4530         }
4531     }
4532 }
4533 
AddActiveScriptPubKeyMan(uint256 id,OutputType type,bool internal)4534 void CWallet::AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
4535 {
4536     WalletBatch batch(*database);
4537     if (!batch.WriteActiveScriptPubKeyMan(static_cast<uint8_t>(type), id, internal)) {
4538         throw std::runtime_error(std::string(__func__) + ": writing active ScriptPubKeyMan id failed");
4539     }
4540     LoadActiveScriptPubKeyMan(id, type, internal);
4541 }
4542 
LoadActiveScriptPubKeyMan(uint256 id,OutputType type,bool internal)4543 void CWallet::LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
4544 {
4545     WalletLogPrintf("Setting spkMan to active: id = %s, type = %d, internal = %d\n", id.ToString(), static_cast<int>(type), static_cast<int>(internal));
4546     auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
4547     auto spk_man = m_spk_managers.at(id).get();
4548     spk_man->SetInternal(internal);
4549     spk_mans[type] = spk_man;
4550 
4551     NotifyCanGetAddressesChanged();
4552 }
4553 
IsLegacy() const4554 bool CWallet::IsLegacy() const
4555 {
4556     if (m_internal_spk_managers.count(OutputType::LEGACY) == 0) {
4557         return false;
4558     }
4559     auto spk_man = dynamic_cast<LegacyScriptPubKeyMan*>(m_internal_spk_managers.at(OutputType::LEGACY));
4560     return spk_man != nullptr;
4561 }
4562 
GetDescriptorScriptPubKeyMan(const WalletDescriptor & desc) const4563 DescriptorScriptPubKeyMan* CWallet::GetDescriptorScriptPubKeyMan(const WalletDescriptor& desc) const
4564 {
4565     for (auto& spk_man_pair : m_spk_managers) {
4566         // Try to downcast to DescriptorScriptPubKeyMan then check if the descriptors match
4567         DescriptorScriptPubKeyMan* spk_manager = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man_pair.second.get());
4568         if (spk_manager != nullptr && spk_manager->HasWalletDescriptor(desc)) {
4569             return spk_manager;
4570         }
4571     }
4572 
4573     return nullptr;
4574 }
4575 
AddWalletDescriptor(WalletDescriptor & desc,const FlatSigningProvider & signing_provider,const std::string & label,bool internal)4576 ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal)
4577 {
4578     if (!IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
4579         WalletLogPrintf("Cannot add WalletDescriptor to a non-descriptor wallet\n");
4580         return nullptr;
4581     }
4582 
4583     LOCK(cs_wallet);
4584     auto new_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, desc));
4585 
4586     // If we already have this descriptor, remove it from the maps but add the existing cache to desc
4587     auto old_spk_man = GetDescriptorScriptPubKeyMan(desc);
4588     if (old_spk_man) {
4589         WalletLogPrintf("Update existing descriptor: %s\n", desc.descriptor->ToString());
4590 
4591         {
4592             LOCK(old_spk_man->cs_desc_man);
4593             new_spk_man->SetCache(old_spk_man->GetWalletDescriptor().cache);
4594         }
4595 
4596         // Remove from maps of active spkMans
4597         auto old_spk_man_id = old_spk_man->GetID();
4598         for (bool internal : {false, true}) {
4599             for (OutputType t : OUTPUT_TYPES) {
4600                 auto active_spk_man = GetScriptPubKeyMan(t, internal);
4601                 if (active_spk_man && active_spk_man->GetID() == old_spk_man_id) {
4602                     if (internal) {
4603                         m_internal_spk_managers.erase(t);
4604                     } else {
4605                         m_external_spk_managers.erase(t);
4606                     }
4607                     break;
4608                 }
4609             }
4610         }
4611         m_spk_managers.erase(old_spk_man_id);
4612     }
4613 
4614     // Add the private keys to the descriptor
4615     for (const auto& entry : signing_provider.keys) {
4616         const CKey& key = entry.second;
4617         new_spk_man->AddDescriptorKey(key, key.GetPubKey());
4618     }
4619 
4620     // Top up key pool, the manager will generate new scriptPubKeys internally
4621     if (!new_spk_man->TopUp()) {
4622         WalletLogPrintf("Could not top up scriptPubKeys\n");
4623         return nullptr;
4624     }
4625 
4626     // Apply the label if necessary
4627     // Note: we disable labels for ranged descriptors
4628     if (!desc.descriptor->IsRange()) {
4629         auto script_pub_keys = new_spk_man->GetScriptPubKeys();
4630         if (script_pub_keys.empty()) {
4631             WalletLogPrintf("Could not generate scriptPubKeys (cache is empty)\n");
4632             return nullptr;
4633         }
4634 
4635         CTxDestination dest;
4636         if (!internal && ExtractDestination(script_pub_keys.at(0), dest)) {
4637             SetAddressBook(dest, label, "receive");
4638         }
4639     }
4640 
4641     // Save the descriptor to memory
4642     auto ret = new_spk_man.get();
4643     m_spk_managers[new_spk_man->GetID()] = std::move(new_spk_man);
4644 
4645     // Save the descriptor to DB
4646     ret->WriteDescriptor();
4647 
4648     return ret;
4649 }
4650