Bitcoin Core  24.1.0
P2P Digital Currency
wallet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 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/amount.h>
10 #include <consensus/consensus.h>
11 #include <consensus/validation.h>
12 #include <external_signer.h>
13 #include <fs.h>
14 #include <interfaces/chain.h>
15 #include <interfaces/wallet.h>
16 #include <key.h>
17 #include <key_io.h>
18 #include <outputtype.h>
19 #include <policy/fees.h>
20 #include <policy/policy.h>
21 #include <primitives/block.h>
22 #include <primitives/transaction.h>
23 #include <psbt.h>
24 #include <random.h>
25 #include <script/descriptor.h>
26 #include <script/script.h>
27 #include <script/signingprovider.h>
28 #include <support/cleanse.h>
29 #include <txmempool.h>
30 #include <util/bip32.h>
31 #include <util/check.h>
32 #include <util/error.h>
33 #include <util/fees.h>
34 #include <util/moneystr.h>
35 #include <util/rbf.h>
36 #include <util/string.h>
37 #include <util/translation.h>
38 #include <wallet/coincontrol.h>
39 #include <wallet/context.h>
40 #include <wallet/fees.h>
42 
43 #include <univalue.h>
44 
45 #include <algorithm>
46 #include <assert.h>
47 #include <optional>
48 
50 
51 namespace wallet {
52 const std::map<uint64_t,std::string> WALLET_FLAG_CAVEATS{
54  "You need to rescan the blockchain in order to correctly mark used "
55  "destinations in the past. Until this is done, some destinations may "
56  "be considered unused, even if the opposite is the case."
57  },
58 };
59 
60 bool AddWalletSetting(interfaces::Chain& chain, const std::string& wallet_name)
61 {
62  util::SettingsValue setting_value = chain.getRwSetting("wallet");
63  if (!setting_value.isArray()) setting_value.setArray();
64  for (const util::SettingsValue& value : setting_value.getValues()) {
65  if (value.isStr() && value.get_str() == wallet_name) return true;
66  }
67  setting_value.push_back(wallet_name);
68  return chain.updateRwSetting("wallet", setting_value);
69 }
70 
71 bool RemoveWalletSetting(interfaces::Chain& chain, const std::string& wallet_name)
72 {
73  util::SettingsValue setting_value = chain.getRwSetting("wallet");
74  if (!setting_value.isArray()) return true;
76  for (const util::SettingsValue& value : setting_value.getValues()) {
77  if (!value.isStr() || value.get_str() != wallet_name) new_value.push_back(value);
78  }
79  if (new_value.size() == setting_value.size()) return true;
80  return chain.updateRwSetting("wallet", new_value);
81 }
82 
84  const std::string& wallet_name,
85  std::optional<bool> load_on_startup,
86  std::vector<bilingual_str>& warnings)
87 {
88  if (!load_on_startup) return;
89  if (load_on_startup.value() && !AddWalletSetting(chain, wallet_name)) {
90  warnings.emplace_back(Untranslated("Wallet load on startup setting could not be updated, so wallet may not be loaded next node startup."));
91  } else if (!load_on_startup.value() && !RemoveWalletSetting(chain, wallet_name)) {
92  warnings.emplace_back(Untranslated("Wallet load on startup setting could not be updated, so wallet may still be loaded next node startup."));
93  }
94 }
95 
102 {
103  if (chain.isInMempool(tx.GetHash())) {
104  tx.m_state = TxStateInMempool();
105  } else if (tx.state<TxStateInMempool>()) {
106  tx.m_state = TxStateInactive();
107  }
108 }
109 
110 bool AddWallet(WalletContext& context, const std::shared_ptr<CWallet>& wallet)
111 {
113  assert(wallet);
114  std::vector<std::shared_ptr<CWallet>>::const_iterator i = std::find(context.wallets.begin(), context.wallets.end(), wallet);
115  if (i != context.wallets.end()) return false;
116  context.wallets.push_back(wallet);
117  wallet->ConnectScriptPubKeyManNotifiers();
118  wallet->NotifyCanGetAddressesChanged();
119  return true;
120 }
121 
122 bool RemoveWallet(WalletContext& context, const std::shared_ptr<CWallet>& wallet, std::optional<bool> load_on_start, std::vector<bilingual_str>& warnings)
123 {
124  assert(wallet);
125 
126  interfaces::Chain& chain = wallet->chain();
127  std::string name = wallet->GetName();
128 
129  // Unregister with the validation interface which also drops shared ponters.
130  wallet->m_chain_notifications_handler.reset();
132  std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(context.wallets.begin(), context.wallets.end(), wallet);
133  if (i == context.wallets.end()) return false;
134  context.wallets.erase(i);
135 
136  // Write the wallet setting
137  UpdateWalletSetting(chain, name, load_on_start, warnings);
138 
139  return true;
140 }
141 
142 bool RemoveWallet(WalletContext& context, const std::shared_ptr<CWallet>& wallet, std::optional<bool> load_on_start)
143 {
144  std::vector<bilingual_str> warnings;
145  return RemoveWallet(context, wallet, load_on_start, warnings);
146 }
147 
148 std::vector<std::shared_ptr<CWallet>> GetWallets(WalletContext& context)
149 {
151  return context.wallets;
152 }
153 
154 std::shared_ptr<CWallet> GetDefaultWallet(WalletContext& context, size_t& count)
155 {
157  count = context.wallets.size();
158  return count == 1 ? context.wallets[0] : nullptr;
159 }
160 
161 std::shared_ptr<CWallet> GetWallet(WalletContext& context, const std::string& name)
162 {
164  for (const std::shared_ptr<CWallet>& wallet : context.wallets) {
165  if (wallet->GetName() == name) return wallet;
166  }
167  return nullptr;
168 }
169 
170 std::unique_ptr<interfaces::Handler> HandleLoadWallet(WalletContext& context, LoadWalletFn load_wallet)
171 {
173  auto it = context.wallet_load_fns.emplace(context.wallet_load_fns.end(), std::move(load_wallet));
174  return interfaces::MakeHandler([&context, it] { LOCK(context.wallets_mutex); context.wallet_load_fns.erase(it); });
175 }
176 
177 void NotifyWalletLoaded(WalletContext& context, const std::shared_ptr<CWallet>& wallet)
178 {
180  for (auto& load_wallet : context.wallet_load_fns) {
181  load_wallet(interfaces::MakeWallet(context, wallet));
182  }
183 }
184 
187 static std::condition_variable g_wallet_release_cv;
188 static std::set<std::string> g_loading_wallet_set GUARDED_BY(g_loading_wallet_mutex);
189 static std::set<std::string> g_unloading_wallet_set GUARDED_BY(g_wallet_release_mutex);
190 
191 // Custom deleter for shared_ptr<CWallet>.
193 {
194  const std::string name = wallet->GetName();
195  wallet->WalletLogPrintf("Releasing wallet\n");
196  wallet->Flush();
197  delete wallet;
198  // Wallet is now released, notify UnloadWallet, if any.
199  {
201  if (g_unloading_wallet_set.erase(name) == 0) {
202  // UnloadWallet was not called for this wallet, all done.
203  return;
204  }
205  }
206  g_wallet_release_cv.notify_all();
207 }
208 
209 void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
210 {
211  // Mark wallet for unloading.
212  const std::string name = wallet->GetName();
213  {
215  auto it = g_unloading_wallet_set.insert(name);
216  assert(it.second);
217  }
218  // The wallet can be in use so it's not possible to explicitly unload here.
219  // Notify the unload intent so that all remaining shared pointers are
220  // released.
221  wallet->NotifyUnload();
222 
223  // Time to ditch our shared_ptr and wait for ReleaseWallet call.
224  wallet.reset();
225  {
227  while (g_unloading_wallet_set.count(name) == 1) {
228  g_wallet_release_cv.wait(lock);
229  }
230  }
231 }
232 
233 namespace {
234 std::shared_ptr<CWallet> LoadWalletInternal(WalletContext& context, const std::string& name, std::optional<bool> load_on_start, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
235 {
236  try {
237  std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(name, options, status, error);
238  if (!database) {
239  error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error;
240  return nullptr;
241  }
242 
243  context.chain->initMessage(_("Loading wallet…").translated);
244  const std::shared_ptr<CWallet> wallet = CWallet::Create(context, name, std::move(database), options.create_flags, error, warnings);
245  if (!wallet) {
246  error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error;
248  return nullptr;
249  }
250 
253  wallet->postInitProcess();
254 
255  // Write the wallet setting
256  UpdateWalletSetting(*context.chain, name, load_on_start, warnings);
257 
258  return wallet;
259  } catch (const std::runtime_error& e) {
260  error = Untranslated(e.what());
262  return nullptr;
263  }
264 }
265 } // namespace
266 
267 std::shared_ptr<CWallet> LoadWallet(WalletContext& context, const std::string& name, std::optional<bool> load_on_start, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
268 {
269  auto result = WITH_LOCK(g_loading_wallet_mutex, return g_loading_wallet_set.insert(name));
270  if (!result.second) {
271  error = Untranslated("Wallet already loading.");
273  return nullptr;
274  }
275  auto wallet = LoadWalletInternal(context, name, load_on_start, options, status, error, warnings);
276  WITH_LOCK(g_loading_wallet_mutex, g_loading_wallet_set.erase(result.first));
277  return wallet;
278 }
279 
280 std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string& name, std::optional<bool> load_on_start, DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
281 {
282  uint64_t wallet_creation_flags = options.create_flags;
283  const SecureString& passphrase = options.create_passphrase;
284 
285  if (wallet_creation_flags & WALLET_FLAG_DESCRIPTORS) options.require_format = DatabaseFormat::SQLITE;
286 
287  // Indicate that the wallet is actually supposed to be blank and not just blank to make it encrypted
288  bool create_blank = (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET);
289 
290  // Born encrypted wallets need to be created blank first.
291  if (!passphrase.empty()) {
292  wallet_creation_flags |= WALLET_FLAG_BLANK_WALLET;
293  }
294 
295  // Private keys must be disabled for an external signer wallet
296  if ((wallet_creation_flags & WALLET_FLAG_EXTERNAL_SIGNER) && !(wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
297  error = Untranslated("Private keys must be disabled when using an external signer");
299  return nullptr;
300  }
301 
302  // Descriptor support must be enabled for an external signer wallet
303  if ((wallet_creation_flags & WALLET_FLAG_EXTERNAL_SIGNER) && !(wallet_creation_flags & WALLET_FLAG_DESCRIPTORS)) {
304  error = Untranslated("Descriptor support must be enabled when using an external signer");
306  return nullptr;
307  }
308 
309  // Do not allow a passphrase when private keys are disabled
310  if (!passphrase.empty() && (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
311  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.");
313  return nullptr;
314  }
315 
316  // Wallet::Verify will check if we're trying to create a wallet with a duplicate name.
317  std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(name, options, status, error);
318  if (!database) {
319  error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error;
321  return nullptr;
322  }
323 
324  // Make the wallet
325  context.chain->initMessage(_("Loading wallet…").translated);
326  const std::shared_ptr<CWallet> wallet = CWallet::Create(context, name, std::move(database), wallet_creation_flags, error, warnings);
327  if (!wallet) {
328  error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error;
330  return nullptr;
331  }
332 
333  // Encrypt the wallet
334  if (!passphrase.empty() && !(wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
335  if (!wallet->EncryptWallet(passphrase)) {
336  error = Untranslated("Error: Wallet created but failed to encrypt.");
338  return nullptr;
339  }
340  if (!create_blank) {
341  // Unlock the wallet
342  if (!wallet->Unlock(passphrase)) {
343  error = Untranslated("Error: Wallet was encrypted but could not be unlocked");
345  return nullptr;
346  }
347 
348  // Set a seed for the wallet
349  {
350  LOCK(wallet->cs_wallet);
351  if (wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
352  wallet->SetupDescriptorScriptPubKeyMans();
353  } else {
354  for (auto spk_man : wallet->GetActiveScriptPubKeyMans()) {
355  if (!spk_man->SetupGeneration()) {
356  error = Untranslated("Unable to generate initial keys");
358  return nullptr;
359  }
360  }
361  }
362  }
363 
364  // Relock the wallet
365  wallet->Lock();
366  }
367  }
368 
371  wallet->postInitProcess();
372 
373  // Write the wallet settings
374  UpdateWalletSetting(*context.chain, name, load_on_start, warnings);
375 
376  // Legacy wallets are being deprecated, warn if a newly created wallet is legacy
377  if (!(wallet_creation_flags & WALLET_FLAG_DESCRIPTORS)) {
378  warnings.push_back(_("Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future."));
379  }
380 
381  status = DatabaseStatus::SUCCESS;
382  return wallet;
383 }
384 
385 std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& backup_file, const std::string& wallet_name, std::optional<bool> load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
386 {
387  DatabaseOptions options;
388  ReadDatabaseArgs(*context.args, options);
389  options.require_existing = true;
390 
391  const fs::path wallet_path = fsbridge::AbsPathJoin(GetWalletDir(), fs::u8path(wallet_name));
392  auto wallet_file = wallet_path / "wallet.dat";
393  std::shared_ptr<CWallet> wallet;
394 
395  try {
396  if (!fs::exists(backup_file)) {
397  error = Untranslated("Backup file does not exist");
399  return nullptr;
400  }
401 
402  if (fs::exists(wallet_path) || !TryCreateDirectories(wallet_path)) {
403  error = Untranslated(strprintf("Failed to create database path '%s'. Database already exists.", fs::PathToString(wallet_path)));
405  return nullptr;
406  }
407 
408  fs::copy_file(backup_file, wallet_file, fs::copy_options::none);
409 
410  wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings);
411  } catch (const std::exception& e) {
412  assert(!wallet);
413  if (!error.empty()) error += Untranslated("\n");
414  error += strprintf(Untranslated("Unexpected exception: %s"), e.what());
415  }
416  if (!wallet) {
417  fs::remove(wallet_file);
418  fs::remove(wallet_path);
419  }
420 
421  return wallet;
422 }
423 
429 const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
430 {
432  const auto it = mapWallet.find(hash);
433  if (it == mapWallet.end())
434  return nullptr;
435  return &(it->second);
436 }
437 
439 {
441  return;
442  }
443 
444  auto spk_man = GetLegacyScriptPubKeyMan();
445  if (!spk_man) {
446  return;
447  }
448 
449  spk_man->UpgradeKeyMetadata();
450  SetWalletFlag(WALLET_FLAG_KEY_ORIGIN_METADATA);
451 }
452 
454 {
456  return;
457  }
458 
459  for (ScriptPubKeyMan* spkm : GetAllScriptPubKeyMans()) {
460  DescriptorScriptPubKeyMan* desc_spkm = dynamic_cast<DescriptorScriptPubKeyMan*>(spkm);
461  desc_spkm->UpgradeDescriptorCache();
462  }
464 }
465 
466 bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys)
467 {
468  CCrypter crypter;
469  CKeyingMaterial _vMasterKey;
470 
471  {
472  LOCK(cs_wallet);
473  for (const MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
474  {
475  if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
476  return false;
477  if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
478  continue; // try another master key
479  if (Unlock(_vMasterKey, accept_no_keys)) {
480  // Now that we've unlocked, upgrade the key metadata
482  // Now that we've unlocked, upgrade the descriptor cache
484  return true;
485  }
486  }
487  }
488  return false;
489 }
490 
491 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
492 {
493  bool fWasLocked = IsLocked();
494 
495  {
496  LOCK(cs_wallet);
497  Lock();
498 
499  CCrypter crypter;
500  CKeyingMaterial _vMasterKey;
501  for (MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
502  {
503  if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
504  return false;
505  if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
506  return false;
507  if (Unlock(_vMasterKey))
508  {
509  int64_t nStartTime = GetTimeMillis();
510  crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
511  pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))));
512 
513  nStartTime = GetTimeMillis();
514  crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
515  pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
516 
517  if (pMasterKey.second.nDeriveIterations < 25000)
518  pMasterKey.second.nDeriveIterations = 25000;
519 
520  WalletLogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
521 
522  if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
523  return false;
524  if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
525  return false;
526  WalletBatch(GetDatabase()).WriteMasterKey(pMasterKey.first, pMasterKey.second);
527  if (fWasLocked)
528  Lock();
529  return true;
530  }
531  }
532  }
533 
534  return false;
535 }
536 
538 {
539  // Don't update the best block until the chain is attached so that in case of a shutdown,
540  // the rescan will be restarted at next startup.
541  if (m_attaching_chain) {
542  return;
543  }
544  WalletBatch batch(GetDatabase());
545  batch.WriteBestBlock(loc);
546 }
547 
548 void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in)
549 {
550  LOCK(cs_wallet);
551  if (nWalletVersion >= nVersion)
552  return;
553  WalletLogPrintf("Setting minversion to %d\n", nVersion);
554  nWalletVersion = nVersion;
555 
556  {
557  WalletBatch* batch = batch_in ? batch_in : new WalletBatch(GetDatabase());
558  if (nWalletVersion > 40000)
559  batch->WriteMinVersion(nWalletVersion);
560  if (!batch_in)
561  delete batch;
562  }
563 }
564 
565 std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
566 {
567  std::set<uint256> result;
569 
570  const auto it = mapWallet.find(txid);
571  if (it == mapWallet.end())
572  return result;
573  const CWalletTx& wtx = it->second;
574 
575  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
576 
577  for (const CTxIn& txin : wtx.tx->vin)
578  {
579  if (mapTxSpends.count(txin.prevout) <= 1)
580  continue; // No conflict if zero or one spends
581  range = mapTxSpends.equal_range(txin.prevout);
582  for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
583  result.insert(_it->second);
584  }
585  return result;
586 }
587 
589 {
591  const uint256& txid = tx->GetHash();
592  for (unsigned int i = 0; i < tx->vout.size(); ++i) {
593  if (IsSpent(COutPoint(txid, i))) {
594  return true;
595  }
596  }
597  return false;
598 }
599 
601 {
602  GetDatabase().Flush();
603 }
604 
606 {
607  GetDatabase().Close();
608 }
609 
610 void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> range)
611 {
612  // We want all the wallet transactions in range to have the same metadata as
613  // the oldest (smallest nOrderPos).
614  // So: find smallest nOrderPos:
615 
616  int nMinOrderPos = std::numeric_limits<int>::max();
617  const CWalletTx* copyFrom = nullptr;
618  for (TxSpends::iterator it = range.first; it != range.second; ++it) {
619  const CWalletTx* wtx = &mapWallet.at(it->second);
620  if (wtx->nOrderPos < nMinOrderPos) {
621  nMinOrderPos = wtx->nOrderPos;
622  copyFrom = wtx;
623  }
624  }
625 
626  if (!copyFrom) {
627  return;
628  }
629 
630  // Now copy data from copyFrom to rest:
631  for (TxSpends::iterator it = range.first; it != range.second; ++it)
632  {
633  const uint256& hash = it->second;
634  CWalletTx* copyTo = &mapWallet.at(hash);
635  if (copyFrom == copyTo) continue;
636  assert(copyFrom && "Oldest wallet transaction in range assumed to have been found.");
637  if (!copyFrom->IsEquivalentTo(*copyTo)) continue;
638  copyTo->mapValue = copyFrom->mapValue;
639  copyTo->vOrderForm = copyFrom->vOrderForm;
640  // fTimeReceivedIsTxTime not copied on purpose
641  // nTimeReceived not copied on purpose
642  copyTo->nTimeSmart = copyFrom->nTimeSmart;
643  copyTo->fFromMe = copyFrom->fFromMe;
644  // nOrderPos not copied on purpose
645  // cached members not copied on purpose
646  }
647 }
648 
653 bool CWallet::IsSpent(const COutPoint& outpoint) const
654 {
655  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
656  range = mapTxSpends.equal_range(outpoint);
657 
658  for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
659  const uint256& wtxid = it->second;
660  const auto mit = mapWallet.find(wtxid);
661  if (mit != mapWallet.end()) {
662  int depth = GetTxDepthInMainChain(mit->second);
663  if (depth > 0 || (depth == 0 && !mit->second.isAbandoned()))
664  return true; // Spent
665  }
666  }
667  return false;
668 }
669 
670 void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch)
671 {
672  mapTxSpends.insert(std::make_pair(outpoint, wtxid));
673 
674  if (batch) {
675  UnlockCoin(outpoint, batch);
676  } else {
677  WalletBatch temp_batch(GetDatabase());
678  UnlockCoin(outpoint, &temp_batch);
679  }
680 
681  std::pair<TxSpends::iterator, TxSpends::iterator> range;
682  range = mapTxSpends.equal_range(outpoint);
683  SyncMetaData(range);
684 }
685 
686 
688 {
689  if (wtx.IsCoinBase()) // Coinbases don't spend anything!
690  return;
691 
692  for (const CTxIn& txin : wtx.tx->vin)
693  AddToSpends(txin.prevout, wtx.GetHash(), batch);
694 }
695 
696 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
697 {
698  if (IsCrypted())
699  return false;
700 
701  CKeyingMaterial _vMasterKey;
702 
703  _vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
704  GetStrongRandBytes(_vMasterKey);
705 
706  CMasterKey kMasterKey;
707 
708  kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
709  GetStrongRandBytes(kMasterKey.vchSalt);
710 
711  CCrypter crypter;
712  int64_t nStartTime = GetTimeMillis();
713  crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
714  kMasterKey.nDeriveIterations = static_cast<unsigned int>(2500000 / ((double)(GetTimeMillis() - nStartTime)));
715 
716  nStartTime = GetTimeMillis();
717  crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
718  kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
719 
720  if (kMasterKey.nDeriveIterations < 25000)
721  kMasterKey.nDeriveIterations = 25000;
722 
723  WalletLogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
724 
725  if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
726  return false;
727  if (!crypter.Encrypt(_vMasterKey, kMasterKey.vchCryptedKey))
728  return false;
729 
730  {
731  LOCK(cs_wallet);
732  mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
733  WalletBatch* encrypted_batch = new WalletBatch(GetDatabase());
734  if (!encrypted_batch->TxnBegin()) {
735  delete encrypted_batch;
736  encrypted_batch = nullptr;
737  return false;
738  }
739  encrypted_batch->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
740 
741  for (const auto& spk_man_pair : m_spk_managers) {
742  auto spk_man = spk_man_pair.second.get();
743  if (!spk_man->Encrypt(_vMasterKey, encrypted_batch)) {
744  encrypted_batch->TxnAbort();
745  delete encrypted_batch;
746  encrypted_batch = nullptr;
747  // We now probably have half of our keys encrypted in memory, and half not...
748  // die and let the user reload the unencrypted wallet.
749  assert(false);
750  }
751  }
752 
753  // Encryption was introduced in version 0.4.0
754  SetMinVersion(FEATURE_WALLETCRYPT, encrypted_batch);
755 
756  if (!encrypted_batch->TxnCommit()) {
757  delete encrypted_batch;
758  encrypted_batch = nullptr;
759  // We now have keys encrypted in memory, but not on disk...
760  // die to avoid confusion and let the user reload the unencrypted wallet.
761  assert(false);
762  }
763 
764  delete encrypted_batch;
765  encrypted_batch = nullptr;
766 
767  Lock();
768  Unlock(strWalletPassphrase);
769 
770  // If we are using descriptors, make new descriptors with a new seed
773  } else if (auto spk_man = GetLegacyScriptPubKeyMan()) {
774  // if we are using HD, replace the HD seed with a new one
775  if (spk_man->IsHDEnabled()) {
776  if (!spk_man->SetupGeneration(true)) {
777  return false;
778  }
779  }
780  }
781  Lock();
782 
783  // Need to completely rewrite the wallet file; if we don't, bdb might keep
784  // bits of the unencrypted private key in slack space in the database file.
785  GetDatabase().Rewrite();
786 
787  // BDB seems to have a bad habit of writing old data into
788  // slack space in .dat files; that is bad if the old data is
789  // unencrypted private keys. So:
791 
792  }
793  NotifyStatusChanged(this);
794 
795  return true;
796 }
797 
799 {
800  LOCK(cs_wallet);
801  WalletBatch batch(GetDatabase());
802 
803  // Old wallets didn't have any defined order for transactions
804  // Probably a bad idea to change the output of this
805 
806  // First: get all CWalletTx into a sorted-by-time multimap.
807  typedef std::multimap<int64_t, CWalletTx*> TxItems;
808  TxItems txByTime;
809 
810  for (auto& entry : mapWallet)
811  {
812  CWalletTx* wtx = &entry.second;
813  txByTime.insert(std::make_pair(wtx->nTimeReceived, wtx));
814  }
815 
816  nOrderPosNext = 0;
817  std::vector<int64_t> nOrderPosOffsets;
818  for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it)
819  {
820  CWalletTx *const pwtx = (*it).second;
821  int64_t& nOrderPos = pwtx->nOrderPos;
822 
823  if (nOrderPos == -1)
824  {
825  nOrderPos = nOrderPosNext++;
826  nOrderPosOffsets.push_back(nOrderPos);
827 
828  if (!batch.WriteTx(*pwtx))
829  return DBErrors::LOAD_FAIL;
830  }
831  else
832  {
833  int64_t nOrderPosOff = 0;
834  for (const int64_t& nOffsetStart : nOrderPosOffsets)
835  {
836  if (nOrderPos >= nOffsetStart)
837  ++nOrderPosOff;
838  }
839  nOrderPos += nOrderPosOff;
840  nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
841 
842  if (!nOrderPosOff)
843  continue;
844 
845  // Since we're changing the order, write it back
846  if (!batch.WriteTx(*pwtx))
847  return DBErrors::LOAD_FAIL;
848  }
849  }
850  batch.WriteOrderPosNext(nOrderPosNext);
851 
852  return DBErrors::LOAD_OK;
853 }
854 
856 {
858  int64_t nRet = nOrderPosNext++;
859  if (batch) {
860  batch->WriteOrderPosNext(nOrderPosNext);
861  } else {
862  WalletBatch(GetDatabase()).WriteOrderPosNext(nOrderPosNext);
863  }
864  return nRet;
865 }
866 
868 {
869  {
870  LOCK(cs_wallet);
871  for (std::pair<const uint256, CWalletTx>& item : mapWallet)
872  item.second.MarkDirty();
873  }
874 }
875 
876 bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
877 {
878  LOCK(cs_wallet);
879 
880  auto mi = mapWallet.find(originalHash);
881 
882  // There is a bug if MarkReplaced is not called on an existing wallet transaction.
883  assert(mi != mapWallet.end());
884 
885  CWalletTx& wtx = (*mi).second;
886 
887  // Ensure for now that we're not overwriting data
888  assert(wtx.mapValue.count("replaced_by_txid") == 0);
889 
890  wtx.mapValue["replaced_by_txid"] = newHash.ToString();
891 
892  // Refresh mempool status without waiting for transactionRemovedFromMempool or transactionAddedToMempool
893  RefreshMempoolStatus(wtx, chain());
894 
895  WalletBatch batch(GetDatabase());
896 
897  bool success = true;
898  if (!batch.WriteTx(wtx)) {
899  WalletLogPrintf("%s: Updating batch tx %s failed\n", __func__, wtx.GetHash().ToString());
900  success = false;
901  }
902 
903  NotifyTransactionChanged(originalHash, CT_UPDATED);
904 
905  return success;
906 }
907 
908 void CWallet::SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations)
909 {
911  const CWalletTx* srctx = GetWalletTx(hash);
912  if (!srctx) return;
913 
914  CTxDestination dst;
915  if (ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst)) {
916  if (IsMine(dst)) {
917  if (used != IsAddressUsed(dst)) {
918  if (used) {
919  tx_destinations.insert(dst);
920  }
921  SetAddressUsed(batch, dst, used);
922  }
923  }
924  }
925 }
926 
927 bool CWallet::IsSpentKey(const CScript& scriptPubKey) const
928 {
930  CTxDestination dest;
931  if (!ExtractDestination(scriptPubKey, dest)) {
932  return false;
933  }
934  if (IsAddressUsed(dest)) {
935  return true;
936  }
937  if (IsLegacy()) {
939  assert(spk_man != nullptr);
940  for (const auto& keyid : GetAffectedKeys(scriptPubKey, *spk_man)) {
941  WitnessV0KeyHash wpkh_dest(keyid);
942  if (IsAddressUsed(wpkh_dest)) {
943  return true;
944  }
945  ScriptHash sh_wpkh_dest(GetScriptForDestination(wpkh_dest));
946  if (IsAddressUsed(sh_wpkh_dest)) {
947  return true;
948  }
949  PKHash pkh_dest(keyid);
950  if (IsAddressUsed(pkh_dest)) {
951  return true;
952  }
953  }
954  }
955  return false;
956 }
957 
958 CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const UpdateWalletTxFn& update_wtx, bool fFlushOnClose, bool rescanning_old_block)
959 {
960  LOCK(cs_wallet);
961 
962  WalletBatch batch(GetDatabase(), fFlushOnClose);
963 
964  uint256 hash = tx->GetHash();
965 
967  // Mark used destinations
968  std::set<CTxDestination> tx_destinations;
969 
970  for (const CTxIn& txin : tx->vin) {
971  const COutPoint& op = txin.prevout;
972  SetSpentKeyState(batch, op.hash, op.n, true, tx_destinations);
973  }
974 
975  MarkDestinationsDirty(tx_destinations);
976  }
977 
978  // Inserts only if not already there, returns tx inserted or tx found
979  auto ret = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(tx, state));
980  CWalletTx& wtx = (*ret.first).second;
981  bool fInsertedNew = ret.second;
982  bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew);
983  if (fInsertedNew) {
984  wtx.nTimeReceived = GetTime();
985  wtx.nOrderPos = IncOrderPosNext(&batch);
986  wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
987  wtx.nTimeSmart = ComputeTimeSmart(wtx, rescanning_old_block);
988  AddToSpends(wtx, &batch);
989  }
990 
991  if (!fInsertedNew)
992  {
993  if (state.index() != wtx.m_state.index()) {
994  wtx.m_state = state;
995  fUpdated = true;
996  } else {
999  }
1000  // If we have a witness-stripped version of this transaction, and we
1001  // see a new version with a witness, then we must be upgrading a pre-segwit
1002  // wallet. Store the new version of the transaction with the witness,
1003  // as the stripped-version must be invalid.
1004  // TODO: Store all versions of the transaction, instead of just one.
1005  if (tx->HasWitness() && !wtx.tx->HasWitness()) {
1006  wtx.SetTx(tx);
1007  fUpdated = true;
1008  }
1009  }
1010 
1012  WalletLogPrintf("AddToWallet %s %s%s\n", hash.ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
1013 
1014  // Write to disk
1015  if (fInsertedNew || fUpdated)
1016  if (!batch.WriteTx(wtx))
1017  return nullptr;
1018 
1019  // Break debit/credit balance caches:
1020  wtx.MarkDirty();
1021 
1022  // Notify UI of new or updated transaction
1023  NotifyTransactionChanged(hash, fInsertedNew ? CT_NEW : CT_UPDATED);
1024 
1025 #if HAVE_SYSTEM
1026  // notify an external script when a wallet transaction comes in or is updated
1027  std::string strCmd = m_args.GetArg("-walletnotify", "");
1028 
1029  if (!strCmd.empty())
1030  {
1031  ReplaceAll(strCmd, "%s", hash.GetHex());
1032  if (auto* conf = wtx.state<TxStateConfirmed>())
1033  {
1034  ReplaceAll(strCmd, "%b", conf->confirmed_block_hash.GetHex());
1035  ReplaceAll(strCmd, "%h", ToString(conf->confirmed_block_height));
1036  } else {
1037  ReplaceAll(strCmd, "%b", "unconfirmed");
1038  ReplaceAll(strCmd, "%h", "-1");
1039  }
1040 #ifndef WIN32
1041  // Substituting the wallet name isn't currently supported on windows
1042  // because windows shell escaping has not been implemented yet:
1043  // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-537384875
1044  // A few ways it could be implemented in the future are described in:
1045  // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-461288094
1046  ReplaceAll(strCmd, "%w", ShellEscape(GetName()));
1047 #endif
1048  std::thread t(runCommand, strCmd);
1049  t.detach(); // thread runs free
1050  }
1051 #endif
1052 
1053  return &wtx;
1054 }
1055 
1056 bool CWallet::LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx)
1057 {
1058  const auto& ins = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(nullptr, TxStateInactive{}));
1059  CWalletTx& wtx = ins.first->second;
1060  if (!fill_wtx(wtx, ins.second)) {
1061  return false;
1062  }
1063  // If wallet doesn't have a chain (e.g when using bitcoin-wallet tool),
1064  // don't bother to update txn.
1065  if (HaveChain()) {
1066  bool active;
1067  auto lookup_block = [&](const uint256& hash, int& height, TxState& state) {
1068  // If tx block (or conflicting block) was reorged out of chain
1069  // while the wallet was shutdown, change tx status to UNCONFIRMED
1070  // and reset block height, hash, and index. ABANDONED tx don't have
1071  // associated blocks and don't need to be updated. The case where a
1072  // transaction was reorged out while online and then reconfirmed
1073  // while offline is covered by the rescan logic.
1074  if (!chain().findBlock(hash, FoundBlock().inActiveChain(active).height(height)) || !active) {
1075  state = TxStateInactive{};
1076  }
1077  };
1078  if (auto* conf = wtx.state<TxStateConfirmed>()) {
1079  lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, wtx.m_state);
1080  } else if (auto* conf = wtx.state<TxStateConflicted>()) {
1081  lookup_block(conf->conflicting_block_hash, conf->conflicting_block_height, wtx.m_state);
1082  }
1083  }
1084  if (/* insertion took place */ ins.second) {
1085  wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
1086  }
1087  AddToSpends(wtx);
1088  for (const CTxIn& txin : wtx.tx->vin) {
1089  auto it = mapWallet.find(txin.prevout.hash);
1090  if (it != mapWallet.end()) {
1091  CWalletTx& prevtx = it->second;
1092  if (auto* prev = prevtx.state<TxStateConflicted>()) {
1093  MarkConflicted(prev->conflicting_block_hash, prev->conflicting_block_height, wtx.GetHash());
1094  }
1095  }
1096  }
1097  return true;
1098 }
1099 
1100 bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const SyncTxState& state, bool fUpdate, bool rescanning_old_block)
1101 {
1102  const CTransaction& tx = *ptx;
1103  {
1105 
1106  if (auto* conf = std::get_if<TxStateConfirmed>(&state)) {
1107  for (const CTxIn& txin : tx.vin) {
1108  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout);
1109  while (range.first != range.second) {
1110  if (range.first->second != tx.GetHash()) {
1111  WalletLogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), conf->confirmed_block_hash.ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
1112  MarkConflicted(conf->confirmed_block_hash, conf->confirmed_block_height, range.first->second);
1113  }
1114  range.first++;
1115  }
1116  }
1117  }
1118 
1119  bool fExisted = mapWallet.count(tx.GetHash()) != 0;
1120  if (fExisted && !fUpdate) return false;
1121  if (fExisted || IsMine(tx) || IsFromMe(tx))
1122  {
1123  /* Check if any keys in the wallet keypool that were supposed to be unused
1124  * have appeared in a new transaction. If so, remove those keys from the keypool.
1125  * This can happen when restoring an old wallet backup that does not contain
1126  * the mostly recently created transactions from newer versions of the wallet.
1127  */
1128 
1129  // loop though all outputs
1130  for (const CTxOut& txout: tx.vout) {
1131  for (const auto& spk_man : GetScriptPubKeyMans(txout.scriptPubKey)) {
1132  for (auto &dest : spk_man->MarkUnusedAddresses(txout.scriptPubKey)) {
1133  // If internal flag is not defined try to infer it from the ScriptPubKeyMan
1134  if (!dest.internal.has_value()) {
1135  dest.internal = IsInternalScriptPubKeyMan(spk_man);
1136  }
1137 
1138  // skip if can't determine whether it's a receiving address or not
1139  if (!dest.internal.has_value()) continue;
1140 
1141  // If this is a receiving address and it's not in the address book yet
1142  // (e.g. it wasn't generated on this node or we're restoring from backup)
1143  // add it to the address book for proper transaction accounting
1144  if (!*dest.internal && !FindAddressBookEntry(dest.dest, /* allow_change= */ false)) {
1145  SetAddressBook(dest.dest, "", "receive");
1146  }
1147  }
1148  }
1149  }
1150 
1151  // Block disconnection override an abandoned tx as unconfirmed
1152  // which means user may have to call abandontransaction again
1153  TxState tx_state = std::visit([](auto&& s) -> TxState { return s; }, state);
1154  CWalletTx* wtx = AddToWallet(MakeTransactionRef(tx), tx_state, /*update_wtx=*/nullptr, /*fFlushOnClose=*/false, rescanning_old_block);
1155  if (!wtx) {
1156  // Can only be nullptr if there was a db write error (missing db, read-only db or a db engine internal writing error).
1157  // As we only store arriving transaction in this process, and we don't want an inconsistent state, let's throw an error.
1158  throw std::runtime_error("DB error adding transaction to wallet, write failed");
1159  }
1160  return true;
1161  }
1162  }
1163  return false;
1164 }
1165 
1167 {
1168  LOCK(cs_wallet);
1169  const CWalletTx* wtx = GetWalletTx(hashTx);
1170  return wtx && !wtx->isAbandoned() && GetTxDepthInMainChain(*wtx) == 0 && !wtx->InMempool();
1171 }
1172 
1174 {
1175  for (const CTxIn& txin : tx->vin) {
1176  auto it = mapWallet.find(txin.prevout.hash);
1177  if (it != mapWallet.end()) {
1178  it->second.MarkDirty();
1179  }
1180  }
1181 }
1182 
1184 {
1185  LOCK(cs_wallet);
1186 
1187  WalletBatch batch(GetDatabase());
1188 
1189  std::set<uint256> todo;
1190  std::set<uint256> done;
1191 
1192  // Can't mark abandoned if confirmed or in mempool
1193  auto it = mapWallet.find(hashTx);
1194  assert(it != mapWallet.end());
1195  const CWalletTx& origtx = it->second;
1196  if (GetTxDepthInMainChain(origtx) != 0 || origtx.InMempool()) {
1197  return false;
1198  }
1199 
1200  todo.insert(hashTx);
1201 
1202  while (!todo.empty()) {
1203  uint256 now = *todo.begin();
1204  todo.erase(now);
1205  done.insert(now);
1206  auto it = mapWallet.find(now);
1207  assert(it != mapWallet.end());
1208  CWalletTx& wtx = it->second;
1209  int currentconfirm = GetTxDepthInMainChain(wtx);
1210  // If the orig tx was not in block, none of its spends can be
1211  assert(currentconfirm <= 0);
1212  // if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon}
1213  if (currentconfirm == 0 && !wtx.isAbandoned()) {
1214  // If the orig tx was not in block/mempool, none of its spends can be in mempool
1215  assert(!wtx.InMempool());
1216  wtx.m_state = TxStateInactive{/*abandoned=*/true};
1217  wtx.MarkDirty();
1218  batch.WriteTx(wtx);
1219  NotifyTransactionChanged(wtx.GetHash(), CT_UPDATED);
1220  // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
1221  for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
1222  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(COutPoint(now, i));
1223  for (TxSpends::const_iterator iter = range.first; iter != range.second; ++iter) {
1224  if (!done.count(iter->second)) {
1225  todo.insert(iter->second);
1226  }
1227  }
1228  }
1229  // If a transaction changes 'conflicted' state, that changes the balance
1230  // available of the outputs it spends. So force those to be recomputed
1231  MarkInputsDirty(wtx.tx);
1232  }
1233  }
1234 
1235  return true;
1236 }
1237 
1238 void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, const uint256& hashTx)
1239 {
1240  LOCK(cs_wallet);
1241 
1242  int conflictconfirms = (m_last_block_processed_height - conflicting_height + 1) * -1;
1243  // If number of conflict confirms cannot be determined, this means
1244  // that the block is still unknown or not yet part of the main chain,
1245  // for example when loading the wallet during a reindex. Do nothing in that
1246  // case.
1247  if (conflictconfirms >= 0)
1248  return;
1249 
1250  // Do not flush the wallet here for performance reasons
1251  WalletBatch batch(GetDatabase(), false);
1252 
1253  std::set<uint256> todo;
1254  std::set<uint256> done;
1255 
1256  todo.insert(hashTx);
1257 
1258  while (!todo.empty()) {
1259  uint256 now = *todo.begin();
1260  todo.erase(now);
1261  done.insert(now);
1262  auto it = mapWallet.find(now);
1263  assert(it != mapWallet.end());
1264  CWalletTx& wtx = it->second;
1265  int currentconfirm = GetTxDepthInMainChain(wtx);
1266  if (conflictconfirms < currentconfirm) {
1267  // Block is 'more conflicted' than current confirm; update.
1268  // Mark transaction as conflicted with this block.
1269  wtx.m_state = TxStateConflicted{hashBlock, conflicting_height};
1270  wtx.MarkDirty();
1271  batch.WriteTx(wtx);
1272  // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
1273  for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
1274  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(COutPoint(now, i));
1275  for (TxSpends::const_iterator iter = range.first; iter != range.second; ++iter) {
1276  if (!done.count(iter->second)) {
1277  todo.insert(iter->second);
1278  }
1279  }
1280  }
1281  // If a transaction changes 'conflicted' state, that changes the balance
1282  // available of the outputs it spends. So force those to be recomputed
1283  MarkInputsDirty(wtx.tx);
1284  }
1285  }
1286 }
1287 
1288 void CWallet::SyncTransaction(const CTransactionRef& ptx, const SyncTxState& state, bool update_tx, bool rescanning_old_block)
1289 {
1290  if (!AddToWalletIfInvolvingMe(ptx, state, update_tx, rescanning_old_block))
1291  return; // Not one of ours
1292 
1293  // If a transaction changes 'conflicted' state, that changes the balance
1294  // available of the outputs it spends. So force those to be
1295  // recomputed, also:
1296  MarkInputsDirty(ptx);
1297 }
1298 
1299 void CWallet::transactionAddedToMempool(const CTransactionRef& tx, uint64_t mempool_sequence) {
1300  LOCK(cs_wallet);
1302 
1303  auto it = mapWallet.find(tx->GetHash());
1304  if (it != mapWallet.end()) {
1305  RefreshMempoolStatus(it->second, chain());
1306  }
1307 }
1308 
1309 void CWallet::transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {
1310  LOCK(cs_wallet);
1311  auto it = mapWallet.find(tx->GetHash());
1312  if (it != mapWallet.end()) {
1313  RefreshMempoolStatus(it->second, chain());
1314  }
1315  // Handle transactions that were removed from the mempool because they
1316  // conflict with transactions in a newly connected block.
1317  if (reason == MemPoolRemovalReason::CONFLICT) {
1318  // Trigger external -walletnotify notifications for these transactions.
1319  // Set Status::UNCONFIRMED instead of Status::CONFLICTED for a few reasons:
1320  //
1321  // 1. The transactionRemovedFromMempool callback does not currently
1322  // provide the conflicting block's hash and height, and for backwards
1323  // compatibility reasons it may not be not safe to store conflicted
1324  // wallet transactions with a null block hash. See
1325  // https://github.com/bitcoin/bitcoin/pull/18600#discussion_r420195993.
1326  // 2. For most of these transactions, the wallet's internal conflict
1327  // detection in the blockConnected handler will subsequently call
1328  // MarkConflicted and update them with CONFLICTED status anyway. This
1329  // applies to any wallet transaction that has inputs spent in the
1330  // block, or that has ancestors in the wallet with inputs spent by
1331  // the block.
1332  // 3. Longstanding behavior since the sync implementation in
1333  // https://github.com/bitcoin/bitcoin/pull/9371 and the prior sync
1334  // implementation before that was to mark these transactions
1335  // unconfirmed rather than conflicted.
1336  //
1337  // Nothing described above should be seen as an unchangeable requirement
1338  // when improving this code in the future. The wallet's heuristics for
1339  // distinguishing between conflicted and unconfirmed transactions are
1340  // imperfect, and could be improved in general, see
1341  // https://github.com/bitcoin-core/bitcoin-devwiki/wiki/Wallet-Transaction-Conflict-Tracking
1343  }
1344 }
1345 
1347 {
1348  assert(block.data);
1349  LOCK(cs_wallet);
1350 
1351  m_last_block_processed_height = block.height;
1352  m_last_block_processed = block.hash;
1353  for (size_t index = 0; index < block.data->vtx.size(); index++) {
1354  SyncTransaction(block.data->vtx[index], TxStateConfirmed{block.hash, block.height, static_cast<int>(index)});
1355  transactionRemovedFromMempool(block.data->vtx[index], MemPoolRemovalReason::BLOCK, 0 /* mempool_sequence */);
1356  }
1357 }
1358 
1360 {
1361  assert(block.data);
1362  LOCK(cs_wallet);
1363 
1364  // At block disconnection, this will change an abandoned transaction to
1365  // be unconfirmed, whether or not the transaction is added back to the mempool.
1366  // User may have to call abandontransaction again. It may be addressed in the
1367  // future with a stickier abandoned state or even removing abandontransaction call.
1368  m_last_block_processed_height = block.height - 1;
1369  m_last_block_processed = *Assert(block.prev_hash);
1370  for (const CTransactionRef& ptx : Assert(block.data)->vtx) {
1372  }
1373 }
1374 
1376 {
1378 }
1379 
1380 void CWallet::BlockUntilSyncedToCurrentChain() const {
1382  // Skip the queue-draining stuff if we know we're caught up with
1383  // chain().Tip(), otherwise put a callback in the validation interface queue and wait
1384  // for the queue to drain enough to execute it (indicating we are caught up
1385  // at least with the time we entered this function).
1386  uint256 last_block_hash = WITH_LOCK(cs_wallet, return m_last_block_processed);
1387  chain().waitForNotificationsIfTipChanged(last_block_hash);
1388 }
1389 
1390 // Note that this function doesn't distinguish between a 0-valued input,
1391 // and a not-"is mine" (according to the filter) input.
1392 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
1393 {
1394  {
1395  LOCK(cs_wallet);
1396  const auto mi = mapWallet.find(txin.prevout.hash);
1397  if (mi != mapWallet.end())
1398  {
1399  const CWalletTx& prev = (*mi).second;
1400  if (txin.prevout.n < prev.tx->vout.size())
1401  if (IsMine(prev.tx->vout[txin.prevout.n]) & filter)
1402  return prev.tx->vout[txin.prevout.n].nValue;
1403  }
1404  }
1405  return 0;
1406 }
1407 
1408 isminetype CWallet::IsMine(const CTxOut& txout) const
1409 {
1411  return IsMine(txout.scriptPubKey);
1412 }
1413 
1415 {
1417  return IsMine(GetScriptForDestination(dest));
1418 }
1419 
1420 isminetype CWallet::IsMine(const CScript& script) const
1421 {
1423  isminetype result = ISMINE_NO;
1424  for (const auto& spk_man_pair : m_spk_managers) {
1425  result = std::max(result, spk_man_pair.second->IsMine(script));
1426  }
1427  return result;
1428 }
1429 
1430 bool CWallet::IsMine(const CTransaction& tx) const
1431 {
1433  for (const CTxOut& txout : tx.vout)
1434  if (IsMine(txout))
1435  return true;
1436  return false;
1437 }
1438 
1439 isminetype CWallet::IsMine(const COutPoint& outpoint) const
1440 {
1442  auto wtx = GetWalletTx(outpoint.hash);
1443  if (!wtx) {
1444  return ISMINE_NO;
1445  }
1446  if (outpoint.n >= wtx->tx->vout.size()) {
1447  return ISMINE_NO;
1448  }
1449  return IsMine(wtx->tx->vout[outpoint.n]);
1450 }
1451 
1452 bool CWallet::IsFromMe(const CTransaction& tx) const
1453 {
1454  return (GetDebit(tx, ISMINE_ALL) > 0);
1455 }
1456 
1457 CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
1458 {
1459  CAmount nDebit = 0;
1460  for (const CTxIn& txin : tx.vin)
1461  {
1462  nDebit += GetDebit(txin, filter);
1463  if (!MoneyRange(nDebit))
1464  throw std::runtime_error(std::string(__func__) + ": value out of range");
1465  }
1466  return nDebit;
1467 }
1468 
1470 {
1471  // All Active ScriptPubKeyMans must be HD for this to be true
1472  bool result = false;
1473  for (const auto& spk_man : GetActiveScriptPubKeyMans()) {
1474  if (!spk_man->IsHDEnabled()) return false;
1475  result = true;
1476  }
1477  return result;
1478 }
1479 
1480 bool CWallet::CanGetAddresses(bool internal) const
1481 {
1482  LOCK(cs_wallet);
1483  if (m_spk_managers.empty()) return false;
1484  for (OutputType t : OUTPUT_TYPES) {
1485  auto spk_man = GetScriptPubKeyMan(t, internal);
1486  if (spk_man && spk_man->CanGetAddresses(internal)) {
1487  return true;
1488  }
1489  }
1490  return false;
1491 }
1492 
1493 void CWallet::SetWalletFlag(uint64_t flags)
1494 {
1495  LOCK(cs_wallet);
1496  m_wallet_flags |= flags;
1497  if (!WalletBatch(GetDatabase()).WriteWalletFlags(m_wallet_flags))
1498  throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1499 }
1500 
1501 void CWallet::UnsetWalletFlag(uint64_t flag)
1502 {
1503  WalletBatch batch(GetDatabase());
1504  UnsetWalletFlagWithDB(batch, flag);
1505 }
1506 
1507 void CWallet::UnsetWalletFlagWithDB(WalletBatch& batch, uint64_t flag)
1508 {
1509  LOCK(cs_wallet);
1510  m_wallet_flags &= ~flag;
1511  if (!batch.WriteWalletFlags(m_wallet_flags))
1512  throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1513 }
1514 
1516 {
1518 }
1519 
1520 bool CWallet::IsWalletFlagSet(uint64_t flag) const
1521 {
1522  return (m_wallet_flags & flag);
1523 }
1524 
1526 {
1527  LOCK(cs_wallet);
1528  if (((flags & KNOWN_WALLET_FLAGS) >> 32) ^ (flags >> 32)) {
1529  // contains unknown non-tolerable wallet flags
1530  return false;
1531  }
1533 
1534  return true;
1535 }
1536 
1538 {
1539  LOCK(cs_wallet);
1540 
1541  // We should never be writing unknown non-tolerable wallet flags
1542  assert(((flags & KNOWN_WALLET_FLAGS) >> 32) == (flags >> 32));
1543  // This should only be used once, when creating a new wallet - so current flags are expected to be blank
1544  assert(m_wallet_flags == 0);
1545 
1546  if (!WalletBatch(GetDatabase()).WriteWalletFlags(flags)) {
1547  throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
1548  }
1549 
1550  if (!LoadWalletFlags(flags)) assert(false);
1551 }
1552 
1553 // Helper for producing a max-sized low-S low-R signature (eg 71 bytes)
1554 // or a max-sized low-S signature (e.g. 72 bytes) depending on coin_control
1555 bool DummySignInput(const SigningProvider& provider, CTxIn &tx_in, const CTxOut &txout, const CCoinControl* coin_control)
1556 {
1557  // Fill in dummy signatures for fee calculation.
1558  const CScript& scriptPubKey = txout.scriptPubKey;
1559  SignatureData sigdata;
1560 
1561  // Use max sig if watch only inputs were used or if this particular input is an external input
1562  // to ensure a sufficient fee is attained for the requested feerate.
1563  const bool use_max_sig = coin_control && (coin_control->fAllowWatchOnly || coin_control->IsExternalSelected(tx_in.prevout));
1564  if (!ProduceSignature(provider, use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR : DUMMY_SIGNATURE_CREATOR, scriptPubKey, sigdata)) {
1565  return false;
1566  }
1567  UpdateInput(tx_in, sigdata);
1568  return true;
1569 }
1570 
1571 bool FillInputToWeight(CTxIn& txin, int64_t target_weight)
1572 {
1573  assert(txin.scriptSig.empty());
1574  assert(txin.scriptWitness.IsNull());
1575 
1576  int64_t txin_weight = GetTransactionInputWeight(txin);
1577 
1578  // Do nothing if the weight that should be added is less than the weight that already exists
1579  if (target_weight < txin_weight) {
1580  return false;
1581  }
1582  if (target_weight == txin_weight) {
1583  return true;
1584  }
1585 
1586  // Subtract current txin weight, which should include empty witness stack
1587  int64_t add_weight = target_weight - txin_weight;
1588  assert(add_weight > 0);
1589 
1590  // We will want to subtract the size of the Compact Size UInt that will also be serialized.
1591  // However doing so when the size is near a boundary can result in a problem where it is not
1592  // possible to have a stack element size and combination to exactly equal a target.
1593  // To avoid this possibility, if the weight to add is less than 10 bytes greater than
1594  // a boundary, the size will be split so that 2/3rds will be in one stack element, and
1595  // the remaining 1/3rd in another. Using 3rds allows us to avoid additional boundaries.
1596  // 10 bytes is used because that accounts for the maximum size. This does not need to be super precise.
1597  if ((add_weight >= 253 && add_weight < 263)
1598  || (add_weight > std::numeric_limits<uint16_t>::max() && add_weight <= std::numeric_limits<uint16_t>::max() + 10)
1599  || (add_weight > std::numeric_limits<uint32_t>::max() && add_weight <= std::numeric_limits<uint32_t>::max() + 10)) {
1600  int64_t first_weight = add_weight / 3;
1601  add_weight -= first_weight;
1602 
1603  first_weight -= GetSizeOfCompactSize(first_weight);
1604  txin.scriptWitness.stack.emplace(txin.scriptWitness.stack.end(), first_weight, 0);
1605  }
1606 
1607  add_weight -= GetSizeOfCompactSize(add_weight);
1608  txin.scriptWitness.stack.emplace(txin.scriptWitness.stack.end(), add_weight, 0);
1609  assert(GetTransactionInputWeight(txin) == target_weight);
1610 
1611  return true;
1612 }
1613 
1614 // Helper for producing a bunch of max-sized low-S low-R signatures (eg 71 bytes)
1615 bool CWallet::DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts, const CCoinControl* coin_control) const
1616 {
1617  // Fill in dummy signatures for fee calculation.
1618  int nIn = 0;
1619  for (const auto& txout : txouts)
1620  {
1621  CTxIn& txin = txNew.vin[nIn];
1622  // If weight was provided, fill the input to that weight
1623  if (coin_control && coin_control->HasInputWeight(txin.prevout)) {
1624  if (!FillInputToWeight(txin, coin_control->GetInputWeight(txin.prevout))) {
1625  return false;
1626  }
1627  nIn++;
1628  continue;
1629  }
1630  const std::unique_ptr<SigningProvider> provider = GetSolvingProvider(txout.scriptPubKey);
1631  if (!provider || !DummySignInput(*provider, txin, txout, coin_control)) {
1632  if (!coin_control || !DummySignInput(coin_control->m_external_provider, txin, txout, coin_control)) {
1633  return false;
1634  }
1635  }
1636 
1637  nIn++;
1638  }
1639  return true;
1640 }
1641 
1642 bool CWallet::ImportScripts(const std::set<CScript> scripts, int64_t timestamp)
1643 {
1644  auto spk_man = GetLegacyScriptPubKeyMan();
1645  if (!spk_man) {
1646  return false;
1647  }
1648  LOCK(spk_man->cs_KeyStore);
1649  return spk_man->ImportScripts(scripts, timestamp);
1650 }
1651 
1652 bool CWallet::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp)
1653 {
1654  auto spk_man = GetLegacyScriptPubKeyMan();
1655  if (!spk_man) {
1656  return false;
1657  }
1658  LOCK(spk_man->cs_KeyStore);
1659  return spk_man->ImportPrivKeys(privkey_map, timestamp);
1660 }
1661 
1662 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)
1663 {
1664  auto spk_man = GetLegacyScriptPubKeyMan();
1665  if (!spk_man) {
1666  return false;
1667  }
1668  LOCK(spk_man->cs_KeyStore);
1669  return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins, add_keypool, internal, timestamp);
1670 }
1671 
1672 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)
1673 {
1674  auto spk_man = GetLegacyScriptPubKeyMan();
1675  if (!spk_man) {
1676  return false;
1677  }
1678  LOCK(spk_man->cs_KeyStore);
1679  if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data, timestamp)) {
1680  return false;
1681  }
1682  if (apply_label) {
1683  WalletBatch batch(GetDatabase());
1684  for (const CScript& script : script_pub_keys) {
1685  CTxDestination dest;
1686  ExtractDestination(script, dest);
1687  if (IsValidDestination(dest)) {
1688  SetAddressBookWithDB(batch, dest, label, "receive");
1689  }
1690  }
1691  }
1692  return true;
1693 }
1694 
1703 int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update)
1704 {
1705  // Find starting block. May be null if nCreateTime is greater than the
1706  // highest blockchain timestamp, in which case there is nothing that needs
1707  // to be scanned.
1708  int start_height = 0;
1709  uint256 start_block;
1710  bool start = chain().findFirstBlockWithTimeAndHeight(startTime - TIMESTAMP_WINDOW, 0, FoundBlock().hash(start_block).height(start_height));
1711  WalletLogPrintf("%s: Rescanning last %i blocks\n", __func__, start ? WITH_LOCK(cs_wallet, return GetLastBlockHeight()) - start_height + 1 : 0);
1712 
1713  if (start) {
1714  // TODO: this should take into account failure by ScanResult::USER_ABORT
1715  ScanResult result = ScanForWalletTransactions(start_block, start_height, /*max_height=*/{}, reserver, /*fUpdate=*/update, /*save_progress=*/false);
1716  if (result.status == ScanResult::FAILURE) {
1717  int64_t time_max;
1718  CHECK_NONFATAL(chain().findBlock(result.last_failed_block, FoundBlock().maxTime(time_max)));
1719  return time_max + TIMESTAMP_WINDOW + 1;
1720  }
1721  }
1722  return startTime;
1723 }
1724 
1747 CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_block, int start_height, std::optional<int> max_height, const WalletRescanReserver& reserver, bool fUpdate, const bool save_progress)
1748 {
1749  constexpr auto INTERVAL_TIME{60s};
1750  auto current_time{reserver.now()};
1751  auto start_time{reserver.now()};
1752 
1753  assert(reserver.isReserved());
1754 
1755  uint256 block_hash = start_block;
1756  ScanResult result;
1757 
1758  WalletLogPrintf("Rescan started from block %s...\n", start_block.ToString());
1759 
1760  fAbortRescan = false;
1761  ShowProgress(strprintf("%s " + _("Rescanning…").translated, GetDisplayName()), 0); // show rescan progress in GUI as dialog or on splashscreen, if rescan required on startup (e.g. due to corruption)
1762  uint256 tip_hash = WITH_LOCK(cs_wallet, return GetLastBlockHash());
1763  uint256 end_hash = tip_hash;
1764  if (max_height) chain().findAncestorByHeight(tip_hash, *max_height, FoundBlock().hash(end_hash));
1765  double progress_begin = chain().guessVerificationProgress(block_hash);
1766  double progress_end = chain().guessVerificationProgress(end_hash);
1767  double progress_current = progress_begin;
1768  int block_height = start_height;
1769  while (!fAbortRescan && !chain().shutdownRequested()) {
1770  if (progress_end - progress_begin > 0.0) {
1771  m_scanning_progress = (progress_current - progress_begin) / (progress_end - progress_begin);
1772  } else { // avoid divide-by-zero for single block scan range (i.e. start and stop hashes are equal)
1773  m_scanning_progress = 0;
1774  }
1775  if (block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
1776  ShowProgress(strprintf("%s " + _("Rescanning…").translated, GetDisplayName()), std::max(1, std::min(99, (int)(m_scanning_progress * 100))));
1777  }
1778 
1779  bool next_interval = reserver.now() >= current_time + INTERVAL_TIME;
1780  if (next_interval) {
1781  current_time = reserver.now();
1782  WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", block_height, progress_current);
1783  }
1784 
1785  // Read block data
1786  CBlock block;
1787  chain().findBlock(block_hash, FoundBlock().data(block));
1788 
1789  // Find next block separately from reading data above, because reading
1790  // is slow and there might be a reorg while it is read.
1791  bool block_still_active = false;
1792  bool next_block = false;
1793  uint256 next_block_hash;
1794  chain().findBlock(block_hash, FoundBlock().inActiveChain(block_still_active).nextBlock(FoundBlock().inActiveChain(next_block).hash(next_block_hash)));
1795 
1796  if (!block.IsNull()) {
1797  LOCK(cs_wallet);
1798  if (!block_still_active) {
1799  // Abort scan if current block is no longer active, to prevent
1800  // marking transactions as coming from the wrong block.
1801  result.last_failed_block = block_hash;
1802  result.status = ScanResult::FAILURE;
1803  break;
1804  }
1805  for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
1806  SyncTransaction(block.vtx[posInBlock], TxStateConfirmed{block_hash, block_height, static_cast<int>(posInBlock)}, fUpdate, /*rescanning_old_block=*/true);
1807  }
1808  // scan succeeded, record block as most recent successfully scanned
1809  result.last_scanned_block = block_hash;
1810  result.last_scanned_height = block_height;
1811 
1812  if (save_progress && next_interval) {
1813  CBlockLocator loc = m_chain->getActiveChainLocator(block_hash);
1814 
1815  if (!loc.IsNull()) {
1816  WalletLogPrintf("Saving scan progress %d.\n", block_height);
1817  WalletBatch batch(GetDatabase());
1818  batch.WriteBestBlock(loc);
1819  }
1820  }
1821  } else {
1822  // could not scan block, keep scanning but record this block as the most recent failure
1823  result.last_failed_block = block_hash;
1824  result.status = ScanResult::FAILURE;
1825  }
1826  if (max_height && block_height >= *max_height) {
1827  break;
1828  }
1829  {
1830  if (!next_block) {
1831  // break successfully when rescan has reached the tip, or
1832  // previous block is no longer on the chain due to a reorg
1833  break;
1834  }
1835 
1836  // increment block and verification progress
1837  block_hash = next_block_hash;
1838  ++block_height;
1839  progress_current = chain().guessVerificationProgress(block_hash);
1840 
1841  // handle updated tip hash
1842  const uint256 prev_tip_hash = tip_hash;
1843  tip_hash = WITH_LOCK(cs_wallet, return GetLastBlockHash());
1844  if (!max_height && prev_tip_hash != tip_hash) {
1845  // in case the tip has changed, update progress max
1846  progress_end = chain().guessVerificationProgress(tip_hash);
1847  }
1848  }
1849  }
1850  if (!max_height) {
1851  WalletLogPrintf("Scanning current mempool transactions.\n");
1852  WITH_LOCK(cs_wallet, chain().requestMempoolTransactions(*this));
1853  }
1854  ShowProgress(strprintf("%s " + _("Rescanning…").translated, GetDisplayName()), 100); // hide progress dialog in GUI
1855  if (block_height && fAbortRescan) {
1856  WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", block_height, progress_current);
1857  result.status = ScanResult::USER_ABORT;
1858  } else if (block_height && chain().shutdownRequested()) {
1859  WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height, progress_current);
1860  result.status = ScanResult::USER_ABORT;
1861  } else {
1862  WalletLogPrintf("Rescan completed in %15dms\n", Ticks<std::chrono::milliseconds>(reserver.now() - start_time));
1863  }
1864  return result;
1865 }
1866 
1867 bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, bool relay) const
1868 {
1870 
1871  // Can't relay if wallet is not broadcasting
1872  if (!GetBroadcastTransactions()) return false;
1873  // Don't relay abandoned transactions
1874  if (wtx.isAbandoned()) return false;
1875  // Don't try to submit coinbase transactions. These would fail anyway but would
1876  // cause log spam.
1877  if (wtx.IsCoinBase()) return false;
1878  // Don't try to submit conflicted or confirmed transactions.
1879  if (GetTxDepthInMainChain(wtx) != 0) return false;
1880 
1881  // Submit transaction to mempool for relay
1882  WalletLogPrintf("Submitting wtx %s to mempool for relay\n", wtx.GetHash().ToString());
1883  // We must set TxStateInMempool here. Even though it will also be set later by the
1884  // entered-mempool callback, if we did not there would be a race where a
1885  // user could call sendmoney in a loop and hit spurious out of funds errors
1886  // because we think that this newly generated transaction's change is
1887  // unavailable as we're not yet aware that it is in the mempool.
1888  //
1889  // If broadcast fails for any reason, trying to set wtx.m_state here would be incorrect.
1890  // If transaction was previously in the mempool, it should be updated when
1891  // TransactionRemovedFromMempool fires.
1892  bool ret = chain().broadcastTransaction(wtx.tx, m_default_max_tx_fee, relay, err_string);
1893  if (ret) wtx.m_state = TxStateInMempool{};
1894  return ret;
1895 }
1896 
1897 std::set<uint256> CWallet::GetTxConflicts(const CWalletTx& wtx) const
1898 {
1900 
1901  const uint256 myHash{wtx.GetHash()};
1902  std::set<uint256> result{GetConflicts(myHash)};
1903  result.erase(myHash);
1904  return result;
1905 }
1906 
1908 {
1909  // Don't attempt to resubmit if the wallet is configured to not broadcast
1910  if (!fBroadcastTransactions) return false;
1911 
1912  // During reindex, importing and IBD, old wallet transactions become
1913  // unconfirmed. Don't resend them as that would spam other nodes.
1914  // We only allow forcing mempool submission when not relaying to avoid this spam.
1915  if (!chain().isReadyToBroadcast()) return false;
1916 
1917  // Do this infrequently and randomly to avoid giving away
1918  // that these are our transactions.
1919  if (GetTime() < m_next_resend) return false;
1920 
1921  return true;
1922 }
1923 
1924 int64_t CWallet::GetDefaultNextResend() { return GetTime() + (12 * 60 * 60) + GetRand(24 * 60 * 60); }
1925 
1926 // Resubmit transactions from the wallet to the mempool, optionally asking the
1927 // mempool to relay them. On startup, we will do this for all unconfirmed
1928 // transactions but will not ask the mempool to relay them. We do this on startup
1929 // to ensure that our own mempool is aware of our transactions. There
1930 // is a privacy side effect here as not broadcasting on startup also means that we won't
1931 // inform the world of our wallet's state, particularly if the wallet (or node) is not
1932 // yet synced.
1933 //
1934 // Otherwise this function is called periodically in order to relay our unconfirmed txs.
1935 // We do this on a random timer to slightly obfuscate which transactions
1936 // come from our wallet.
1937 //
1938 // TODO: Ideally, we'd only resend transactions that we think should have been
1939 // mined in the most recent block. Any transaction that wasn't in the top
1940 // blockweight of transactions in the mempool shouldn't have been mined,
1941 // and so is probably just sitting in the mempool waiting to be confirmed.
1942 // Rebroadcasting does nothing to speed up confirmation and only damages
1943 // privacy.
1944 //
1945 // The `force` option results in all unconfirmed transactions being submitted to
1946 // the mempool. This does not necessarily result in those transactions being relayed,
1947 // that depends on the `relay` option. Periodic rebroadcast uses the pattern
1948 // relay=true force=false, while loading into the mempool
1949 // (on start, or after import) uses relay=false force=true.
1950 void CWallet::ResubmitWalletTransactions(bool relay, bool force)
1951 {
1952  // Don't attempt to resubmit if the wallet is configured to not broadcast,
1953  // even if forcing.
1954  if (!fBroadcastTransactions) return;
1955 
1956  int submitted_tx_count = 0;
1957 
1958  { // cs_wallet scope
1959  LOCK(cs_wallet);
1960 
1961  // First filter for the transactions we want to rebroadcast.
1962  // We use a set with WalletTxOrderComparator so that rebroadcasting occurs in insertion order
1963  std::set<CWalletTx*, WalletTxOrderComparator> to_submit;
1964  for (auto& [txid, wtx] : mapWallet) {
1965  // Only rebroadcast unconfirmed txs
1966  if (!wtx.isUnconfirmed()) continue;
1967 
1968  // attempt to rebroadcast all txes more than 5 minutes older than
1969  // the last block, or all txs if forcing.
1970  if (!force && wtx.nTimeReceived > m_best_block_time - 5 * 60) continue;
1971  to_submit.insert(&wtx);
1972  }
1973  // Now try submitting the transactions to the memory pool and (optionally) relay them.
1974  for (auto wtx : to_submit) {
1975  std::string unused_err_string;
1976  if (SubmitTxMemoryPoolAndRelay(*wtx, unused_err_string, relay)) ++submitted_tx_count;
1977  }
1978  } // cs_wallet
1979 
1980  if (submitted_tx_count > 0) {
1981  WalletLogPrintf("%s: resubmit %u unconfirmed transactions\n", __func__, submitted_tx_count);
1982  }
1983 }
1984  // end of mapWallet
1986 
1988 {
1989  for (const std::shared_ptr<CWallet>& pwallet : GetWallets(context)) {
1990  if (!pwallet->ShouldResend()) continue;
1991  pwallet->ResubmitWalletTransactions(/*relay=*/true, /*force=*/false);
1992  pwallet->SetNextResend();
1993  }
1994 }
1995 
1996 
2003 {
2005 
2006  // Build coins map
2007  std::map<COutPoint, Coin> coins;
2008  for (auto& input : tx.vin) {
2009  const auto mi = mapWallet.find(input.prevout.hash);
2010  if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
2011  return false;
2012  }
2013  const CWalletTx& wtx = mi->second;
2014  int prev_height = wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height : 0;
2015  coins[input.prevout] = Coin(wtx.tx->vout[input.prevout.n], prev_height, wtx.IsCoinBase());
2016  }
2017  std::map<int, bilingual_str> input_errors;
2018  return SignTransaction(tx, coins, SIGHASH_DEFAULT, input_errors);
2019 }
2020 
2021 bool CWallet::SignTransaction(CMutableTransaction& tx, const std::map<COutPoint, Coin>& coins, int sighash, std::map<int, bilingual_str>& input_errors) const
2022 {
2023  // Try to sign with all ScriptPubKeyMans
2024  for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) {
2025  // spk_man->SignTransaction will return true if the transaction is complete,
2026  // so we can exit early and return true if that happens
2027  if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2028  return true;
2029  }
2030  }
2031 
2032  // At this point, one input was not fully signed otherwise we would have exited already
2033  return false;
2034 }
2035 
2036 TransactionError CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bool& complete, int sighash_type, bool sign, bool bip32derivs, size_t * n_signed, bool finalize) const
2037 {
2038  if (n_signed) {
2039  *n_signed = 0;
2040  }
2041  LOCK(cs_wallet);
2042  // Get all of the previous transactions
2043  for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
2044  const CTxIn& txin = psbtx.tx->vin[i];
2045  PSBTInput& input = psbtx.inputs.at(i);
2046 
2047  if (PSBTInputSigned(input)) {
2048  continue;
2049  }
2050 
2051  // If we have no utxo, grab it from the wallet.
2052  if (!input.non_witness_utxo) {
2053  const uint256& txhash = txin.prevout.hash;
2054  const auto it = mapWallet.find(txhash);
2055  if (it != mapWallet.end()) {
2056  const CWalletTx& wtx = it->second;
2057  // We only need the non_witness_utxo, which is a superset of the witness_utxo.
2058  // The signing code will switch to the smaller witness_utxo if this is ok.
2059  input.non_witness_utxo = wtx.tx;
2060  }
2061  }
2062  }
2063 
2064  const PrecomputedTransactionData txdata = PrecomputePSBTData(psbtx);
2065 
2066  // Fill in information from ScriptPubKeyMans
2067  for (ScriptPubKeyMan* spk_man : GetAllScriptPubKeyMans()) {
2068  int n_signed_this_spkm = 0;
2069  TransactionError res = spk_man->FillPSBT(psbtx, txdata, sighash_type, sign, bip32derivs, &n_signed_this_spkm, finalize);
2070  if (res != TransactionError::OK) {
2071  return res;
2072  }
2073 
2074  if (n_signed) {
2075  (*n_signed) += n_signed_this_spkm;
2076  }
2077  }
2078 
2079  // Only drop non_witness_utxos if sighash_type != SIGHASH_ANYONECANPAY
2080  if ((sighash_type & 0x80) != SIGHASH_ANYONECANPAY) {
2081  // Figure out if any non_witness_utxos should be dropped
2082  std::vector<unsigned int> to_drop;
2083  for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
2084  const auto& input = psbtx.inputs.at(i);
2085  int wit_ver;
2086  std::vector<unsigned char> wit_prog;
2087  if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {
2088  // There's a non-segwit input or Segwit v0, so we cannot drop any witness_utxos
2089  to_drop.clear();
2090  break;
2091  }
2092  if (wit_ver == 0) {
2093  // Segwit v0, so we cannot drop any non_witness_utxos
2094  to_drop.clear();
2095  break;
2096  }
2097  if (input.non_witness_utxo) {
2098  to_drop.push_back(i);
2099  }
2100  }
2101 
2102  // Drop the non_witness_utxos that we can drop
2103  for (unsigned int i : to_drop) {
2104  psbtx.inputs.at(i).non_witness_utxo = nullptr;
2105  }
2106  }
2107 
2108  // Complete if every input is now signed
2109  complete = true;
2110  for (const auto& input : psbtx.inputs) {
2111  complete &= PSBTInputSigned(input);
2112  }
2113 
2114  return TransactionError::OK;
2115 }
2116 
2117 SigningResult CWallet::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
2118 {
2119  SignatureData sigdata;
2120  CScript script_pub_key = GetScriptForDestination(pkhash);
2121  for (const auto& spk_man_pair : m_spk_managers) {
2122  if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
2123  LOCK(cs_wallet); // DescriptorScriptPubKeyMan calls IsLocked which can lock cs_wallet in a deadlocking order
2124  return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
2125  }
2126  }
2128 }
2129 
2130 OutputType CWallet::TransactionChangeType(const std::optional<OutputType>& change_type, const std::vector<CRecipient>& vecSend) const
2131 {
2132  // If -changetype is specified, always use that change type.
2133  if (change_type) {
2134  return *change_type;
2135  }
2136 
2137  // if m_default_address_type is legacy, use legacy address as change.
2139  return OutputType::LEGACY;
2140  }
2141 
2142  bool any_tr{false};
2143  bool any_wpkh{false};
2144  bool any_sh{false};
2145  bool any_pkh{false};
2146 
2147  for (const auto& recipient : vecSend) {
2148  std::vector<std::vector<uint8_t>> dummy;
2149  const TxoutType type{Solver(recipient.scriptPubKey, dummy)};
2150  if (type == TxoutType::WITNESS_V1_TAPROOT) {
2151  any_tr = true;
2152  } else if (type == TxoutType::WITNESS_V0_KEYHASH) {
2153  any_wpkh = true;
2154  } else if (type == TxoutType::SCRIPTHASH) {
2155  any_sh = true;
2156  } else if (type == TxoutType::PUBKEYHASH) {
2157  any_pkh = true;
2158  }
2159  }
2160 
2161  const bool has_bech32m_spkman(GetScriptPubKeyMan(OutputType::BECH32M, /*internal=*/true));
2162  if (has_bech32m_spkman && any_tr) {
2163  // Currently tr is the only type supported by the BECH32M spkman
2164  return OutputType::BECH32M;
2165  }
2166  const bool has_bech32_spkman(GetScriptPubKeyMan(OutputType::BECH32, /*internal=*/true));
2167  if (has_bech32_spkman && any_wpkh) {
2168  // Currently wpkh is the only type supported by the BECH32 spkman
2169  return OutputType::BECH32;
2170  }
2171  const bool has_p2sh_segwit_spkman(GetScriptPubKeyMan(OutputType::P2SH_SEGWIT, /*internal=*/true));
2172  if (has_p2sh_segwit_spkman && any_sh) {
2173  // Currently sh_wpkh is the only type supported by the P2SH_SEGWIT spkman
2174  // As of 2021 about 80% of all SH are wrapping WPKH, so use that
2175  return OutputType::P2SH_SEGWIT;
2176  }
2177  const bool has_legacy_spkman(GetScriptPubKeyMan(OutputType::LEGACY, /*internal=*/true));
2178  if (has_legacy_spkman && any_pkh) {
2179  // Currently pkh is the only type supported by the LEGACY spkman
2180  return OutputType::LEGACY;
2181  }
2182 
2183  if (has_bech32m_spkman) {
2184  return OutputType::BECH32M;
2185  }
2186  if (has_bech32_spkman) {
2187  return OutputType::BECH32;
2188  }
2189  // else use m_default_address_type for change
2190  return m_default_address_type;
2191 }
2192 
2193 void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm)
2194 {
2195  LOCK(cs_wallet);
2196  WalletLogPrintf("CommitTransaction:\n%s", tx->ToString()); /* Continued */
2197 
2198  // Add tx to wallet, because if it has change it's also ours,
2199  // otherwise just for transaction history.
2200  CWalletTx* wtx = AddToWallet(tx, TxStateInactive{}, [&](CWalletTx& wtx, bool new_tx) {
2201  CHECK_NONFATAL(wtx.mapValue.empty());
2202  CHECK_NONFATAL(wtx.vOrderForm.empty());
2203  wtx.mapValue = std::move(mapValue);
2204  wtx.vOrderForm = std::move(orderForm);
2205  wtx.fTimeReceivedIsTxTime = true;
2206  wtx.fFromMe = true;
2207  return true;
2208  });
2209 
2210  // wtx can only be null if the db write failed.
2211  if (!wtx) {
2212  throw std::runtime_error(std::string(__func__) + ": Wallet db error, transaction commit failed");
2213  }
2214 
2215  // Notify that old coins are spent
2216  for (const CTxIn& txin : tx->vin) {
2217  CWalletTx &coin = mapWallet.at(txin.prevout.hash);
2218  coin.MarkDirty();
2220  }
2221 
2222  if (!fBroadcastTransactions) {
2223  // Don't submit tx to the mempool
2224  return;
2225  }
2226 
2227  std::string err_string;
2228  if (!SubmitTxMemoryPoolAndRelay(*wtx, err_string, true)) {
2229  WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
2230  // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
2231  }
2232 }
2233 
2235 {
2236  LOCK(cs_wallet);
2237 
2238  DBErrors nLoadWalletRet = WalletBatch(GetDatabase()).LoadWallet(this);
2239  if (nLoadWalletRet == DBErrors::NEED_REWRITE)
2240  {
2241  if (GetDatabase().Rewrite("\x04pool"))
2242  {
2243  for (const auto& spk_man_pair : m_spk_managers) {
2244  spk_man_pair.second->RewriteDB();
2245  }
2246  }
2247  }
2248 
2249  if (m_spk_managers.empty()) {
2252  }
2253 
2254  return nLoadWalletRet;
2255 }
2256 
2257 DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
2258 {
2260  DBErrors nZapSelectTxRet = WalletBatch(GetDatabase()).ZapSelectTx(vHashIn, vHashOut);
2261  for (const uint256& hash : vHashOut) {
2262  const auto& it = mapWallet.find(hash);
2263  wtxOrdered.erase(it->second.m_it_wtxOrdered);
2264  for (const auto& txin : it->second.tx->vin)
2265  mapTxSpends.erase(txin.prevout);
2266  mapWallet.erase(it);
2268  }
2269 
2270  if (nZapSelectTxRet == DBErrors::NEED_REWRITE)
2271  {
2272  if (GetDatabase().Rewrite("\x04pool"))
2273  {
2274  for (const auto& spk_man_pair : m_spk_managers) {
2275  spk_man_pair.second->RewriteDB();
2276  }
2277  }
2278  }
2279 
2280  if (nZapSelectTxRet != DBErrors::LOAD_OK)
2281  return nZapSelectTxRet;
2282 
2283  MarkDirty();
2284 
2285  return DBErrors::LOAD_OK;
2286 }
2287 
2288 bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
2289 {
2290  bool fUpdated = false;
2291  bool is_mine;
2292  {
2293  LOCK(cs_wallet);
2294  std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find(address);
2295  fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
2296  m_address_book[address].SetLabel(strName);
2297  if (!strPurpose.empty()) /* update purpose only if requested */
2298  m_address_book[address].purpose = strPurpose;
2299  is_mine = IsMine(address) != ISMINE_NO;
2300  }
2301  NotifyAddressBookChanged(address, strName, is_mine,
2302  strPurpose, (fUpdated ? CT_UPDATED : CT_NEW));
2303  if (!strPurpose.empty() && !batch.WritePurpose(EncodeDestination(address), strPurpose))
2304  return false;
2305  return batch.WriteName(EncodeDestination(address), strName);
2306 }
2307 
2308 bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
2309 {
2310  WalletBatch batch(GetDatabase());
2311  return SetAddressBookWithDB(batch, address, strName, strPurpose);
2312 }
2313 
2315 {
2316  bool is_mine;
2317  WalletBatch batch(GetDatabase());
2318  {
2319  LOCK(cs_wallet);
2320  // 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)
2321  // NOTE: This isn't a problem for sending addresses because they never have any DestData yet!
2322  // When adding new DestData, it should be considered here whether to retain or delete it (or move it?).
2323  if (IsMine(address)) {
2324  WalletLogPrintf("%s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n", __func__, PACKAGE_BUGREPORT);
2325  return false;
2326  }
2327  // Delete destdata tuples associated with address
2328  std::string strAddress = EncodeDestination(address);
2329  for (const std::pair<const std::string, std::string> &item : m_address_book[address].destdata)
2330  {
2331  batch.EraseDestData(strAddress, item.first);
2332  }
2333  m_address_book.erase(address);
2334  is_mine = IsMine(address) != ISMINE_NO;
2335  }
2336 
2337  NotifyAddressBookChanged(address, "", is_mine, "", CT_DELETED);
2338 
2339  batch.ErasePurpose(EncodeDestination(address));
2340  return batch.EraseName(EncodeDestination(address));
2341 }
2342 
2344 {
2346 
2347  auto legacy_spk_man = GetLegacyScriptPubKeyMan();
2348  if (legacy_spk_man) {
2349  return legacy_spk_man->KeypoolCountExternalKeys();
2350  }
2351 
2352  unsigned int count = 0;
2353  for (auto spk_man : m_external_spk_managers) {
2354  count += spk_man.second->GetKeyPoolSize();
2355  }
2356 
2357  return count;
2358 }
2359 
2360 unsigned int CWallet::GetKeyPoolSize() const
2361 {
2363 
2364  unsigned int count = 0;
2365  for (auto spk_man : GetActiveScriptPubKeyMans()) {
2366  count += spk_man->GetKeyPoolSize();
2367  }
2368  return count;
2369 }
2370 
2371 bool CWallet::TopUpKeyPool(unsigned int kpSize)
2372 {
2373  LOCK(cs_wallet);
2374  bool res = true;
2375  for (auto spk_man : GetActiveScriptPubKeyMans()) {
2376  res &= spk_man->TopUp(kpSize);
2377  }
2378  return res;
2379 }
2380 
2382 {
2383  LOCK(cs_wallet);
2384  auto spk_man = GetScriptPubKeyMan(type, false /* internal */);
2385  if (!spk_man) {
2386  return util::Error{strprintf(_("Error: No %s addresses available."), FormatOutputType(type))};
2387  }
2388 
2389  spk_man->TopUp();
2390  auto op_dest = spk_man->GetNewDestination(type);
2391  if (op_dest) {
2392  SetAddressBook(*op_dest, label, "receive");
2393  }
2394 
2395  return op_dest;
2396 }
2397 
2399 {
2400  LOCK(cs_wallet);
2401 
2402  ReserveDestination reservedest(this, type);
2403  auto op_dest = reservedest.GetReservedDestination(true);
2404  if (op_dest) reservedest.KeepDestination();
2405 
2406  return op_dest;
2407 }
2408 
2409 std::optional<int64_t> CWallet::GetOldestKeyPoolTime() const
2410 {
2411  LOCK(cs_wallet);
2412  if (m_spk_managers.empty()) {
2413  return std::nullopt;
2414  }
2415 
2416  std::optional<int64_t> oldest_key{std::numeric_limits<int64_t>::max()};
2417  for (const auto& spk_man_pair : m_spk_managers) {
2418  oldest_key = std::min(oldest_key, spk_man_pair.second->GetOldestKeyPoolTime());
2419  }
2420  return oldest_key;
2421 }
2422 
2423 void CWallet::MarkDestinationsDirty(const std::set<CTxDestination>& destinations) {
2424  for (auto& entry : mapWallet) {
2425  CWalletTx& wtx = entry.second;
2426  if (wtx.m_is_cache_empty) continue;
2427  for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
2428  CTxDestination dst;
2429  if (ExtractDestination(wtx.tx->vout[i].scriptPubKey, dst) && destinations.count(dst)) {
2430  wtx.MarkDirty();
2431  break;
2432  }
2433  }
2434  }
2435 }
2436 
2438 {
2440  for (const std::pair<const CTxDestination, CAddressBookData>& item : m_address_book) {
2441  const auto& entry = item.second;
2442  func(item.first, entry.GetLabel(), entry.purpose, entry.IsChange());
2443  }
2444 }
2445 
2446 std::vector<CTxDestination> CWallet::ListAddrBookAddresses(const std::optional<AddrBookFilter>& _filter) const
2447 {
2449  std::vector<CTxDestination> result;
2450  AddrBookFilter filter = _filter ? *_filter : AddrBookFilter();
2451  ForEachAddrBookEntry([&result, &filter](const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change) {
2452  // Filter by change
2453  if (filter.ignore_change && is_change) return;
2454  // Filter by label
2455  if (filter.m_op_label && *filter.m_op_label != label) return;
2456  // All good
2457  result.emplace_back(dest);
2458  });
2459  return result;
2460 }
2461 
2462 std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) const
2463 {
2465  std::set<std::string> label_set;
2466  ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label,
2467  const std::string& _purpose, bool _is_change) {
2468  if (_is_change) return;
2469  if (purpose.empty() || _purpose == purpose) {
2470  label_set.insert(_label);
2471  }
2472  });
2473  return label_set;
2474 }
2475 
2477 {
2478  m_spk_man = pwallet->GetScriptPubKeyMan(type, internal);
2479  if (!m_spk_man) {
2480  return util::Error{strprintf(_("Error: No %s addresses available."), FormatOutputType(type))};
2481  }
2482 
2483  if (nIndex == -1)
2484  {
2485  m_spk_man->TopUp();
2486 
2487  CKeyPool keypool;
2488  auto op_address = m_spk_man->GetReservedDestination(type, internal, nIndex, keypool);
2489  if (!op_address) return op_address;
2490  address = *op_address;
2491  fInternal = keypool.fInternal;
2492  }
2493  return address;
2494 }
2495 
2497 {
2498  if (nIndex != -1) {
2500  }
2501  nIndex = -1;
2502  address = CNoDestination();
2503 }
2504 
2506 {
2507  if (nIndex != -1) {
2509  }
2510  nIndex = -1;
2511  address = CNoDestination();
2512 }
2513 
2515 {
2516  CScript scriptPubKey = GetScriptForDestination(dest);
2517  for (const auto& spk_man : GetScriptPubKeyMans(scriptPubKey)) {
2518  auto signer_spk_man = dynamic_cast<ExternalSignerScriptPubKeyMan *>(spk_man);
2519  if (signer_spk_man == nullptr) {
2520  continue;
2521  }
2523  return signer_spk_man->DisplayAddress(scriptPubKey, signer);
2524  }
2525  return false;
2526 }
2527 
2528 bool CWallet::LockCoin(const COutPoint& output, WalletBatch* batch)
2529 {
2531  setLockedCoins.insert(output);
2532  if (batch) {
2533  return batch->WriteLockedUTXO(output);
2534  }
2535  return true;
2536 }
2537 
2538 bool CWallet::UnlockCoin(const COutPoint& output, WalletBatch* batch)
2539 {
2541  bool was_locked = setLockedCoins.erase(output);
2542  if (batch && was_locked) {
2543  return batch->EraseLockedUTXO(output);
2544  }
2545  return true;
2546 }
2547 
2549 {
2551  bool success = true;
2552  WalletBatch batch(GetDatabase());
2553  for (auto it = setLockedCoins.begin(); it != setLockedCoins.end(); ++it) {
2554  success &= batch.EraseLockedUTXO(*it);
2555  }
2556  setLockedCoins.clear();
2557  return success;
2558 }
2559 
2560 bool CWallet::IsLockedCoin(const COutPoint& output) const
2561 {
2563  return setLockedCoins.count(output) > 0;
2564 }
2565 
2566 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const
2567 {
2569  for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
2570  it != setLockedCoins.end(); it++) {
2571  COutPoint outpt = (*it);
2572  vOutpts.push_back(outpt);
2573  }
2574 }
2575  // end of Actions
2577 
2578 void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const {
2580  mapKeyBirth.clear();
2581 
2582  // map in which we'll infer heights of other keys
2583  std::map<CKeyID, const TxStateConfirmed*> mapKeyFirstBlock;
2584  TxStateConfirmed max_confirm{uint256{}, /*height=*/-1, /*index=*/-1};
2585  max_confirm.confirmed_block_height = GetLastBlockHeight() > 144 ? GetLastBlockHeight() - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
2586  CHECK_NONFATAL(chain().findAncestorByHeight(GetLastBlockHash(), max_confirm.confirmed_block_height, FoundBlock().hash(max_confirm.confirmed_block_hash)));
2587 
2588  {
2590  assert(spk_man != nullptr);
2591  LOCK(spk_man->cs_KeyStore);
2592 
2593  // get birth times for keys with metadata
2594  for (const auto& entry : spk_man->mapKeyMetadata) {
2595  if (entry.second.nCreateTime) {
2596  mapKeyBirth[entry.first] = entry.second.nCreateTime;
2597  }
2598  }
2599 
2600  // Prepare to infer birth heights for keys without metadata
2601  for (const CKeyID &keyid : spk_man->GetKeys()) {
2602  if (mapKeyBirth.count(keyid) == 0)
2603  mapKeyFirstBlock[keyid] = &max_confirm;
2604  }
2605 
2606  // if there are no such keys, we're done
2607  if (mapKeyFirstBlock.empty())
2608  return;
2609 
2610  // find first block that affects those keys, if there are any left
2611  for (const auto& entry : mapWallet) {
2612  // iterate over all wallet transactions...
2613  const CWalletTx &wtx = entry.second;
2614  if (auto* conf = wtx.state<TxStateConfirmed>()) {
2615  // ... which are already in a block
2616  for (const CTxOut &txout : wtx.tx->vout) {
2617  // iterate over all their outputs
2618  for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *spk_man)) {
2619  // ... and all their affected keys
2620  auto rit = mapKeyFirstBlock.find(keyid);
2621  if (rit != mapKeyFirstBlock.end() && conf->confirmed_block_height < rit->second->confirmed_block_height) {
2622  rit->second = conf;
2623  }
2624  }
2625  }
2626  }
2627  }
2628  }
2629 
2630  // Extract block timestamps for those keys
2631  for (const auto& entry : mapKeyFirstBlock) {
2632  int64_t block_time;
2633  CHECK_NONFATAL(chain().findBlock(entry.second->confirmed_block_hash, FoundBlock().time(block_time)));
2634  mapKeyBirth[entry.first] = block_time - TIMESTAMP_WINDOW; // block times can be 2h off
2635  }
2636 }
2637 
2661 unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx, bool rescanning_old_block) const
2662 {
2663  std::optional<uint256> block_hash;
2664  if (auto* conf = wtx.state<TxStateConfirmed>()) {
2665  block_hash = conf->confirmed_block_hash;
2666  } else if (auto* conf = wtx.state<TxStateConflicted>()) {
2667  block_hash = conf->conflicting_block_hash;
2668  }
2669 
2670  unsigned int nTimeSmart = wtx.nTimeReceived;
2671  if (block_hash) {
2672  int64_t blocktime;
2673  int64_t block_max_time;
2674  if (chain().findBlock(*block_hash, FoundBlock().time(blocktime).maxTime(block_max_time))) {
2675  if (rescanning_old_block) {
2676  nTimeSmart = block_max_time;
2677  } else {
2678  int64_t latestNow = wtx.nTimeReceived;
2679  int64_t latestEntry = 0;
2680 
2681  // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
2682  int64_t latestTolerated = latestNow + 300;
2683  const TxItems& txOrdered = wtxOrdered;
2684  for (auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
2685  CWalletTx* const pwtx = it->second;
2686  if (pwtx == &wtx) {
2687  continue;
2688  }
2689  int64_t nSmartTime;
2690  nSmartTime = pwtx->nTimeSmart;
2691  if (!nSmartTime) {
2692  nSmartTime = pwtx->nTimeReceived;
2693  }
2694  if (nSmartTime <= latestTolerated) {
2695  latestEntry = nSmartTime;
2696  if (nSmartTime > latestNow) {
2697  latestNow = nSmartTime;
2698  }
2699  break;
2700  }
2701  }
2702 
2703  nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
2704  }
2705  } else {
2706  WalletLogPrintf("%s: found %s in block %s not in index\n", __func__, wtx.GetHash().ToString(), block_hash->ToString());
2707  }
2708  }
2709  return nTimeSmart;
2710 }
2711 
2712 bool CWallet::SetAddressUsed(WalletBatch& batch, const CTxDestination& dest, bool used)
2713 {
2714  const std::string key{"used"};
2715  if (std::get_if<CNoDestination>(&dest))
2716  return false;
2717 
2718  if (!used) {
2719  if (auto* data = util::FindKey(m_address_book, dest)) data->destdata.erase(key);
2720  return batch.EraseDestData(EncodeDestination(dest), key);
2721  }
2722 
2723  const std::string value{"1"};
2724  m_address_book[dest].destdata.insert(std::make_pair(key, value));
2725  return batch.WriteDestData(EncodeDestination(dest), key, value);
2726 }
2727 
2728 void CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
2729 {
2730  m_address_book[dest].destdata.insert(std::make_pair(key, value));
2731 }
2732 
2734 {
2735  const std::string key{"used"};
2736  std::map<CTxDestination, CAddressBookData>::const_iterator i = m_address_book.find(dest);
2737  if(i != m_address_book.end())
2738  {
2739  CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
2740  if(j != i->second.destdata.end())
2741  {
2742  return true;
2743  }
2744  }
2745  return false;
2746 }
2747 
2748 std::vector<std::string> CWallet::GetAddressReceiveRequests() const
2749 {
2750  const std::string prefix{"rr"};
2751  std::vector<std::string> values;
2752  for (const auto& address : m_address_book) {
2753  for (const auto& data : address.second.destdata) {
2754  if (!data.first.compare(0, prefix.size(), prefix)) {
2755  values.emplace_back(data.second);
2756  }
2757  }
2758  }
2759  return values;
2760 }
2761 
2762 bool CWallet::SetAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id, const std::string& value)
2763 {
2764  const std::string key{"rr" + id}; // "rr" prefix = "receive request" in destdata
2765  CAddressBookData& data = m_address_book.at(dest);
2766  if (value.empty()) {
2767  if (!batch.EraseDestData(EncodeDestination(dest), key)) return false;
2768  data.destdata.erase(key);
2769  } else {
2770  if (!batch.WriteDestData(EncodeDestination(dest), key, value)) return false;
2771  data.destdata[key] = value;
2772  }
2773  return true;
2774 }
2775 
2776 std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string)
2777 {
2778  // Do some checking on wallet path. It should be either a:
2779  //
2780  // 1. Path where a directory can be created.
2781  // 2. Path to an existing directory.
2782  // 3. Path to a symlink to a directory.
2783  // 4. For backwards compatibility, the name of a data file in -walletdir.
2785  fs::file_type path_type = fs::symlink_status(wallet_path).type();
2786  if (!(path_type == fs::file_type::not_found || path_type == fs::file_type::directory ||
2787  (path_type == fs::file_type::symlink && fs::is_directory(wallet_path)) ||
2788  (path_type == fs::file_type::regular && fs::PathFromString(name).filename() == fs::PathFromString(name)))) {
2789  error_string = Untranslated(strprintf(
2790  "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
2791  "database/log.?????????? files can be stored, a location where such a directory could be created, "
2792  "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
2795  return nullptr;
2796  }
2797  return MakeDatabase(wallet_path, options, status, error_string);
2798 }
2799 
2800 std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::string& name, std::unique_ptr<WalletDatabase> database, uint64_t wallet_creation_flags, bilingual_str& error, std::vector<bilingual_str>& warnings)
2801 {
2802  interfaces::Chain* chain = context.chain;
2803  ArgsManager& args = *Assert(context.args);
2804  const std::string& walletFile = database->Filename();
2805 
2806  const auto start{SteadyClock::now()};
2807  // TODO: Can't use std::make_shared because we need a custom deleter but
2808  // should be possible to use std::allocate_shared.
2809  const std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, args, std::move(database)), ReleaseWallet);
2810  bool rescan_required = false;
2811  DBErrors nLoadWalletRet = walletInstance->LoadWallet();
2812  if (nLoadWalletRet != DBErrors::LOAD_OK) {
2813  if (nLoadWalletRet == DBErrors::CORRUPT) {
2814  error = strprintf(_("Error loading %s: Wallet corrupted"), walletFile);
2815  return nullptr;
2816  }
2817  else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
2818  {
2819  warnings.push_back(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
2820  " or address book entries might be missing or incorrect."),
2821  walletFile));
2822  }
2823  else if (nLoadWalletRet == DBErrors::TOO_NEW) {
2824  error = strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, PACKAGE_NAME);
2825  return nullptr;
2826  }
2827  else if (nLoadWalletRet == DBErrors::EXTERNAL_SIGNER_SUPPORT_REQUIRED) {
2828  error = strprintf(_("Error loading %s: External signer wallet being loaded without external signer support compiled"), walletFile);
2829  return nullptr;
2830  }
2831  else if (nLoadWalletRet == DBErrors::NEED_REWRITE)
2832  {
2833  error = strprintf(_("Wallet needed to be rewritten: restart %s to complete"), PACKAGE_NAME);
2834  return nullptr;
2835  } else if (nLoadWalletRet == DBErrors::NEED_RESCAN) {
2836  warnings.push_back(strprintf(_("Error reading %s! Transaction data may be missing or incorrect."
2837  " Rescanning wallet."), walletFile));
2838  rescan_required = true;
2839  } else if (nLoadWalletRet == DBErrors::UNKNOWN_DESCRIPTOR) {
2840  error = strprintf(_("Unrecognized descriptor found. Loading wallet %s\n\n"
2841  "The wallet might had been created on a newer version.\n"
2842  "Please try running the latest software version.\n"), walletFile);
2843  return nullptr;
2844  } else {
2845  error = strprintf(_("Error loading %s"), walletFile);
2846  return nullptr;
2847  }
2848  }
2849 
2850  // This wallet is in its first run if there are no ScriptPubKeyMans and it isn't blank or no privkeys
2851  const bool fFirstRun = walletInstance->m_spk_managers.empty() &&
2852  !walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) &&
2853  !walletInstance->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
2854  if (fFirstRun)
2855  {
2856  // ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
2857  walletInstance->SetMinVersion(FEATURE_LATEST);
2858 
2859  walletInstance->InitWalletFlags(wallet_creation_flags);
2860 
2861  // Only create LegacyScriptPubKeyMan when not descriptor wallet
2862  if (!walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
2863  walletInstance->SetupLegacyScriptPubKeyMan();
2864  }
2865 
2866  if ((wallet_creation_flags & WALLET_FLAG_EXTERNAL_SIGNER) || !(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) {
2867  LOCK(walletInstance->cs_wallet);
2868  if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
2869  walletInstance->SetupDescriptorScriptPubKeyMans();
2870  // SetupDescriptorScriptPubKeyMans already calls SetupGeneration for us so we don't need to call SetupGeneration separately
2871  } else {
2872  // Legacy wallets need SetupGeneration here.
2873  for (auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
2874  if (!spk_man->SetupGeneration()) {
2875  error = _("Unable to generate initial keys");
2876  return nullptr;
2877  }
2878  }
2879  }
2880  }
2881 
2882  if (chain) {
2883  walletInstance->chainStateFlushed(chain->getTipLocator());
2884  }
2885  } else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
2886  // Make it impossible to disable private keys after creation
2887  error = strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile);
2888  return nullptr;
2889  } else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
2890  for (auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
2891  if (spk_man->HavePrivateKeys()) {
2892  warnings.push_back(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
2893  break;
2894  }
2895  }
2896  }
2897 
2898  if (!args.GetArg("-addresstype", "").empty()) {
2899  std::optional<OutputType> parsed = ParseOutputType(args.GetArg("-addresstype", ""));
2900  if (!parsed) {
2901  error = strprintf(_("Unknown address type '%s'"), args.GetArg("-addresstype", ""));
2902  return nullptr;
2903  }
2904  walletInstance->m_default_address_type = parsed.value();
2905  }
2906 
2907  if (!args.GetArg("-changetype", "").empty()) {
2908  std::optional<OutputType> parsed = ParseOutputType(args.GetArg("-changetype", ""));
2909  if (!parsed) {
2910  error = strprintf(_("Unknown change type '%s'"), args.GetArg("-changetype", ""));
2911  return nullptr;
2912  }
2913  walletInstance->m_default_change_type = parsed.value();
2914  }
2915 
2916  if (args.IsArgSet("-mintxfee")) {
2917  std::optional<CAmount> min_tx_fee = ParseMoney(args.GetArg("-mintxfee", ""));
2918  if (!min_tx_fee || min_tx_fee.value() == 0) {
2919  error = AmountErrMsg("mintxfee", args.GetArg("-mintxfee", ""));
2920  return nullptr;
2921  } else if (min_tx_fee.value() > HIGH_TX_FEE_PER_KB) {
2922  warnings.push_back(AmountHighWarn("-mintxfee") + Untranslated(" ") +
2923  _("This is the minimum transaction fee you pay on every transaction."));
2924  }
2925 
2926  walletInstance->m_min_fee = CFeeRate{min_tx_fee.value()};
2927  }
2928 
2929  if (args.IsArgSet("-maxapsfee")) {
2930  const std::string max_aps_fee{args.GetArg("-maxapsfee", "")};
2931  if (max_aps_fee == "-1") {
2932  walletInstance->m_max_aps_fee = -1;
2933  } else if (std::optional<CAmount> max_fee = ParseMoney(max_aps_fee)) {
2934  if (max_fee.value() > HIGH_APS_FEE) {
2935  warnings.push_back(AmountHighWarn("-maxapsfee") + Untranslated(" ") +
2936  _("This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection."));
2937  }
2938  walletInstance->m_max_aps_fee = max_fee.value();
2939  } else {
2940  error = AmountErrMsg("maxapsfee", max_aps_fee);
2941  return nullptr;
2942  }
2943  }
2944 
2945  if (args.IsArgSet("-fallbackfee")) {
2946  std::optional<CAmount> fallback_fee = ParseMoney(args.GetArg("-fallbackfee", ""));
2947  if (!fallback_fee) {
2948  error = strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), args.GetArg("-fallbackfee", ""));
2949  return nullptr;
2950  } else if (fallback_fee.value() > HIGH_TX_FEE_PER_KB) {
2951  warnings.push_back(AmountHighWarn("-fallbackfee") + Untranslated(" ") +
2952  _("This is the transaction fee you may pay when fee estimates are not available."));
2953  }
2954  walletInstance->m_fallback_fee = CFeeRate{fallback_fee.value()};
2955  }
2956 
2957  // Disable fallback fee in case value was set to 0, enable if non-null value
2958  walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
2959 
2960  if (args.IsArgSet("-discardfee")) {
2961  std::optional<CAmount> discard_fee = ParseMoney(args.GetArg("-discardfee", ""));
2962  if (!discard_fee) {
2963  error = strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), args.GetArg("-discardfee", ""));
2964  return nullptr;
2965  } else if (discard_fee.value() > HIGH_TX_FEE_PER_KB) {
2966  warnings.push_back(AmountHighWarn("-discardfee") + Untranslated(" ") +
2967  _("This is the transaction fee you may discard if change is smaller than dust at this level"));
2968  }
2969  walletInstance->m_discard_rate = CFeeRate{discard_fee.value()};
2970  }
2971 
2972  if (args.IsArgSet("-paytxfee")) {
2973  std::optional<CAmount> pay_tx_fee = ParseMoney(args.GetArg("-paytxfee", ""));
2974  if (!pay_tx_fee) {
2975  error = AmountErrMsg("paytxfee", args.GetArg("-paytxfee", ""));
2976  return nullptr;
2977  } else if (pay_tx_fee.value() > HIGH_TX_FEE_PER_KB) {
2978  warnings.push_back(AmountHighWarn("-paytxfee") + Untranslated(" ") +
2979  _("This is the transaction fee you will pay if you send a transaction."));
2980  }
2981 
2982  walletInstance->m_pay_tx_fee = CFeeRate{pay_tx_fee.value(), 1000};
2983 
2984  if (chain && walletInstance->m_pay_tx_fee < chain->relayMinFee()) {
2985  error = strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
2986  args.GetArg("-paytxfee", ""), chain->relayMinFee().ToString());
2987  return nullptr;
2988  }
2989  }
2990 
2991  if (args.IsArgSet("-maxtxfee")) {
2992  std::optional<CAmount> max_fee = ParseMoney(args.GetArg("-maxtxfee", ""));
2993  if (!max_fee) {
2994  error = AmountErrMsg("maxtxfee", args.GetArg("-maxtxfee", ""));
2995  return nullptr;
2996  } else if (max_fee.value() > HIGH_MAX_TX_FEE) {
2997  warnings.push_back(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
2998  }
2999 
3000  if (chain && CFeeRate{max_fee.value(), 1000} < chain->relayMinFee()) {
3001  error = strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
3002  args.GetArg("-maxtxfee", ""), chain->relayMinFee().ToString());
3003  return nullptr;
3004  }
3005 
3006  walletInstance->m_default_max_tx_fee = max_fee.value();
3007  }
3008 
3009  if (args.IsArgSet("-consolidatefeerate")) {
3010  if (std::optional<CAmount> consolidate_feerate = ParseMoney(args.GetArg("-consolidatefeerate", ""))) {
3011  walletInstance->m_consolidate_feerate = CFeeRate(*consolidate_feerate);
3012  } else {
3013  error = AmountErrMsg("consolidatefeerate", args.GetArg("-consolidatefeerate", ""));
3014  return nullptr;
3015  }
3016  }
3017 
3019  warnings.push_back(AmountHighWarn("-minrelaytxfee") + Untranslated(" ") +
3020  _("The wallet will avoid paying less than the minimum relay fee."));
3021  }
3022 
3023  walletInstance->m_confirm_target = args.GetIntArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
3024  walletInstance->m_spend_zero_conf_change = args.GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE);
3025  walletInstance->m_signal_rbf = args.GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF);
3026 
3027  walletInstance->WalletLogPrintf("Wallet completed loading in %15dms\n", Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
3028 
3029  // Try to top up keypool. No-op if the wallet is locked.
3030  walletInstance->TopUpKeyPool();
3031 
3032  if (chain && !AttachChain(walletInstance, *chain, rescan_required, error, warnings)) {
3033  return nullptr;
3034  }
3035 
3036  {
3037  LOCK(walletInstance->cs_wallet);
3038  walletInstance->SetBroadcastTransactions(args.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
3039  walletInstance->WalletLogPrintf("setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
3040  walletInstance->WalletLogPrintf("mapWallet.size() = %u\n", walletInstance->mapWallet.size());
3041  walletInstance->WalletLogPrintf("m_address_book.size() = %u\n", walletInstance->m_address_book.size());
3042  }
3043 
3044  return walletInstance;
3045 }
3046 
3047 bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interfaces::Chain& chain, const bool rescan_required, bilingual_str& error, std::vector<bilingual_str>& warnings)
3048 {
3049  LOCK(walletInstance->cs_wallet);
3050  // allow setting the chain if it hasn't been set already but prevent changing it
3051  assert(!walletInstance->m_chain || walletInstance->m_chain == &chain);
3052  walletInstance->m_chain = &chain;
3053 
3054  // Unless allowed, ensure wallet files are not reused across chains:
3055  if (!gArgs.GetBoolArg("-walletcrosschain", DEFAULT_WALLETCROSSCHAIN)) {
3056  WalletBatch batch(walletInstance->GetDatabase());
3057  CBlockLocator locator;
3058  if (batch.ReadBestBlock(locator) && locator.vHave.size() > 0 && chain.getHeight()) {
3059  // Wallet is assumed to be from another chain, if genesis block in the active
3060  // chain differs from the genesis block known to the wallet.
3061  if (chain.getBlockHash(0) != locator.vHave.back()) {
3062  error = Untranslated("Wallet files should not be reused across chains. Restart bitcoind with -walletcrosschain to override.");
3063  return false;
3064  }
3065  }
3066  }
3067 
3068  // Register wallet with validationinterface. It's done before rescan to avoid
3069  // missing block connections between end of rescan and validation subscribing.
3070  // Because of wallet lock being hold, block connection notifications are going to
3071  // be pending on the validation-side until lock release. It's likely to have
3072  // block processing duplicata (if rescan block range overlaps with notification one)
3073  // but we guarantee at least than wallet state is correct after notifications delivery.
3074  // However, chainStateFlushed notifications are ignored until the rescan is finished
3075  // so that in case of a shutdown event, the rescan will be repeated at the next start.
3076  // This is temporary until rescan and notifications delivery are unified under same
3077  // interface.
3078  walletInstance->m_attaching_chain = true; //ignores chainStateFlushed notifications
3079  walletInstance->m_chain_notifications_handler = walletInstance->chain().handleNotifications(walletInstance);
3080 
3081  // If rescan_required = true, rescan_height remains equal to 0
3082  int rescan_height = 0;
3083  if (!rescan_required)
3084  {
3085  WalletBatch batch(walletInstance->GetDatabase());
3086  CBlockLocator locator;
3087  if (batch.ReadBestBlock(locator)) {
3088  if (const std::optional<int> fork_height = chain.findLocatorFork(locator)) {
3089  rescan_height = *fork_height;
3090  }
3091  }
3092  }
3093 
3094  const std::optional<int> tip_height = chain.getHeight();
3095  if (tip_height) {
3096  walletInstance->m_last_block_processed = chain.getBlockHash(*tip_height);
3097  walletInstance->m_last_block_processed_height = *tip_height;
3098  } else {
3099  walletInstance->m_last_block_processed.SetNull();
3100  walletInstance->m_last_block_processed_height = -1;
3101  }
3102 
3103  if (tip_height && *tip_height != rescan_height)
3104  {
3105  // No need to read and scan block if block was created before
3106  // our wallet birthday (as adjusted for block time variability)
3107  std::optional<int64_t> time_first_key;
3108  for (auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
3109  int64_t time = spk_man->GetTimeFirstKey();
3110  if (!time_first_key || time < *time_first_key) time_first_key = time;
3111  }
3112  if (time_first_key) {
3113  FoundBlock found = FoundBlock().height(rescan_height);
3114  chain.findFirstBlockWithTimeAndHeight(*time_first_key - TIMESTAMP_WINDOW, rescan_height, found);
3115  if (!found.found) {
3116  // We were unable to find a block that had a time more recent than our earliest timestamp
3117  // or a height higher than the wallet was synced to, indicating that the wallet is newer than the
3118  // current chain tip. Skip rescanning in this case.
3119  rescan_height = *tip_height;
3120  }
3121  }
3122 
3123  // Technically we could execute the code below in any case, but performing the
3124  // `while` loop below can make startup very slow, so only check blocks on disk
3125  // if necessary.
3127  int block_height = *tip_height;
3128  while (block_height > 0 && chain.haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
3129  --block_height;
3130  }
3131 
3132  if (rescan_height != block_height) {
3133  // We can't rescan beyond blocks we don't have data for, stop and throw an error.
3134  // This might happen if a user uses an old wallet within a pruned node
3135  // or if they ran -disablewallet for a longer time, then decided to re-enable
3136  // Exit early and print an error.
3137  // It also may happen if an assumed-valid chain is in use and therefore not
3138  // all block data is available.
3139  // If a block is pruned after this check, we will load the wallet,
3140  // but fail the rescan with a generic error.
3141 
3143  _(
3144  "Assumed-valid: last wallet synchronisation goes beyond "
3145  "available block data. You need to wait for the background "
3146  "validation chain to download more blocks.") :
3147  _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
3148  return false;
3149  }
3150  }
3151 
3152  chain.initMessage(_("Rescanning…").translated);
3153  walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
3154 
3155  {
3156  WalletRescanReserver reserver(*walletInstance);
3157  if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/true).status)) {
3158  error = _("Failed to rescan the wallet during initialization");
3159  return false;
3160  }
3161  }
3162  walletInstance->m_attaching_chain = false;
3163  walletInstance->chainStateFlushed(chain.getTipLocator());
3164  walletInstance->GetDatabase().IncrementUpdateCounter();
3165  }
3166  walletInstance->m_attaching_chain = false;
3167 
3168  return true;
3169 }
3170 
3171 const CAddressBookData* CWallet::FindAddressBookEntry(const CTxDestination& dest, bool allow_change) const
3172 {
3173  const auto& address_book_it = m_address_book.find(dest);
3174  if (address_book_it == m_address_book.end()) return nullptr;
3175  if ((!allow_change) && address_book_it->second.IsChange()) {
3176  return nullptr;
3177  }
3178  return &address_book_it->second;
3179 }
3180 
3182 {
3183  int prev_version = GetVersion();
3184  if (version == 0) {
3185  WalletLogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
3186  version = FEATURE_LATEST;
3187  } else {
3188  WalletLogPrintf("Allowing wallet upgrade up to %i\n", version);
3189  }
3190  if (version < prev_version) {
3191  error = strprintf(_("Cannot downgrade wallet from version %i to version %i. Wallet version unchanged."), prev_version, version);
3192  return false;
3193  }
3194 
3195  LOCK(cs_wallet);
3196 
3197  // Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT
3199  error = strprintf(_("Cannot upgrade a non HD split wallet from version %i to version %i without upgrading to support pre-split keypool. Please use version %i or no version specified."), prev_version, version, FEATURE_PRE_SPLIT_KEYPOOL);
3200  return false;
3201  }
3202 
3203  // Permanently upgrade to the version
3205 
3206  for (auto spk_man : GetActiveScriptPubKeyMans()) {
3207  if (!spk_man->Upgrade(prev_version, version, error)) {
3208  return false;
3209  }
3210  }
3211  return true;
3212 }
3213 
3215 {
3216  // Add wallet transactions that aren't already in a block to mempool
3217  // Do this here as mempool requires genesis block to be loaded
3218  ResubmitWalletTransactions(/*relay=*/false, /*force=*/true);
3219 
3220  // Update wallet transactions with current mempool transactions.
3221  WITH_LOCK(cs_wallet, chain().requestMempoolTransactions(*this));
3222 }
3223 
3224 bool CWallet::BackupWallet(const std::string& strDest) const
3225 {
3226  return GetDatabase().Backup(strDest);
3227 }
3228 
3230 {
3231  nTime = GetTime();
3232  fInternal = false;
3233  m_pre_split = false;
3234 }
3235 
3236 CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn)
3237 {
3238  nTime = GetTime();
3239  vchPubKey = vchPubKeyIn;
3240  fInternal = internalIn;
3241  m_pre_split = false;
3242 }
3243 
3245 {
3247  if (auto* conf = wtx.state<TxStateConfirmed>()) {
3248  return GetLastBlockHeight() - conf->confirmed_block_height + 1;
3249  } else if (auto* conf = wtx.state<TxStateConflicted>()) {
3250  return -1 * (GetLastBlockHeight() - conf->conflicting_block_height + 1);
3251  } else {
3252  return 0;
3253  }
3254 }
3255 
3257 {
3259 
3260  if (!wtx.IsCoinBase()) {
3261  return 0;
3262  }
3263  int chain_depth = GetTxDepthInMainChain(wtx);
3264  assert(chain_depth >= 0); // coinbase tx should not be conflicted
3265  return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
3266 }
3267 
3269 {
3271 
3272  // note GetBlocksToMaturity is 0 for non-coinbase tx
3273  return GetTxBlocksToMaturity(wtx) > 0;
3274 }
3275 
3277 {
3278  return HasEncryptionKeys();
3279 }
3280 
3281 bool CWallet::IsLocked() const
3282 {
3283  if (!IsCrypted()) {
3284  return false;
3285  }
3286  LOCK(cs_wallet);
3287  return vMasterKey.empty();
3288 }
3289 
3291 {
3292  if (!IsCrypted())
3293  return false;
3294 
3295  {
3296  LOCK(cs_wallet);
3297  if (!vMasterKey.empty()) {
3298  memory_cleanse(vMasterKey.data(), vMasterKey.size() * sizeof(decltype(vMasterKey)::value_type));
3299  vMasterKey.clear();
3300  }
3301  }
3302 
3303  NotifyStatusChanged(this);
3304  return true;
3305 }
3306 
3307 bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool accept_no_keys)
3308 {
3309  {
3310  LOCK(cs_wallet);
3311  for (const auto& spk_man_pair : m_spk_managers) {
3312  if (!spk_man_pair.second->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) {
3313  return false;
3314  }
3315  }
3316  vMasterKey = vMasterKeyIn;
3317  }
3318  NotifyStatusChanged(this);
3319  return true;
3320 }
3321 
3322 std::set<ScriptPubKeyMan*> CWallet::GetActiveScriptPubKeyMans() const
3323 {
3324  std::set<ScriptPubKeyMan*> spk_mans;
3325  for (bool internal : {false, true}) {
3326  for (OutputType t : OUTPUT_TYPES) {
3327  auto spk_man = GetScriptPubKeyMan(t, internal);
3328  if (spk_man) {
3329  spk_mans.insert(spk_man);
3330  }
3331  }
3332  }
3333  return spk_mans;
3334 }
3335 
3336 std::set<ScriptPubKeyMan*> CWallet::GetAllScriptPubKeyMans() const
3337 {
3338  std::set<ScriptPubKeyMan*> spk_mans;
3339  for (const auto& spk_man_pair : m_spk_managers) {
3340  spk_mans.insert(spk_man_pair.second.get());
3341  }
3342  return spk_mans;
3343 }
3344 
3345 ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(const OutputType& type, bool internal) const
3346 {
3347  const std::map<OutputType, ScriptPubKeyMan*>& spk_managers = internal ? m_internal_spk_managers : m_external_spk_managers;
3348  std::map<OutputType, ScriptPubKeyMan*>::const_iterator it = spk_managers.find(type);
3349  if (it == spk_managers.end()) {
3350  return nullptr;
3351  }
3352  return it->second;
3353 }
3354 
3355 std::set<ScriptPubKeyMan*> CWallet::GetScriptPubKeyMans(const CScript& script) const
3356 {
3357  std::set<ScriptPubKeyMan*> spk_mans;
3358  SignatureData sigdata;
3359  for (const auto& spk_man_pair : m_spk_managers) {
3360  if (spk_man_pair.second->CanProvide(script, sigdata)) {
3361  spk_mans.insert(spk_man_pair.second.get());
3362  }
3363  }
3364  return spk_mans;
3365 }
3366 
3368 {
3369  if (m_spk_managers.count(id) > 0) {
3370  return m_spk_managers.at(id).get();
3371  }
3372  return nullptr;
3373 }
3374 
3375 std::unique_ptr<SigningProvider> CWallet::GetSolvingProvider(const CScript& script) const
3376 {
3377  SignatureData sigdata;
3378  return GetSolvingProvider(script, sigdata);
3379 }
3380 
3381 std::unique_ptr<SigningProvider> CWallet::GetSolvingProvider(const CScript& script, SignatureData& sigdata) const
3382 {
3383  for (const auto& spk_man_pair : m_spk_managers) {
3384  if (spk_man_pair.second->CanProvide(script, sigdata)) {
3385  return spk_man_pair.second->GetSolvingProvider(script);
3386  }
3387  }
3388  return nullptr;
3389 }
3390 
3391 std::vector<WalletDescriptor> CWallet::GetWalletDescriptors(const CScript& script) const
3392 {
3393  std::vector<WalletDescriptor> descs;
3394  for (const auto spk_man: GetScriptPubKeyMans(script)) {
3395  if (const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man)) {
3396  LOCK(desc_spk_man->cs_desc_man);
3397  descs.push_back(desc_spk_man->GetWalletDescriptor());
3398  }
3399  }
3400  return descs;
3401 }
3402 
3404 {
3406  return nullptr;
3407  }
3408  // Legacy wallets only have one ScriptPubKeyMan which is a LegacyScriptPubKeyMan.
3409  // Everything in m_internal_spk_managers and m_external_spk_managers point to the same legacyScriptPubKeyMan.
3411  if (it == m_internal_spk_managers.end()) return nullptr;
3412  return dynamic_cast<LegacyScriptPubKeyMan*>(it->second);
3413 }
3414 
3416 {
3418  return GetLegacyScriptPubKeyMan();
3419 }
3420 
3422 {
3424  return;
3425  }
3426 
3427  auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new LegacyScriptPubKeyMan(*this));
3428  for (const auto& type : LEGACY_OUTPUT_TYPES) {
3429  m_internal_spk_managers[type] = spk_manager.get();
3430  m_external_spk_managers[type] = spk_manager.get();
3431  }
3432  m_spk_managers[spk_manager->GetID()] = std::move(spk_manager);
3433 }
3434 
3436 {
3437  return vMasterKey;
3438 }
3439 
3441 {
3442  return !mapMasterKeys.empty();
3443 }
3444 
3446 {
3447  for (const auto& spk_man : GetActiveScriptPubKeyMans()) {
3448  spk_man->NotifyWatchonlyChanged.connect(NotifyWatchonlyChanged);
3449  spk_man->NotifyCanGetAddressesChanged.connect(NotifyCanGetAddressesChanged);
3450  }
3451 }
3452 
3454 {
3456  auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(*this, desc));
3457  m_spk_managers[id] = std::move(spk_manager);
3458  } else {
3459  auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, desc));
3460  m_spk_managers[id] = std::move(spk_manager);
3461  }
3462 }
3463 
3465 {
3467 
3468  for (bool internal : {false, true}) {
3469  for (OutputType t : OUTPUT_TYPES) {
3470  auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this));
3471  if (IsCrypted()) {
3472  if (IsLocked()) {
3473  throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors");
3474  }
3475  if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey, nullptr)) {
3476  throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors");
3477  }
3478  }
3479  spk_manager->SetupDescriptorGeneration(master_key, t, internal);
3480  uint256 id = spk_manager->GetID();
3481  m_spk_managers[id] = std::move(spk_manager);
3482  AddActiveScriptPubKeyMan(id, t, internal);
3483  }
3484  }
3485 }
3486 
3488 {
3490 
3492  // Make a seed
3493  CKey seed_key;
3494  seed_key.MakeNewKey(true);
3495  CPubKey seed = seed_key.GetPubKey();
3496  assert(seed_key.VerifyPubKey(seed));
3497 
3498  // Get the extended key
3499  CExtKey master_key;
3500  master_key.SetSeed(seed_key);
3501 
3502  SetupDescriptorScriptPubKeyMans(master_key);
3503  } else {
3505 
3506  // TODO: add account parameter
3507  int account = 0;
3508  UniValue signer_res = signer.GetDescriptors(account);
3509 
3510  if (!signer_res.isObject()) throw std::runtime_error(std::string(__func__) + ": Unexpected result");
3511  for (bool internal : {false, true}) {
3512  const UniValue& descriptor_vals = find_value(signer_res, internal ? "internal" : "receive");
3513  if (!descriptor_vals.isArray()) throw std::runtime_error(std::string(__func__) + ": Unexpected result");
3514  for (const UniValue& desc_val : descriptor_vals.get_array().getValues()) {
3515  const std::string& desc_str = desc_val.getValStr();
3516  FlatSigningProvider keys;
3517  std::string desc_error;
3518  std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, desc_error, false);
3519  if (desc == nullptr) {
3520  throw std::runtime_error(std::string(__func__) + ": Invalid descriptor \"" + desc_str + "\" (" + desc_error + ")");
3521  }
3522  if (!desc->GetOutputType()) {
3523  continue;
3524  }
3525  OutputType t = *desc->GetOutputType();
3526  auto spk_manager = std::unique_ptr<ExternalSignerScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(*this));
3527  spk_manager->SetupDescriptor(std::move(desc));
3528  uint256 id = spk_manager->GetID();
3529  m_spk_managers[id] = std::move(spk_manager);
3530  AddActiveScriptPubKeyMan(id, t, internal);
3531  }
3532  }
3533  }
3534 }
3535 
3537 {
3538  WalletBatch batch(GetDatabase());
3539  if (!batch.WriteActiveScriptPubKeyMan(static_cast<uint8_t>(type), id, internal)) {
3540  throw std::runtime_error(std::string(__func__) + ": writing active ScriptPubKeyMan id failed");
3541  }
3542  LoadActiveScriptPubKeyMan(id, type, internal);
3543 }
3544 
3546 {
3547  // Activating ScriptPubKeyManager for a given output and change type is incompatible with legacy wallets.
3548  // Legacy wallets have only one ScriptPubKeyManager and it's active for all output and change types.
3550 
3551  WalletLogPrintf("Setting spkMan to active: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(type), internal ? "true" : "false");
3552  auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
3553  auto& spk_mans_other = internal ? m_external_spk_managers : m_internal_spk_managers;
3554  auto spk_man = m_spk_managers.at(id).get();
3555  spk_mans[type] = spk_man;
3556 
3557  const auto it = spk_mans_other.find(type);
3558  if (it != spk_mans_other.end() && it->second == spk_man) {
3559  spk_mans_other.erase(type);
3560  }
3561 
3563 }
3564 
3566 {
3567  auto spk_man = GetScriptPubKeyMan(type, internal);
3568  if (spk_man != nullptr && spk_man->GetID() == id) {
3569  WalletLogPrintf("Deactivate spkMan: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(type), internal ? "true" : "false");
3570  WalletBatch batch(GetDatabase());
3571  if (!batch.EraseActiveScriptPubKeyMan(static_cast<uint8_t>(type), internal)) {
3572  throw std::runtime_error(std::string(__func__) + ": erasing active ScriptPubKeyMan id failed");
3573  }
3574 
3575  auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
3576  spk_mans.erase(type);
3577  }
3578 
3580 }
3581 
3582 bool CWallet::IsLegacy() const
3583 {
3584  if (m_internal_spk_managers.count(OutputType::LEGACY) == 0) {
3585  return false;
3586  }
3587  auto spk_man = dynamic_cast<LegacyScriptPubKeyMan*>(m_internal_spk_managers.at(OutputType::LEGACY));
3588  return spk_man != nullptr;
3589 }
3590 
3592 {
3593  for (auto& spk_man_pair : m_spk_managers) {
3594  // Try to downcast to DescriptorScriptPubKeyMan then check if the descriptors match
3595  DescriptorScriptPubKeyMan* spk_manager = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man_pair.second.get());
3596  if (spk_manager != nullptr && spk_manager->HasWalletDescriptor(desc)) {
3597  return spk_manager;
3598  }
3599  }
3600 
3601  return nullptr;
3602 }
3603 
3604 std::optional<bool> CWallet::IsInternalScriptPubKeyMan(ScriptPubKeyMan* spk_man) const
3605 {
3606  // Legacy script pubkey man can't be either external or internal
3607  if (IsLegacy()) {
3608  return std::nullopt;
3609  }
3610 
3611  // only active ScriptPubKeyMan can be internal
3612  if (!GetActiveScriptPubKeyMans().count(spk_man)) {
3613  return std::nullopt;
3614  }
3615 
3616  const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man);
3617  if (!desc_spk_man) {
3618  throw std::runtime_error(std::string(__func__) + ": unexpected ScriptPubKeyMan type.");
3619  }
3620 
3621  LOCK(desc_spk_man->cs_desc_man);
3622  const auto& type = desc_spk_man->GetWalletDescriptor().descriptor->GetOutputType();
3623  assert(type.has_value());
3624 
3625  return GetScriptPubKeyMan(*type, /* internal= */ true) == desc_spk_man;
3626 }
3627 
3628 ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal)
3629 {
3631 
3633  WalletLogPrintf("Cannot add WalletDescriptor to a non-descriptor wallet\n");
3634  return nullptr;
3635  }
3636 
3637  auto spk_man = GetDescriptorScriptPubKeyMan(desc);
3638  if (spk_man) {
3639  WalletLogPrintf("Update existing descriptor: %s\n", desc.descriptor->ToString());
3640  spk_man->UpdateWalletDescriptor(desc);
3641  } else {
3642  auto new_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, desc));
3643  spk_man = new_spk_man.get();
3644 
3645  // Save the descriptor to memory
3646  m_spk_managers[new_spk_man->GetID()] = std::move(new_spk_man);
3647  }
3648 
3649  // Add the private keys to the descriptor
3650  for (const auto& entry : signing_provider.keys) {
3651  const CKey& key = entry.second;
3652  spk_man->AddDescriptorKey(key, key.GetPubKey());
3653  }
3654 
3655  // Top up key pool, the manager will generate new scriptPubKeys internally
3656  if (!spk_man->TopUp()) {
3657  WalletLogPrintf("Could not top up scriptPubKeys\n");
3658  return nullptr;
3659  }
3660 
3661  // Apply the label if necessary
3662  // Note: we disable labels for ranged descriptors
3663  if (!desc.descriptor->IsRange()) {
3664  auto script_pub_keys = spk_man->GetScriptPubKeys();
3665  if (script_pub_keys.empty()) {
3666  WalletLogPrintf("Could not generate scriptPubKeys (cache is empty)\n");
3667  return nullptr;
3668  }
3669 
3670  if (!internal) {
3671  for (const auto& script : script_pub_keys) {
3672  CTxDestination dest;
3673  if (ExtractDestination(script, dest)) {
3674  SetAddressBook(dest, label, "receive");
3675  }
3676  }
3677  }
3678  }
3679 
3680  // Save the descriptor to DB
3681  spk_man->WriteDescriptor();
3682 
3683  return spk_man;
3684 }
3685 
3687 {
3689 
3690  WalletLogPrintf("Migrating wallet storage database from BerkeleyDB to SQLite.\n");
3691 
3692  if (m_database->Format() == "sqlite") {
3693  error = _("Error: This wallet already uses SQLite");
3694  return false;
3695  }
3696 
3697  // Get all of the records for DB type migration
3698  std::unique_ptr<DatabaseBatch> batch = m_database->MakeBatch();
3699  std::vector<std::pair<SerializeData, SerializeData>> records;
3700  if (!batch->StartCursor()) {
3701  error = _("Error: Unable to begin reading all records in the database");
3702  return false;
3703  }
3704  bool complete = false;
3705  while (true) {
3707  CDataStream ss_value(SER_DISK, CLIENT_VERSION);
3708  bool ret = batch->ReadAtCursor(ss_key, ss_value, complete);
3709  if (!ret) {
3710  break;
3711  }
3712  SerializeData key(ss_key.begin(), ss_key.end());
3713  SerializeData value(ss_value.begin(), ss_value.end());
3714  records.emplace_back(key, value);
3715  }
3716  batch->CloseCursor();
3717  batch.reset();
3718  if (!complete) {
3719  error = _("Error: Unable to read all records in the database");
3720  return false;
3721  }
3722 
3723  // Close this database and delete the file
3724  fs::path db_path = fs::PathFromString(m_database->Filename());
3725  fs::path db_dir = db_path.parent_path();
3726  m_database->Close();
3727  fs::remove(db_path);
3728 
3729  // Make new DB
3730  DatabaseOptions opts;
3731  opts.require_create = true;
3733  DatabaseStatus db_status;
3734  std::unique_ptr<WalletDatabase> new_db = MakeDatabase(db_dir, opts, db_status, error);
3735  assert(new_db); // This is to prevent doing anything further with this wallet. The original file was deleted, but a backup exists.
3736  m_database.reset();
3737  m_database = std::move(new_db);
3738 
3739  // Write existing records into the new DB
3740  batch = m_database->MakeBatch();
3741  bool began = batch->TxnBegin();
3742  assert(began); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution.
3743  for (const auto& [key, value] : records) {
3744  CDataStream ss_key(key, SER_DISK, CLIENT_VERSION);
3745  CDataStream ss_value(value, SER_DISK, CLIENT_VERSION);
3746  if (!batch->Write(ss_key, ss_value)) {
3747  batch->TxnAbort();
3748  m_database->Close();
3749  fs::remove(m_database->Filename());
3750  assert(false); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution.
3751  }
3752  }
3753  bool committed = batch->TxnCommit();
3754  assert(committed); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution.
3755  return true;
3756 }
3757 
3758 std::optional<MigrationData> CWallet::GetDescriptorsForLegacy(bilingual_str& error) const
3759 {
3761 
3763  if (!legacy_spkm) {
3764  error = _("Error: This wallet is already a descriptor wallet");
3765  return std::nullopt;
3766  }
3767 
3768  std::optional<MigrationData> res = legacy_spkm->MigrateToDescriptor();
3769  if (res == std::nullopt) {
3770  error = _("Error: Unable to produce descriptors for this legacy wallet. Make sure to provide the wallet's passphrase if it is encrypted.");
3771  return std::nullopt;
3772  }
3773  return res;
3774 }
3775 
3777 {
3779 
3781  if (!legacy_spkm) {
3782  error = _("Error: This wallet is already a descriptor wallet");
3783  return false;
3784  }
3785 
3786  for (auto& desc_spkm : data.desc_spkms) {
3787  if (m_spk_managers.count(desc_spkm->GetID()) > 0) {
3788  error = _("Error: Duplicate descriptors created during migration. Your wallet may be corrupted.");
3789  return false;
3790  }
3791  m_spk_managers[desc_spkm->GetID()] = std::move(desc_spkm);
3792  }
3793 
3794  // Remove the LegacyScriptPubKeyMan from disk
3795  if (!legacy_spkm->DeleteRecords()) {
3796  return false;
3797  }
3798 
3799  // Remove the LegacyScriptPubKeyMan from memory
3800  m_spk_managers.erase(legacy_spkm->GetID());
3801  m_external_spk_managers.clear();
3802  m_internal_spk_managers.clear();
3803 
3804  // Setup new descriptors
3805  SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
3807  // Use the existing master key if we have it
3808  if (data.master_key.key.IsValid()) {
3810  } else {
3811  // Setup with a new seed if we don't.
3813  }
3814  }
3815 
3816  // Check if the transactions in the wallet are still ours. Either they belong here, or they belong in the watchonly wallet.
3817  // We need to go through these in the tx insertion order so that lookups to spends works.
3818  std::vector<uint256> txids_to_delete;
3819  for (const auto& [_pos, wtx] : wtxOrdered) {
3820  if (!IsMine(*wtx->tx) && !IsFromMe(*wtx->tx)) {
3821  // Check it is the watchonly wallet's
3822  // solvable_wallet doesn't need to be checked because transactions for those scripts weren't being watched for
3823  if (data.watchonly_wallet) {
3824  LOCK(data.watchonly_wallet->cs_wallet);
3825  if (data.watchonly_wallet->IsMine(*wtx->tx) || data.watchonly_wallet->IsFromMe(*wtx->tx)) {
3826  // Add to watchonly wallet
3827  if (!data.watchonly_wallet->AddToWallet(wtx->tx, wtx->m_state)) {
3828  error = _("Error: Could not add watchonly tx to watchonly wallet");
3829  return false;
3830  }
3831  // Mark as to remove from this wallet
3832  txids_to_delete.push_back(wtx->GetHash());
3833  continue;
3834  }
3835  }
3836  // Both not ours and not in the watchonly wallet
3837  error = strprintf(_("Error: Transaction %s in wallet cannot be identified to belong to migrated wallets"), wtx->GetHash().GetHex());
3838  return false;
3839  }
3840  }
3841  // Do the removes
3842  if (txids_to_delete.size() > 0) {
3843  std::vector<uint256> deleted_txids;
3844  if (ZapSelectTx(txids_to_delete, deleted_txids) != DBErrors::LOAD_OK) {
3845  error = _("Error: Could not delete watchonly transactions");
3846  return false;
3847  }
3848  if (deleted_txids != txids_to_delete) {
3849  error = _("Error: Not all watchonly txs could be deleted");
3850  return false;
3851  }
3852  // Tell the GUI of each tx
3853  for (const uint256& txid : deleted_txids) {
3855  }
3856  }
3857 
3858  // Check the address book data in the same way we did for transactions
3859  std::vector<CTxDestination> dests_to_delete;
3860  for (const auto& addr_pair : m_address_book) {
3861  // Labels applied to receiving addresses should go based on IsMine
3862  if (addr_pair.second.purpose == "receive") {
3863  if (!IsMine(addr_pair.first)) {
3864  // Check the address book data is the watchonly wallet's
3865  if (data.watchonly_wallet) {
3866  LOCK(data.watchonly_wallet->cs_wallet);
3867  if (data.watchonly_wallet->IsMine(addr_pair.first)) {
3868  // Add to the watchonly. Preserve the labels, purpose, and change-ness
3869  std::string label = addr_pair.second.GetLabel();
3870  std::string purpose = addr_pair.second.purpose;
3871  if (!purpose.empty()) {
3872  data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose;
3873  }
3874  if (!addr_pair.second.IsChange()) {
3875  data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label);
3876  }
3877  dests_to_delete.push_back(addr_pair.first);
3878  continue;
3879  }
3880  }
3881  if (data.solvable_wallet) {
3882  LOCK(data.solvable_wallet->cs_wallet);
3883  if (data.solvable_wallet->IsMine(addr_pair.first)) {
3884  // Add to the solvable. Preserve the labels, purpose, and change-ness
3885  std::string label = addr_pair.second.GetLabel();
3886  std::string purpose = addr_pair.second.purpose;
3887  if (!purpose.empty()) {
3888  data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose;
3889  }
3890  if (!addr_pair.second.IsChange()) {
3891  data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label);
3892  }
3893  dests_to_delete.push_back(addr_pair.first);
3894  continue;
3895  }
3896  }
3897  // Not ours, not in watchonly wallet, and not in solvable
3898  error = _("Error: Address book data in wallet cannot be identified to belong to migrated wallets");
3899  return false;
3900  }
3901  } else {
3902  // Labels for everything else (send) should be cloned to all
3903  if (data.watchonly_wallet) {
3904  LOCK(data.watchonly_wallet->cs_wallet);
3905  // Add to the watchonly. Preserve the labels, purpose, and change-ness
3906  std::string label = addr_pair.second.GetLabel();
3907  std::string purpose = addr_pair.second.purpose;
3908  if (!purpose.empty()) {
3909  data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose;
3910  }
3911  if (!addr_pair.second.IsChange()) {
3912  data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label);
3913  }
3914  continue;
3915  }
3916  if (data.solvable_wallet) {
3917  LOCK(data.solvable_wallet->cs_wallet);
3918  // Add to the solvable. Preserve the labels, purpose, and change-ness
3919  std::string label = addr_pair.second.GetLabel();
3920  std::string purpose = addr_pair.second.purpose;
3921  if (!purpose.empty()) {
3922  data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose;
3923  }
3924  if (!addr_pair.second.IsChange()) {
3925  data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label);
3926  }
3927  continue;
3928  }
3929  }
3930  }
3931 
3932  // Persist added address book entries (labels, purpose) for watchonly and solvable wallets
3933  auto persist_address_book = [](const CWallet& wallet) {
3934  LOCK(wallet.cs_wallet);
3935  WalletBatch batch{wallet.GetDatabase()};
3936  for (const auto& [destination, addr_book_data] : wallet.m_address_book) {
3937  auto address{EncodeDestination(destination)};
3938  auto purpose{addr_book_data.purpose};
3939  auto label{addr_book_data.GetLabel()};
3940  // don't bother writing default values (unknown purpose, empty label)
3941  if (purpose != "unknown") batch.WritePurpose(address, purpose);
3942  if (!label.empty()) batch.WriteName(address, label);
3943  }
3944  };
3945  if (data.watchonly_wallet) persist_address_book(*data.watchonly_wallet);
3946  if (data.solvable_wallet) persist_address_book(*data.solvable_wallet);
3947 
3948  // Remove the things to delete
3949  if (dests_to_delete.size() > 0) {
3950  for (const auto& dest : dests_to_delete) {
3951  if (!DelAddressBook(dest)) {
3952  error = _("Error: Unable to remove watchonly address book data");
3953  return false;
3954  }
3955  }
3956  }
3957 
3958  // Connect the SPKM signals
3961 
3962  WalletLogPrintf("Wallet migration complete.\n");
3963 
3964  return true;
3965 }
3966 
3968 {
3969  AssertLockHeld(wallet.cs_wallet);
3970 
3971  // Get all of the descriptors from the legacy wallet
3972  std::optional<MigrationData> data = wallet.GetDescriptorsForLegacy(error);
3973  if (data == std::nullopt) return false;
3974 
3975  // Create the watchonly and solvable wallets if necessary
3976  if (data->watch_descs.size() > 0 || data->solvable_descs.size() > 0) {
3977  DatabaseOptions options;
3978  options.require_existing = false;
3979  options.require_create = true;
3980 
3981  // Make the wallets
3983  if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) {
3985  }
3986  if (wallet.IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) {
3988  }
3989  if (data->watch_descs.size() > 0) {
3990  wallet.WalletLogPrintf("Making a new watchonly wallet containing the watched scripts\n");
3991 
3992  DatabaseStatus status;
3993  std::vector<bilingual_str> warnings;
3994  std::string wallet_name = wallet.GetName() + "_watchonly";
3995  data->watchonly_wallet = CreateWallet(context, wallet_name, std::nullopt, options, status, error, warnings);
3996  if (status != DatabaseStatus::SUCCESS) {
3997  error = _("Error: Failed to create new watchonly wallet");
3998  return false;
3999  }
4000  res.watchonly_wallet = data->watchonly_wallet;
4001  LOCK(data->watchonly_wallet->cs_wallet);
4002 
4003  // Parse the descriptors and add them to the new wallet
4004  for (const auto& [desc_str, creation_time] : data->watch_descs) {
4005  // Parse the descriptor
4006  FlatSigningProvider keys;
4007  std::string parse_err;
4008  std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, parse_err, /* require_checksum */ true);
4009  assert(desc); // It shouldn't be possible to have the LegacyScriptPubKeyMan make an invalid descriptor
4010  assert(!desc->IsRange()); // It shouldn't be possible to have LegacyScriptPubKeyMan make a ranged watchonly descriptor
4011 
4012  // Add to the wallet
4013  WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
4014  data->watchonly_wallet->AddWalletDescriptor(w_desc, keys, "", false);
4015  }
4016 
4017  // Add the wallet to settings
4018  UpdateWalletSetting(*context.chain, wallet_name, /*load_on_startup=*/true, warnings);
4019  }
4020  if (data->solvable_descs.size() > 0) {
4021  wallet.WalletLogPrintf("Making a new watchonly wallet containing the unwatched solvable scripts\n");
4022 
4023  DatabaseStatus status;
4024  std::vector<bilingual_str> warnings;
4025  std::string wallet_name = wallet.GetName() + "_solvables";
4026  data->solvable_wallet = CreateWallet(context, wallet_name, std::nullopt, options, status, error, warnings);
4027  if (status != DatabaseStatus::SUCCESS) {
4028  error = _("Error: Failed to create new watchonly wallet");
4029  return false;
4030  }
4031  res.solvables_wallet = data->solvable_wallet;
4032  LOCK(data->solvable_wallet->cs_wallet);
4033 
4034  // Parse the descriptors and add them to the new wallet
4035  for (const auto& [desc_str, creation_time] : data->solvable_descs) {
4036  // Parse the descriptor
4037  FlatSigningProvider keys;
4038  std::string parse_err;
4039  std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, parse_err, /* require_checksum */ true);
4040  assert(desc); // It shouldn't be possible to have the LegacyScriptPubKeyMan make an invalid descriptor
4041  assert(!desc->IsRange()); // It shouldn't be possible to have LegacyScriptPubKeyMan make a ranged watchonly descriptor
4042 
4043  // Add to the wallet
4044  WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0);
4045  data->solvable_wallet->AddWalletDescriptor(w_desc, keys, "", false);
4046  }
4047 
4048  // Add the wallet to settings
4049  UpdateWalletSetting(*context.chain, wallet_name, /*load_on_startup=*/true, warnings);
4050  }
4051  }
4052 
4053  // Add the descriptors to wallet, remove LegacyScriptPubKeyMan, and cleanup txs and address book data
4054  if (!wallet.ApplyMigrationData(*data, error)) {
4055  return false;
4056  }
4057  return true;
4058 }
4059 
4061 {
4062  MigrationResult res;
4064  std::vector<bilingual_str> warnings;
4065 
4066  // If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
4067  if (auto wallet = GetWallet(context, wallet_name)) {
4068  if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) {
4069  return util::Error{_("Unable to unload the wallet before migrating")};
4070  }
4071  UnloadWallet(std::move(wallet));
4072  }
4073 
4074  // Load the wallet but only in the context of this function.
4075  // No signals should be connected nor should anything else be aware of this wallet
4076  WalletContext empty_context;
4077  empty_context.args = context.args;
4078  DatabaseOptions options;
4079  options.require_existing = true;
4080  DatabaseStatus status;
4081  std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(wallet_name, options, status, error);
4082  if (!database) {
4083  return util::Error{Untranslated("Wallet file verification failed.") + Untranslated(" ") + error};
4084  }
4085 
4086  // Make the local wallet
4087  std::shared_ptr<CWallet> local_wallet = CWallet::Create(empty_context, wallet_name, std::move(database), options.create_flags, error, warnings);
4088  if (!local_wallet) {
4089  return util::Error{Untranslated("Wallet loading failed.") + Untranslated(" ") + error};
4090  }
4091 
4092  // Before anything else, check if there is something to migrate.
4093  if (!local_wallet->GetLegacyScriptPubKeyMan()) {
4094  return util::Error{_("Error: This wallet is already a descriptor wallet")};
4095  }
4096 
4097  // Make a backup of the DB
4098  fs::path this_wallet_dir = fs::absolute(fs::PathFromString(local_wallet->GetDatabase().Filename())).parent_path();
4099  fs::path backup_filename = fs::PathFromString(strprintf("%s-%d.legacy.bak", wallet_name, GetTime()));
4100  fs::path backup_path = this_wallet_dir / backup_filename;
4101  if (!local_wallet->BackupWallet(fs::PathToString(backup_path))) {
4102  return util::Error{_("Error: Unable to make a backup of your wallet")};
4103  }
4104  res.backup_path = backup_path;
4105 
4106  bool success = false;
4107  {
4108  LOCK(local_wallet->cs_wallet);
4109 
4110  // Unlock the wallet if needed
4111  if (local_wallet->IsLocked() && !local_wallet->Unlock(passphrase)) {
4112  if (passphrase.find('\0') == std::string::npos) {
4113  return util::Error{Untranslated("Error: Wallet decryption failed, the wallet passphrase was not provided or was incorrect.")};
4114  } else {
4115  return util::Error{Untranslated("Error: Wallet decryption failed, the wallet passphrase entered was incorrect. "
4116  "The passphrase contains a null character (ie - a zero byte). "
4117  "If this passphrase was set with a version of this software prior to 25.0, "
4118  "please try again with only the characters up to — but not including — "
4119  "the first null character.")};
4120  }
4121  }
4122 
4123  // First change to using SQLite
4124  if (!local_wallet->MigrateToSQLite(error)) return util::Error{error};
4125 
4126  // Do the migration, and cleanup if it fails
4127  success = DoMigration(*local_wallet, context, error, res);
4128  }
4129 
4130  if (success) {
4131  // Migration successful, unload the wallet locally, then reload it.
4132  assert(local_wallet.use_count() == 1);
4133  local_wallet.reset();
4134  LoadWallet(context, wallet_name, /*load_on_start=*/std::nullopt, options, status, error, warnings);
4135  res.wallet_name = wallet_name;
4136  } else {
4137  // Migration failed, cleanup
4138  // Copy the backup to the actual wallet dir
4139  fs::path temp_backup_location = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename);
4140  fs::copy_file(backup_path, temp_backup_location, fs::copy_options::none);
4141 
4142  // Remember this wallet's walletdir to remove after unloading
4143  std::vector<fs::path> wallet_dirs;
4144  wallet_dirs.push_back(fs::PathFromString(local_wallet->GetDatabase().Filename()).parent_path());
4145 
4146  // Unload the wallet locally
4147  assert(local_wallet.use_count() == 1);
4148  local_wallet.reset();
4149 
4150  // Make list of wallets to cleanup
4151  std::vector<std::shared_ptr<CWallet>> created_wallets;
4152  if (res.watchonly_wallet) created_wallets.push_back(std::move(res.watchonly_wallet));
4153  if (res.solvables_wallet) created_wallets.push_back(std::move(res.solvables_wallet));
4154 
4155  // Get the directories to remove after unloading
4156  for (std::shared_ptr<CWallet>& w : created_wallets) {
4157  wallet_dirs.push_back(fs::PathFromString(w->GetDatabase().Filename()).parent_path());
4158  }
4159 
4160  // Unload the wallets
4161  for (std::shared_ptr<CWallet>& w : created_wallets) {
4162  if (!RemoveWallet(context, w, /*load_on_start=*/false)) {
4163  error += _("\nUnable to cleanup failed migration");
4164  return util::Error{error};
4165  }
4166  UnloadWallet(std::move(w));
4167  }
4168 
4169  // Delete the wallet directories
4170  for (fs::path& dir : wallet_dirs) {
4171  fs::remove_all(dir);
4172  }
4173 
4174  // Restore the backup
4175  DatabaseStatus status;
4176  std::vector<bilingual_str> warnings;
4177  if (!RestoreWallet(context, temp_backup_location, wallet_name, /*load_on_start=*/std::nullopt, status, error, warnings)) {
4178  error += _("\nUnable to restore backup of wallet.");
4179  return util::Error{error};
4180  }
4181 
4182  // Move the backup to the wallet dir
4183  fs::copy_file(temp_backup_location, backup_path, fs::copy_options::none);
4184  fs::remove(temp_backup_location);
4185 
4186  return util::Error{error};
4187  }
4188  return res;
4189 }
4190 } // namespace wallet
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Definition: walletdb.cpp:1156
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:414
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
Definition: wallet.h:538
void ReturnDestination()
Return reserved address.
Definition: wallet.cpp:2505
void SyncTransaction(const CTransactionRef &tx, const SyncTxState &state, bool update_tx=true, bool rescanning_old_block=false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1288
virtual bool haveBlockOnDisk(int height)=0
Check that the block is available on disk (i.e.
bool UpgradeWallet(int version, bilingual_str &error)
Upgrade the wallet.
Definition: wallet.cpp:3181
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:50
enum wallet::CWallet::ScanResult::@17 status
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
Definition: crypter.h:34
std::optional< DatabaseFormat > require_format
Definition: db.h:208
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:173
bool isObject() const
Definition: univalue.h:81
void AddToSpends(const COutPoint &outpoint, const uint256 &wtxid, WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:670
void push_back(UniValue val)
Definition: univalue.cpp:104
int ret
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:500
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
check whether we support the named feature
Definition: wallet.h:447
std::atomic< bool > fAbortRescan
Definition: wallet.h:242
State of transaction added to mempool.
Definition: transaction.h:33
std::vector< CTxDestination > ListAddrBookAddresses(const std::optional< AddrBookFilter > &filter) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Filter and retrieve destinations stored in the addressbook.
Definition: wallet.cpp:2446
void ReadDatabaseArgs(const ArgsManager &args, DatabaseOptions &options)
Definition: db.cpp:142
ArgsManager gArgs
Definition: system.cpp:86
interfaces::Chain & chain() const
Interface for accessing chain state.
Definition: wallet.h:419
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
Definition: fs.cpp:35
Enables interaction with an external signing device or service, such as a hardware wallet...
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: transaction.h:165
AssertLockHeld(pool.cs)
void MarkDirty()
make sure balances are recalculated
Definition: transaction.h:274
const std::vector< UniValue > & getValues() const
bool CanGetAddresses(bool internal=false) const
Definition: wallet.cpp:1480
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:237
int64_t nIndex
The index of the address&#39;s key in the keypool.
Definition: wallet.h:173
std::map< OutputType, ScriptPubKeyMan * > m_external_spk_managers
Definition: wallet.h:337
constexpr CAmount HIGH_TX_FEE_PER_KB
Discourage users to set fees higher than this amount (in satoshis) per kB.
Definition: wallet.h:112
virtual std::optional< int > getHeight()=0
Get current chain height, not including genesis block (returns 0 if chain only contains genesis block...
bool SetAddressBookWithDB(WalletBatch &batch, const CTxDestination &address, const std::string &strName, const std::string &strPurpose)
Definition: wallet.cpp:2288
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1642
bilingual_str AmountErrMsg(const std::string &optname, const std::string &strValue)
Definition: error.cpp:57
virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock &block={})=0
Find first block in the chain with timestamp >= the given time and height >= than the given height...
void SetNull()
Definition: uint256.h:42
bool HasEncryptionKeys() const override
Definition: wallet.cpp:3440
const T * state() const
Definition: transaction.h:291
assert(!tx.IsCoinBase())
Describes a place in the block chain to another node such that if the other node doesn&#39;t have the sam...
Definition: block.h:120
CScript scriptPubKey
Definition: transaction.h:160
const CAddressBookData * FindAddressBookEntry(const CTxDestination &, bool allow_change=false) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:3171
virtual bool Backup(const std::string &strDest) const =0
Back up the entire database to a file.
bool SubmitTxMemoryPoolAndRelay(CWalletTx &wtx, std::string &err_string, bool relay) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Pass this transaction to node for mempool insertion and relay to peers if flag set to true...
Definition: wallet.cpp:1867
int GetTxBlocksToMaturity(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:3256
std::optional< int > last_scanned_height
Definition: wallet.h:532
CKey key
Definition: key.h:166
bool DoMigration(CWallet &wallet, WalletContext &context, bilingual_str &error, MigrationResult &res) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
Definition: wallet.cpp:3967
void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade DescriptorCaches.
Definition: wallet.cpp:453
bool LoadToWallet(const uint256 &hash, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1056
const ArgsManager & m_args
Provider of aplication-wide arguments.
Definition: wallet.h:310
A UTXO entry.
Definition: coins.h:30
isminetype IsMine(const CTxDestination &dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1414
Bilingual messages:
Definition: translation.h:18
std::set< uint256 > GetConflicts(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get wallet transactions that conflict with given transaction (spend same outputs) ...
Definition: wallet.cpp:565
Definition: block.h:68
virtual uint256 getBlockHash(int height)=0
Get block hash. Height must be valid or this function will abort.
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:107
boost::signals2::signal< void(const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)> NotifyAddressBookChanged
Address book entry changed.
Definition: wallet.h:742
int64_t IncOrderPosNext(WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Increment the next transaction order id.
Definition: wallet.cpp:855
bool ApplyMigrationData(MigrationData &data, bilingual_str &error) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Adds the ScriptPubKeyMans given in MigrationData to this wallet, removes LegacyScriptPubKeyMan, and where needed, moves tx and address book entries to watchonly_wallet or solvable_wallet.
Definition: wallet.cpp:3776
virtual CBlockLocator getActiveChainLocator(const uint256 &block_hash)=0
Return a locator that refers to a block in the active chain.
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
Definition: wallet.h:531
RecursiveMutex cs_KeyStore
std::map< std::string, std::string > mapValue_t
Definition: transaction.h:111
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
Definition: key.cpp:241
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:187
bool DummySignTx(CMutableTransaction &txNew, const std::set< CTxOut > &txouts, const CCoinControl *coin_control=nullptr) const
Definition: wallet.h:594
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< unsigned char > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
Definition: crypter.cpp:40
bool SetAddressReceiveRequest(WalletBatch &batch, const CTxDestination &dest, const std::string &id, const std::string &value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2762
static int g_sqlite_count GUARDED_BY(g_sqlite_mutex)=0
std::vector< CTxIn > vin
Definition: transaction.h:374
bool MigrateToSQLite(bilingual_str &error) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Move all records from the BDB database to a new SQLite database for storage.
Definition: wallet.cpp:3686
std::map< CKeyID, CKey > keys
CScriptWitness scriptWitness
Only serialized through CTransaction.
Definition: transaction.h:79
SigningResult
Definition: message.h:43
CWalletTx * AddToWallet(CTransactionRef tx, const TxState &state, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true, bool rescanning_old_block=false)
Add the transaction to the wallet, wrapping it up inside a CWalletTx.
Definition: wallet.cpp:958
bool 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) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1672
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:48
std::optional< MigrationData > MigrateToDescriptor()
Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this Legac...
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
Definition: walletdb.cpp:1086
virtual void Flush()=0
Make sure all changes are flushed to database file.
std::vector< std::pair< std::string, std::string > > vOrderForm
Definition: transaction.h:166
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
Definition: wallet.h:368
const char * prefix
Definition: rest.cpp:938
std::shared_ptr< CWallet > LoadWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:267
Definition: key.h:161
struct containing information needed for migrating legacy wallets to descriptor wallets ...
Definition: walletutil.h:112
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:27
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:47
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1313
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< unsigned char > &vchCiphertext) const
Definition: crypter.cpp:72
void blockConnected(const interfaces::BlockInfo &block) override
Definition: wallet.cpp:1346
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:356
bool IsLegacy() const
Determine if we are a legacy wallet.
Definition: wallet.cpp:3582
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 ...
Definition: serialize.h:233
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
Definition: sign.cpp:634
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:59
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
Definition: walletdb.cpp:147
bool m_is_cache_empty
This flag is true if all m_amounts caches are empty.
Definition: transaction.h:197
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2257
MasterKeyMap mapMasterKeys
Definition: wallet.h:371
WalletDatabase & GetDatabase() const override
Definition: wallet.h:360
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule) ...
Definition: consensus.h:19
static unsigned const char sighash[]
Definition: sighash.json.h:2
void transactionAddedToMempool(const CTransactionRef &tx, uint64_t mempool_sequence) override
Definition: wallet.cpp:1299
bool TxnAbort()
Abort current transaction.
Definition: walletdb.cpp:1151
bool fInternal
Whether this is from the internal (change output) keypool.
Definition: wallet.h:177
std::vector< std::vector< unsigned char > > stack
Definition: script.h:566
std::optional< int64_t > GetOldestKeyPoolTime() const
Definition: wallet.cpp:2409
const CWallet *const pwallet
The wallet to reserve from.
Definition: wallet.h:168
const std::map< uint64_t, std::string > WALLET_FLAG_CAVEATS
Definition: wallet.cpp:52
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const
Definition: wallet.cpp:2117
void DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Remove specified ScriptPubKeyMan from set of active SPK managers.
Definition: wallet.cpp:3565
bool DelAddressBook(const CTxDestination &address)
Definition: wallet.cpp:2314
CTxDestination address
The destination.
Definition: wallet.h:175
RecursiveMutex cs_wallet
Main wallet lock.
Definition: wallet.h:358
#define PACKAGE_NAME
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
Definition: sign.cpp:635
bool SignTransaction(CMutableTransaction &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Fetch the inputs and sign with SIGHASH_ALL.
Definition: wallet.cpp:2002
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
Definition: coincontrol.h:42
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
State of transaction not confirmed or conflicting with a known block and not in the mempool...
Definition: transaction.h:48
bool RemoveWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Remove wallet name from persistent configuration so it will not be loaded on startup.
Definition: wallet.cpp:71
virtual void Close()=0
Flush to the database file and close the database.
const UniValue & get_array() const
std::variant< TxStateConfirmed, TxStateInMempool, TxStateInactive > SyncTxState
Subset of states transaction sync logic is implemented to handle.
Definition: transaction.h:69
RAII object to check and reserve a wallet rescan.
Definition: wallet.h:951
std::unique_ptr< Wallet > MakeWallet(wallet::WalletContext &context, const std::shared_ptr< wallet::CWallet > &wallet)
Return implementation of Wallet interface.
Definition: interfaces.cpp:630
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
Definition: txmempool.h:349
std::multimap< int64_t, CWalletTx * > TxItems
Definition: wallet.h:400
bool WriteLockedUTXO(const COutPoint &output)
Definition: walletdb.cpp:290
bool DeleteRecords()
Delete all the records ofthis LegacyScriptPubKeyMan from disk.
FlatSigningProvider m_external_provider
SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs...
Definition: coincontrol.h:62
static GlobalMutex g_loading_wallet_mutex
Definition: wallet.cpp:185
A version of CTransaction with the PSBT format.
Definition: psbt.h:946
bool IsNull() const
Definition: block.h:141
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
Definition: handler.cpp:35
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:185
bool WriteMinVersion(int nVersion)
Definition: walletdb.cpp:205
std::vector< std::string > GetAddressReceiveRequests() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2748
const CWalletTx * GetWalletTx(const uint256 &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:429
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:654
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
std::shared_ptr< CWallet > solvable_wallet
Definition: walletutil.h:119
Access to the wallet database.
Definition: walletdb.h:187
ScriptPubKeyMan * GetScriptPubKeyMan(const OutputType &type, bool internal) const
Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
Definition: wallet.cpp:3345
std::atomic< uint64_t > m_wallet_flags
WalletFlags set on this wallet.
Definition: wallet.h:299
A key from a CWallet&#39;s keypool.
boost::signals2::signal< void(const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
Definition: wallet.h:748
State of transaction confirmed in a block.
Definition: transaction.h:24
bool IsEquivalentTo(const CWalletTx &tx) const
True if only scriptSigs are different.
Definition: transaction.cpp:8
bool fBroadcastTransactions
Whether this wallet will submit newly created transactions to the node&#39;s mempool and prompt rebroadca...
Definition: wallet.h:256
bool AddToWalletIfInvolvingMe(const CTransactionRef &tx, const SyncTxState &state, bool fUpdate, bool rescanning_old_block) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Add a transaction to the wallet, or update it.
Definition: wallet.cpp:1100
bool WriteOrderPosNext(int64_t nOrderPosNext)
Definition: walletdb.cpp:185
bool IsNull() const
Definition: script.h:571
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:11
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
Definition: interpreter.h:33
virtual bool Rewrite(const char *pszSkip=nullptr)=0
Rewrite the entire database on disk, with the exception of key pszSkip if non-zero.
unsigned char * begin()
Definition: uint256.h:61
LegacyScriptPubKeyMan * GetLegacyScriptPubKeyMan() const
Get the LegacyScriptPubKeyMan which is used for all types, internal, and external.
Definition: wallet.cpp:3403
bool isReserved() const
Definition: wallet.h:974
static void UpdateWalletSetting(interfaces::Chain &chain, const std::string &wallet_name, std::optional< bool > load_on_startup, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:83
void GetKeyBirthTimes(std::map< CKeyID, int64_t > &mapKeyBirth) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2578
bool IsAddressUsed(const CTxDestination &dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2733
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
Definition: chain.h:31
std::set< ScriptPubKeyMan * > GetAllScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans.
Definition: wallet.cpp:3336
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
Definition: settings.h:106
virtual double guessVerificationProgress(const uint256 &block_hash)=0
Estimate fraction of total transactions verified if blocks up to the specified block hash are verifie...
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:696
OutputType
Definition: outputtype.h:17
static int64_t GetDefaultNextResend()
Definition: wallet.cpp:1924
ArgsManager args
bool isAbandoned() const
Definition: transaction.h:294
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses, and other watch only things, and is therefore "blank.".
Definition: walletutil.h:63
constexpr CAmount HIGH_MAX_TX_FEE
-maxtxfee will warn if called with a higher fee than this amount (in satoshis)
Definition: wallet.h:114
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
static constexpr auto OUTPUT_TYPES
Definition: outputtype.h:25
void updatedBlockTip() override
Definition: wallet.cpp:1375
const std::vector< CTxIn > vin
Definition: transaction.h:298
std::optional< bool > IsInternalScriptPubKeyMan(ScriptPubKeyMan *spk_man) const
Returns whether the provided ScriptPubKeyMan is internal.
Definition: wallet.cpp:3604
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:233
void SyncMetaData(std::pair< TxSpends::iterator, TxSpends::iterator >) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:610
bool LockCoin(const COutPoint &output, WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2528
bool WriteBestBlock(const CBlockLocator &locator)
Definition: walletdb.cpp:173
static const bool DEFAULT_WALLET_RBF
-walletrbf default
Definition: wallet.h:105
void MaybeResendWalletTxs(WalletContext &context)
Called periodically by the schedule thread.
Definition: wallet.cpp:1987
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE
Default for -spendzeroconfchange.
Definition: wallet.h:99
std::map< uint256, std::unique_ptr< ScriptPubKeyMan > > m_spk_managers
Definition: wallet.h:342
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
Definition: wallet.h:754
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
virtual std::optional< int > findLocatorFork(const CBlockLocator &locator)=0
Return height of the highest block on chain in common with the locator, which will either be the orig...
bool DisplayAddress(const CTxDestination &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Display address on an external signer.
Definition: wallet.cpp:2514
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition: random.h:79
bool HasWalletSpend(const CTransactionRef &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Check if a given transaction has any of its outputs spent by another transaction in the wallet...
Definition: wallet.cpp:588
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
Definition: wallet.cpp:3453
bool Decrypt(const std::vector< unsigned char > &vchCiphertext, CKeyingMaterial &vchPlaintext) const
Definition: crypter.cpp:90
const uint256 & hash
Definition: chain.h:82
A transaction with a bunch of additional info that only the owner cares about.
Definition: transaction.h:137
interfaces::Chain * m_chain
Interface for accessing chain state.
Definition: wallet.h:313
bool FillInputToWeight(CTxIn &txin, int64_t target_weight)
Definition: wallet.cpp:1571
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
int64_t GetInputWeight(const COutPoint &outpoint) const
Definition: coincontrol.h:127
bool EraseName(const std::string &strAddress)
Definition: walletdb.cpp:74
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:109
DescriptorScriptPubKeyMan * GetDescriptorScriptPubKeyMan(const WalletDescriptor &desc) const
Return the DescriptorScriptPubKeyMan for a WalletDescriptor if it is already in the wallet...
Definition: wallet.cpp:3591
Block data sent with blockConnected, blockDisconnected notifications.
Definition: chain.h:81
bool IsLocked() const override
Definition: wallet.cpp:3281
Indicates that the wallet needs an external signer.
Definition: walletutil.h:69
void SetupLegacyScriptPubKeyMan()
Make a LegacyScriptPubKeyMan and set it for all types, internal, and external.
Definition: wallet.cpp:3421
DBErrors LoadWallet(CWallet *pwallet)
Definition: walletdb.cpp:769
bool MarkReplaced(const uint256 &originalHash, const uint256 &newHash)
Mark a transaction as replaced by another transaction.
Definition: wallet.cpp:876
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
virtual bool hasAssumedValidChain()=0
Return true if an assumed-valid chain is in use.
const CBlock * data
Definition: chain.h:87
std::underlying_type< isminetype >::type isminefilter
used for bitflags of isminetype
Definition: wallet.h:41
void AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Adds the active ScriptPubKeyMan for the specified type and internal.
Definition: wallet.cpp:3536
bool ShouldResend() const
Return true if all conditions for periodically resending transactions are met.
Definition: wallet.cpp:1907
std::set< CKeyID > GetKeys() const override
std::set< ScriptPubKeyMan * > GetActiveScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans in m_internal_spk_managers and m_external_spk_managers.
Definition: wallet.cpp:3322
virtual bool isInMempool(const uint256 &txid)=0
Check if transaction is in mempool.
bool TxnCommit()
Commit current transaction.
Definition: walletdb.cpp:1146
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:150
SecureString create_passphrase
Definition: db.h:210
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
Definition: walletdb.cpp:210
std::string wallet_name
Definition: wallet.h:1002
CPubKey vchPubKey
The public key.
std::multimap< int64_t, CWalletTx * >::const_iterator m_it_wtxOrdered
Definition: transaction.h:186
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
virtual bool findAncestorByHeight(const uint256 &block_hash, int ancestor_height, const FoundBlock &ancestor_out={})=0
Find ancestor of block at specified height and optionally return ancestor information.
const uint256 * prev_hash
Definition: chain.h:83
uint64_t create_flags
Definition: db.h:209
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
bool GetBroadcastTransactions() const
Inquire whether this wallet broadcasts transactions.
Definition: wallet.h:766
An input of a transaction.
Definition: transaction.h:73
static int64_t GetTransactionInputWeight(const CTxIn &txin)
Definition: validation.h:156
static constexpr uint64_t KNOWN_WALLET_FLAGS
Definition: wallet.h:125
int GetLastBlockHeight() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get last block processed height.
Definition: wallet.h:870
void SetMinVersion(enum WalletFeature, WalletBatch *batch_in=nullptr) override
signify that a particular wallet feature is now used.
Definition: wallet.cpp:548
#define LOCK(cs)
Definition: sync.h:261
const char * name
Definition: rest.cpp:46
static const unsigned int DEFAULT_TX_CONFIRM_TARGET
-txconfirmtarget default
Definition: wallet.h:103
void MarkInputsDirty(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Mark a transaction&#39;s inputs dirty, thus forcing the outputs to be recomputed.
Definition: wallet.cpp:1173
std::vector< std::byte, zero_after_free_allocator< std::byte > > SerializeData
Byte-vector that clears its contents before deletion.
Definition: zeroafterfree.h:44
void Flush()
Flush wallet (bitdb flush)
Definition: wallet.cpp:600
bool WriteTx(const CWalletTx &wtx)
Definition: walletdb.cpp:91
std::map< OutputType, ScriptPubKeyMan * > m_internal_spk_managers
Definition: wallet.h:338
const uint256 & GetHash() const
Definition: transaction.h:330
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:65
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:491
void chainStateFlushed(const CBlockLocator &loc) override
Definition: wallet.cpp:537
Removed for conflict with in-block transaction.
util::Result< CTxDestination > GetReservedDestination(bool internal)
Reserve an address.
Definition: wallet.cpp:2476
virtual void ReloadDbEnv()=0
TxoutType
Definition: standard.h:51
std::optional< OutputType > ParseOutputType(const std::string &type)
Definition: outputtype.cpp:25
void blockDisconnected(const interfaces::BlockInfo &block) override
Definition: wallet.cpp:1359
bilingual_str AmountHighWarn(const std::string &optname)
Definition: error.cpp:52
Removed for block.
std::shared_ptr< Descriptor > descriptor
Definition: walletutil.h:79
An encapsulated public key.
Definition: pubkey.h:33
CAmount m_default_max_tx_fee
Absolute maximum transaction fee (in satoshis) used by default for the wallet.
Definition: wallet.h:643
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
Definition: ismine.h:41
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
Definition: feerate.cpp:39
bool IsFromMe(const CTransaction &tx) const
should probably be renamed to IsRelevantToMe
Definition: wallet.cpp:1452
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.
Definition: system.cpp:1159
void NotifyWalletLoaded(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
Definition: wallet.cpp:177
int64_t m_next_resend
The next scheduled rebroadcast of wallet transactions.
Definition: wallet.h:253
uint32_t n
Definition: transaction.h:38
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver &reserver, bool update)
Scan active chain for relevant transactions after importing keys.
Definition: wallet.cpp:1703
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:160
const std::vector< CTxOut > vout
Definition: transaction.h:299
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:42
WalletFeature
(client) version numbers for particular wallet features
Definition: walletutil.h:15
Indicate that this wallet supports DescriptorScriptPubKeyMan.
Definition: walletutil.h:66
bool AbandonTransaction(const uint256 &hashTx)
Definition: wallet.cpp:1183
unsigned int ComputeTimeSmart(const CWalletTx &wtx, bool rescanning_old_block) const
Compute smart timestamp for a transaction being added to the wallet.
Definition: wallet.cpp:2661
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
bool IsHDEnabled() const
Definition: wallet.cpp:1469
bool BackupWallet(const std::string &strDest) const
Definition: wallet.cpp:3224
WalletContext context
static int TxStateSerializedIndex(const TxState &state)
Get TxState serialized block index. Inverse of TxStateInterpretSerialized.
Definition: transaction.h:99
virtual void waitForNotificationsIfTipChanged(const uint256 &old_tip)=0
Wait for pending notifications to be processed unless block hash points to the current chain tip...
std::set< uint256 > GetTxConflicts(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1897
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:235
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:149
A structure for PSBTs which contain per-input information.
Definition: psbt.h:191
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:2308
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2360
bool IsExternalSelected(const COutPoint &output) const
Definition: coincontrol.h:76
bool WriteWalletFlags(const uint64_t flags)
Definition: walletdb.cpp:1097
#define WAIT_LOCK(cs, name)
Definition: sync.h:266
An output of a transaction.
Definition: transaction.h:156
void ReplaceAll(std::string &in_out, const std::string &search, const std::string &substitute)
Definition: string.cpp:10
unsigned int nDeriveIterations
Definition: crypter.h:42
DBErrors LoadWallet()
Definition: wallet.cpp:2234
std::string ToString() const
Definition: uint256.cpp:64
bool IsTxImmatureCoinBase(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:3268
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:334
bool UnlockCoin(const COutPoint &output, WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2538
void MarkDirty()
Definition: wallet.cpp:867
bool IsWalletFlagSet(uint64_t flag) const override
check if a certain wallet flag is set
Definition: wallet.cpp:1520
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:34
void UnsetBlankWalletFlag(WalletBatch &batch) override
Unset the blank wallet flag and saves it to disk.
Definition: wallet.cpp:1515
bool Unlock(const CKeyingMaterial &vMasterKeyIn, bool accept_no_keys=false)
Definition: wallet.cpp:3307
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
Definition: walletdb.cpp:1081
TxItems wtxOrdered
Definition: wallet.h:401
static const std::unordered_set< OutputType > LEGACY_OUTPUT_TYPES
OutputTypes supported by the LegacyScriptPubKeyMan.
ScanResult ScanForWalletTransactions(const uint256 &start_block, int start_height, std::optional< int > max_height, const WalletRescanReserver &reserver, bool fUpdate, const bool save_progress)
Scan the block chain (starting in start_block) for transactions from or to us.
Definition: wallet.cpp:1747
Definition: node.h:39
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
Definition: wallet.cpp:209
util::Result< MigrationResult > MigrateLegacyToDescriptor(const std::string &wallet_name, const SecureString &passphrase, WalletContext &context)
Do all steps to migrate a legacy wallet to a descriptor wallet.
Definition: wallet.cpp:4060
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
Definition: wallet.h:751
std::vector< PSBTInput > inputs
Definition: psbt.h:952
bool AddWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Add wallet name to persistent configuration so it will be loaded on startup.
Definition: wallet.cpp:60
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:305
void ForEachAddrBookEntry(const ListAddrBookFunc &func) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2437
std::shared_ptr< CWallet > solvables_wallet
Definition: wallet.h:1004
bool ErasePurpose(const std::string &strAddress)
Definition: walletdb.cpp:86
static uint256 TxStateSerializedBlockHash(const TxState &state)
Get TxState serialized block hash. Inverse of TxStateInterpretSerialized.
Definition: transaction.h:87
uint256 GetID() const override
UniValue GetDescriptors(const int account)
Get receive and change Descriptor(s) from device for a given account.
unsigned int nDerivationMethod
0 = EVP_sha512() 1 = scrypt()
Definition: crypter.h:41
ScriptPubKeyMan * m_spk_man
The ScriptPubKeyMan to reserve from. Based on type when GetReservedDestination is called...
Definition: wallet.h:170
Descriptor with some wallet metadata.
Definition: walletutil.h:76
bool SetAddressUsed(WalletBatch &batch, const CTxDestination &dest, bool used) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2712
void Close()
Close wallet database.
Definition: wallet.cpp:605
Address book data.
Definition: wallet.h:203
CWallet(interfaces::Chain *chain, const std::string &name, const ArgsManager &args, std::unique_ptr< WalletDatabase > database)
Construct wallet with specified name and database implementation.
Definition: wallet.h:375
virtual void KeepDestination(int64_t index, const OutputType &type)
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:415
static const bool DEFAULT_WALLETBROADCAST
Definition: wallet.h:106
void postInitProcess()
Wallet post-init setup Gives the wallet a chance to register repetitive tasks and complete post-init ...
Definition: wallet.cpp:3214
static void ReleaseWallet(CWallet *wallet)
Definition: wallet.cpp:192
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:122
CScript scriptSig
Definition: transaction.h:77
if(!SetupNetworking())
int flags
Definition: bitcoin-tx.cpp:525
const std::string & FormatOutputType(OutputType type)
Definition: outputtype.cpp:39
std::shared_ptr< CWallet > GetWallet(WalletContext &context, const std::string &name)
Definition: wallet.cpp:161
const std::string GetDisplayName() const override
Returns a bracketed wallet name for displaying in logs, will return [default wallet] if the wallet ha...
Definition: wallet.h:824
std::atomic< int64_t > m_best_block_time
Definition: wallet.h:258
DatabaseStatus
Definition: db.h:219
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1652
256-bit opaque blob.
Definition: uint256.h:119
std::function< void(const CTxDestination &dest, const std::string &label, const std::string &purpose, bool is_change)> ListAddrBookFunc
Walk-through the address book entries.
Definition: wallet.h:672
unsigned int fTimeReceivedIsTxTime
Definition: transaction.h:167
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
std::vector< CTransactionRef > vtx
Definition: block.h:72
void ResubmitWalletTransactions(bool relay, bool force)
Definition: wallet.cpp:1950
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
Definition: wallet.cpp:148
const_iterator end() const
Definition: streams.h:235
virtual util::SettingsValue getRwSetting(const std::string &name)=0
Return <datadir>/settings.json setting value.
void SetSeed(Span< const std::byte > seed)
Definition: key.cpp:344
const_iterator begin() const
Definition: streams.h:233
bool TransactionCanBeAbandoned(const uint256 &hashTx) const
Return whether transaction can be abandoned.
Definition: wallet.cpp:1166
An interface to be implemented by keystores that support signing.
bool TopUpKeyPool(unsigned int kpSize=0)
Definition: wallet.cpp:2371
bool IsLockedCoin(const COutPoint &output) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2560
State of rejected transaction that conflicts with a confirmed block.
Definition: transaction.h:37
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:117
void KeepDestination()
Keep the address. Do not return it&#39;s key to the keypool when this object goes out of scope...
Definition: wallet.cpp:2496
bool IsSpent(const COutPoint &outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Outpoint is spent if any non-conflicted transaction spends it:
Definition: wallet.cpp:653
std::function< bool(CWalletTx &wtx, bool new_tx)> UpdateWalletTxFn
Callback for updating transaction metadata in mapWallet.
Definition: wallet.h:511
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:410
bool IsNull() const
Definition: block.h:49
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Loads an active ScriptPubKeyMan for the specified type and internal.
Definition: wallet.cpp:3545
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:629
bool fFromMe
From me flag is set to 1 for transactions that were created by the wallet on this bitcoin node...
Definition: transaction.h:184
void InitWalletFlags(uint64_t flags)
overwrite all flags by the given uint64_t flags must be uninitialised (or 0) only known flags may be ...
Definition: wallet.cpp:1537
std::shared_ptr< CWallet > watchonly_wallet
Definition: wallet.h:1003
virtual util::Result< CTxDestination > GetReservedDestination(const OutputType type, bool internal, int64_t &index, CKeyPool &keypool)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:604
bool empty() const
Definition: prevector.h:288
std::set< ScriptPubKeyMan * > GetScriptPubKeyMans(const CScript &script) const
Get all the ScriptPubKeyMans for a script.
Definition: wallet.cpp:3355
virtual bool updateRwSetting(const std::string &name, const util::SettingsValue &value, bool write=true)=0
Write a setting to <datadir>/settings.json.
size_t KeypoolCountExternalKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2343
boost::signals2::signal< void(CWallet *wallet)> NotifyStatusChanged
Wallet status (encrypted, locked) changed.
Definition: wallet.h:763
CTransactionRef non_witness_utxo
Definition: psbt.h:193
bool InMempool() const
Definition: transaction.cpp:17
std::optional< std::string > m_op_label
Definition: wallet.h:653
const uint256 & GetHash() const
Definition: transaction.h:298
bool IsCrypted() const
Definition: wallet.cpp:3276
virtual void initMessage(const std::string &message)=0
Send init message.
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:23
void UpdateInput(CTxIn &input, const SignatureData &data)
Definition: sign.cpp:545
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:168
std::string GetHex() const
Definition: uint256.cpp:20
OutputType const type
Definition: wallet.h:171
void LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Adds a destination data tuple to the store, without saving it to disk.
Definition: wallet.cpp:2728
std::set< std::string > ListAddrBookLabels(const std::string &purpose) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Retrieve all the known labels in the address book.
Definition: wallet.cpp:2462
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet...
Definition: transaction.h:178
std::unique_ptr< interfaces::Handler > HandleLoadWallet(WalletContext &context, LoadWalletFn load_wallet)
Definition: wallet.cpp:170
bool TxnBegin()
Begin a new transaction.
Definition: walletdb.cpp:1141
WalletContext struct containing references to state shared between CWallet instances, like the reference to the chain interface, and the list of opened wallets.
Definition: context.h:35
A wrapper to reserve an address from a wallet.
Definition: wallet.h:164
DBErrors ReorderTransactions()
Definition: wallet.cpp:798
std::vector< unsigned char > vchSalt
Definition: crypter.h:38
TransactionError
Definition: error.h:22
bool HaveChain() const
Interface to assert chain access.
Definition: wallet.h:394
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
Definition: feerate.h:32
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:45
bool LoadWalletFlags(uint64_t flags)
Loads the flags into the wallet.
Definition: wallet.cpp:1525
void SetSpentKeyState(WalletBatch &batch, const uint256 &hash, unsigned int n, bool used, std::set< CTxDestination > &tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:908
#define AssertLockNotHeld(cs)
Definition: sync.h:148
const unsigned int WALLET_CRYPTO_KEY_SIZE
Definition: crypter.h:14
static int count
Definition: tests.c:33
std::optional< MigrationData > GetDescriptorsForLegacy(bilingual_str &error) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get all of the descriptors from a legacy wallet.
Definition: wallet.cpp:3758
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:384
bool require_existing
Definition: db.h:206
static void RefreshMempoolStatus(CWalletTx &tx, interfaces::Chain &chain)
Refresh mempool status so the wallet is in an internally consistent state and immediately knows the t...
Definition: wallet.cpp:101
Encryption/decryption context with key information.
Definition: crypter.h:70
interfaces::Chain * chain
Definition: context.h:36
std::vector< WalletDescriptor > GetWalletDescriptors(const CScript &script) const
Get the wallet descriptors for a script.
Definition: wallet.cpp:3391
bool WriteName(const std::string &strAddress, const std::string &strName)
Definition: walletdb.cpp:69
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:276
A mutable version of CTransaction.
Definition: transaction.h:372
std::shared_ptr< CWallet > watchonly_wallet
Definition: walletutil.h:118
uint256 GetLastBlockHash() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.h:876
bool UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2548
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
Definition: psbt.cpp:276
std::unique_ptr< WalletDatabase > m_database
Internal database handle.
Definition: wallet.h:319
void UnsetWalletFlag(uint64_t flag)
Unsets a single wallet flag.
Definition: wallet.cpp:1501
bool IsCoinBase() const
Definition: transaction.h:300
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
Definition: wallet.cpp:438
static GlobalMutex g_wallet_release_mutex
Definition: wallet.cpp:186
int GetVersion() const
get the current wallet format (the oldest client version guaranteed to understand this wallet) ...
Definition: wallet.h:718
static auto quoted(const std::string &s)
Definition: fs.h:94
void MarkDestinationsDirty(const std::set< CTxDestination > &destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Marks all outputs in each one of the destinations dirty, so their cache is reset and does not return ...
Definition: wallet.cpp:2423
FoundBlock & height(int &height)
Definition: chain.h:54
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr)
unsigned int nTimeReceived
time received by this node
Definition: transaction.h:168
virtual bool broadcastTransaction(const CTransactionRef &tx, const CAmount &max_tx_fee, bool relay, std::string &err_string)=0
Transaction is added to memory pool, if the transaction fee is below the amount specified by max_tx_f...
size_t size() const
Definition: univalue.h:65
std::vector< unsigned char > vchCryptedKey
Definition: crypter.h:37
An encapsulated private key.
Definition: key.h:26
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:287
Different type to mark Mutex at global scope.
Definition: sync.h:141
static const bool DEFAULT_WALLETCROSSCHAIN
Definition: wallet.h:108
std::shared_ptr< CWallet > wallet
constexpr CAmount HIGH_APS_FEE
discourage APS fee higher than this amount
Definition: wallet.h:95
int64_t nOrderPos
position in ordered transaction list
Definition: transaction.h:185
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
Definition: wallet.h:831
OutputType m_default_address_type
Definition: wallet.h:634
bool EraseLockedUTXO(const COutPoint &output)
Definition: walletdb.cpp:295
void setArray()
Definition: univalue.cpp:92
std::optional< CMutableTransaction > tx
Definition: psbt.h:948
virtual CBlockLocator getTipLocator()=0
Get locator for the current chain tip.
bool 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) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:1662
std::shared_ptr< CWallet > CreateWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:280
static bool exists(const path &p)
Definition: fs.h:88
virtual bool TopUp(unsigned int size=0)
Fills internal address pool.
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
Definition: walletdb.cpp:216
static path u8path(const std::string &utf8_str)
Definition: fs.h:70
std::shared_ptr< CWallet > RestoreWallet(WalletContext &context, const fs::path &backup_file, const std::string &wallet_name, std::optional< bool > load_on_start, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:385
util::Result< CTxDestination > GetNewDestination(const OutputType type, const std::string label)
Definition: wallet.cpp:2381
unsigned int nMasterKeyMaxID
Definition: wallet.h:372
int64_t GetTime()
DEPRECATED, see GetTime.
Definition: time.cpp:117
bool DummySignInput(const SigningProvider &provider, CTxIn &tx_in, const CTxOut &txout, const CCoinControl *coin_control)
Definition: wallet.cpp:1555
COutPoint prevout
Definition: transaction.h:76
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
Definition: walletdb.cpp:1016
const unsigned int WALLET_CRYPTO_SALT_SIZE
Definition: crypter.h:15
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
static path absolute(const path &p)
Definition: fs.h:81
const CKeyingMaterial & GetEncryptionKey() const override
Definition: wallet.cpp:3435
ArgsManager * args
Definition: context.h:37
std::shared_ptr< CWallet > GetDefaultWallet(WalletContext &context, size_t &count)
Definition: wallet.cpp:154
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
Definition: walletdb.cpp:81
bool AddWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
Definition: wallet.cpp:110
void MarkConflicted(const uint256 &hashBlock, int conflicting_height, const uint256 &hashTx)
Mark a transaction (and its in-wallet descendants) as conflicting with a particular block...
Definition: wallet.cpp:1238
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
std::atomic< double > m_scanning_progress
Definition: wallet.h:246
virtual CFeeRate relayMinFee()=0
Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
void SetTx(CTransactionRef arg)
Definition: transaction.h:268
bool isArray() const
Definition: univalue.h:80
CTransactionRef tx
Definition: transaction.h:219
void ConnectScriptPubKeyManNotifiers()
Connect the signals from ScriptPubKeyMans to the signals in CWallet.
Definition: wallet.cpp:3445
CAmount GetFeePerK() const
Return the fee in satoshis for a vsize of 1000 vbytes.
Definition: feerate.h:65
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:2566
bool HasWalletDescriptor(const WalletDescriptor &desc) const
Coin Control Features.
Definition: coincontrol.h:29
std::variant< TxStateConfirmed, TxStateInMempool, TxStateConflicted, TxStateInactive, TxStateUnrecognized > TxState
All possible CWalletTx states.
Definition: transaction.h:66
WalletFeature GetClosestWalletFeature(int version)
Definition: walletutil.cpp:38
TransactionError FillPSBT(PartiallySignedTransaction &psbtx, bool &complete, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=true, size_t *n_signed=nullptr, bool finalize=true) const
Fills out a PSBT with information from the wallet.
Definition: wallet.cpp:2036
#define PACKAGE_BUGREPORT
static std::condition_variable g_wallet_release_cv
Definition: wallet.cpp:187
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
Definition: wallet.h:757
bool HasInputWeight(const COutPoint &outpoint) const
Definition: coincontrol.h:122
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector< std::pair< std::string, std::string >> orderForm)
Submit the transaction to the node&#39;s mempool and then relay to peers.
Definition: wallet.cpp:2193
virtual bool havePruned()=0
Check if any block has been pruned.
util::Result< CTxDestination > GetNewChangeDestination(const OutputType type)
Definition: wallet.cpp:2398
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
Definition: crypter.h:62
void UnsetWalletFlagWithDB(WalletBatch &batch, uint64_t flag)
Unsets a wallet flag and saves it to disk.
Definition: wallet.cpp:1507
ScriptPubKeyMan * AddWalletDescriptor(WalletDescriptor &desc, const FlatSigningProvider &signing_provider, const std::string &label, bool internal) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type.
Definition: wallet.cpp:3628
Clock::time_point now() const
Definition: wallet.h:979
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
Definition: wallet.cpp:2776
#define Assert(val)
Identity function.
Definition: check.h:74
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
Definition: context.h:23
bool IsSpentKey(const CScript &scriptPubKey) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:927
std::vector< std::unique_ptr< DescriptorScriptPubKeyMan > > desc_spkms
Definition: walletutil.h:117
static bool copy_file(const path &from, const path &to, copy_options options)
Definition: fs.h:127
void GetStrongRandBytes(Span< unsigned char > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Definition: random.cpp:581
OutputType TransactionChangeType(const std::optional< OutputType > &change_type, const std::vector< CRecipient > &vecSend) const
Definition: wallet.cpp:2130
static std::shared_ptr< CWallet > Create(WalletContext &context, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:2800
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:93
static bool AttachChain(const std::shared_ptr< CWallet > &wallet, interfaces::Chain &chain, const bool rescan_required, bilingual_str &error, std::vector< bilingual_str > &warnings)
Catch wallet up to current chain, scanning new blocks, updating the best block locator and m_last_blo...
Definition: wallet.cpp:3047
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
Definition: wallet.cpp:3415
void SetupDescriptorScriptPubKeyMans() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.cpp:3487
std::atomic< bool > m_attaching_chain
Definition: wallet.h:244
CAmount GetDebit(const CTxIn &txin, const isminefilter &filter) const
Returns amount of debit if the input matches the filter, otherwise returns 0.
Definition: wallet.cpp:1392
PrecomputedTransactionData PrecomputePSBTData(const PartiallySignedTransaction &psbt)
Compute a PrecomputedTransactionData object from a psbt.
Definition: psbt.cpp:312
void transactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override
Definition: wallet.cpp:1309
uint256 hash
Definition: transaction.h:37
int GetTxDepthInMainChain(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
Definition: wallet.cpp:3244
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const
Get the SigningProvider for a script.
Definition: wallet.cpp:3375