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