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