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