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