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