9#include <chainparams.h>
46 "You need to rescan the blockchain in order to correctly mark used "
47 "destinations in the past. Until this is done, some destinations may "
48 "be considered unused, even if the opposite is the case."},
56 const std::string &wallet_name) {
62 if (value.isStr() && value.get_str() == wallet_name) {
71 const std::string &wallet_name) {
78 if (!value.isStr() || value.get_str() != wallet_name) {
82 if (new_value.
size() == setting_value.
size()) {
89 const std::string &wallet_name,
90 std::optional<bool> load_on_startup,
91 std::vector<bilingual_str> &warnings) {
92 if (!load_on_startup) {
96 warnings.emplace_back(
97 Untranslated(
"Wallet load on startup setting could not be updated, "
98 "so wallet may not be loaded next node startup."));
99 }
else if (!load_on_startup.value() &&
101 warnings.emplace_back(
102 Untranslated(
"Wallet load on startup setting could not be updated, "
103 "so wallet may still be loaded next node startup."));
110 std::vector<std::shared_ptr<CWallet>>::const_iterator i =
111 std::find(vpwallets.begin(), vpwallets.end(),
wallet);
112 if (i != vpwallets.end()) {
115 vpwallets.push_back(
wallet);
116 wallet->ConnectScriptPubKeyManNotifiers();
117 wallet->NotifyCanGetAddressesChanged();
122 std::optional<bool> load_on_start,
123 std::vector<bilingual_str> &warnings) {
130 wallet->m_chain_notifications_handler.reset();
132 std::vector<std::shared_ptr<CWallet>>::iterator i =
133 std::find(vpwallets.begin(), vpwallets.end(),
wallet);
134 if (i == vpwallets.end()) {
146 std::optional<bool> load_on_start) {
147 std::vector<bilingual_str> warnings;
158 for (
const std::shared_ptr<CWallet> &
wallet : vpwallets) {
166std::unique_ptr<interfaces::Handler>
169 auto it = g_load_wallet_fns.emplace(g_load_wallet_fns.end(),
170 std::move(load_wallet));
173 g_load_wallet_fns.erase(it);
180static std::set<std::string>
182static std::set<std::string>
188 wallet->WalletLogPrintf(
"Releasing wallet\n");
194 if (g_unloading_wallet_set.erase(
name) == 0) {
207 auto it = g_unloading_wallet_set.insert(
name);
219 while (g_unloading_wallet_set.count(
name) == 1) {
226std::shared_ptr<CWallet>
228 std::optional<bool> load_on_start,
232 std::unique_ptr<WalletDatabase> database =
241 std::shared_ptr<CWallet>
wallet =
251 wallet->postInitProcess();
257 }
catch (
const std::runtime_error &e) {
265std::shared_ptr<CWallet>
269 std::vector<bilingual_str> &warnings) {
271 return g_loading_wallet_set.insert(
name));
272 if (!result.second) {
277 auto wallet = LoadWalletInternal(chain,
name, load_on_start, options,
278 status,
error, warnings);
283std::shared_ptr<CWallet>
287 std::vector<bilingual_str> &warnings) {
296 if (!passphrase.empty()) {
302 std::unique_ptr<WalletDatabase> database =
312 if (!passphrase.empty() &&
315 "Passphrase provided but private keys are disabled. A passphrase "
316 "is only used to encrypt private keys, so cannot be used for "
317 "wallets with private keys disabled.");
324 std::shared_ptr<CWallet>
wallet =
326 wallet_creation_flags,
error, warnings);
335 if (!passphrase.empty() &&
337 if (!
wallet->EncryptWallet(passphrase)) {
339 Untranslated(
"Error: Wallet created but failed to encrypt.");
345 if (!
wallet->Unlock(passphrase)) {
347 "Error: Wallet was encrypted but could not be unlocked");
356 wallet->SetupDescriptorScriptPubKeyMans();
358 for (
auto spk_man :
wallet->GetActiveScriptPubKeyMans()) {
359 if (!spk_man->SetupGeneration()) {
374 wallet->postInitProcess();
396 std::map<TxId, CWalletTx>::const_iterator it = mapWallet.find(txid);
397 if (it == mapWallet.end()) {
401 return &(it->second);
414 spk_man->UpgradeKeyMetadata();
419 bool accept_no_keys) {
425 for (
const MasterKeyMap::value_type &pMasterKey :
mapMasterKeys) {
427 strWalletPassphrase, pMasterKey.second.vchSalt,
428 pMasterKey.second.nDeriveIterations,
429 pMasterKey.second.nDerivationMethod)) {
432 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey,
437 if (
Unlock(_vMasterKey, accept_no_keys)) {
460 strOldWalletPassphrase, pMasterKey.second.vchSalt,
461 pMasterKey.second.nDeriveIterations,
462 pMasterKey.second.nDerivationMethod)) {
466 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey)) {
470 if (
Unlock(_vMasterKey)) {
473 pMasterKey.second.vchSalt,
474 pMasterKey.second.nDeriveIterations,
475 pMasterKey.second.nDerivationMethod);
476 pMasterKey.second.nDeriveIterations =
static_cast<unsigned int>(
477 pMasterKey.second.nDeriveIterations *
482 pMasterKey.second.vchSalt,
483 pMasterKey.second.nDeriveIterations,
484 pMasterKey.second.nDerivationMethod);
485 pMasterKey.second.nDeriveIterations =
486 (pMasterKey.second.nDeriveIterations +
487 static_cast<unsigned int>(
488 pMasterKey.second.nDeriveIterations * 100 /
492 if (pMasterKey.second.nDeriveIterations < 25000) {
493 pMasterKey.second.nDeriveIterations = 25000;
497 "Wallet passphrase changed to an nDeriveIterations of %i\n",
498 pMasterKey.second.nDeriveIterations);
501 strNewWalletPassphrase, pMasterKey.second.vchSalt,
502 pMasterKey.second.nDeriveIterations,
503 pMasterKey.second.nDerivationMethod)) {
507 if (!crypter.
Encrypt(_vMasterKey,
508 pMasterKey.second.vchCryptedKey)) {
533 if (nWalletVersion >= nVersion) {
539 if (fExplicit && nVersion > nWalletMaxVersion) {
543 nWalletVersion = nVersion;
545 if (nVersion > nWalletMaxVersion) {
546 nWalletMaxVersion = nVersion;
550 if (nWalletVersion > 40000) {
562 if (nWalletVersion > nVersion) {
566 nWalletMaxVersion = nVersion;
572 std::set<TxId> result;
575 std::map<TxId, CWalletTx>::const_iterator it = mapWallet.find(txid);
576 if (it == mapWallet.end()) {
582 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
584 for (
const CTxIn &txin : wtx.
tx->vin) {
585 if (mapTxSpends.count(txin.prevout) <= 1) {
590 range = mapTxSpends.equal_range(txin.prevout);
591 for (TxSpends::const_iterator _it = range.first; _it != range.second;
593 result.insert(_it->second);
602 auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
603 return (iter != mapTxSpends.end() && iter->first.GetTxId() == txid);
615 std::pair<TxSpends::iterator, TxSpends::iterator> range) {
620 int nMinOrderPos = std::numeric_limits<int>::max();
622 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
623 const CWalletTx *wtx = &mapWallet.at(it->second);
635 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
636 const TxId &txid = it->second;
638 if (copyFrom == copyTo) {
644 "Oldest wallet transaction in range assumed to have been found.");
666 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range =
667 mapTxSpends.equal_range(outpoint);
669 for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
670 const TxId &wtxid = it->second;
671 std::map<TxId, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
672 if (mit != mapWallet.end()) {
674 if (depth > 0 || (depth == 0 && !mit->second.isAbandoned())) {
685 mapTxSpends.insert(std::make_pair(outpoint, wtxid));
687 setLockedCoins.erase(outpoint);
689 std::pair<TxSpends::iterator, TxSpends::iterator> range;
690 range = mapTxSpends.equal_range(outpoint);
695 auto it = mapWallet.find(wtxid);
696 assert(it != mapWallet.end());
703 for (
const CTxIn &txin : thisTx.
tx->vin) {
762 delete encrypted_batch;
763 encrypted_batch =
nullptr;
769 auto spk_man = spk_man_pair.second.get();
770 if (!spk_man->Encrypt(_vMasterKey, encrypted_batch)) {
772 delete encrypted_batch;
773 encrypted_batch =
nullptr;
785 delete encrypted_batch;
786 encrypted_batch =
nullptr;
793 delete encrypted_batch;
794 encrypted_batch =
nullptr;
797 Unlock(strWalletPassphrase);
805 if (spk_man->IsHDEnabled()) {
806 if (!spk_man->SetupGeneration(
true)) {
839 for (
auto &entry : mapWallet) {
845 std::vector<int64_t> nOrderPosOffsets;
846 for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) {
850 if (nOrderPos == -1) {
851 nOrderPos = nOrderPosNext++;
852 nOrderPosOffsets.push_back(nOrderPos);
858 int64_t nOrderPosOff = 0;
859 for (
const int64_t &nOffsetStart : nOrderPosOffsets) {
860 if (nOrderPos >= nOffsetStart) {
865 nOrderPos += nOrderPosOff;
866 nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
886 int64_t nRet = nOrderPosNext++;
898 for (std::pair<const TxId, CWalletTx> &item : mapWallet) {
899 item.second.MarkDirty();
904 unsigned int n,
bool used,
905 std::set<CTxDestination> &tx_destinations) {
918 tx_destinations.insert(dst);
920 }
else if (!used &&
GetDestData(dst,
"used",
nullptr)) {
941 assert(spk_man !=
nullptr);
942 for (
const auto &keyid :
957 bool fFlushOnClose) {
962 const TxId &txid = tx->GetId();
966 std::set<CTxDestination> tx_destinations;
968 for (
const CTxIn &txin : tx->vin) {
969 const COutPoint &op = txin.prevout;
979 mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid),
980 std::forward_as_tuple(tx));
982 bool fInsertedNew = ret.second;
983 bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew);
1010 (fInsertedNew ?
"new" :
""), (fUpdated ?
"update" :
""));
1013 if ((fInsertedNew || fUpdated) && !batch.
WriteTx(wtx)) {
1023#if defined(HAVE_SYSTEM)
1026 std::string strCmd =
gArgs.
GetArg(
"-walletnotify",
"");
1028 if (!strCmd.empty()) {
1039 std::thread t(runCommand, strCmd);
1050 mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid),
1051 std::forward_as_tuple(
nullptr));
1053 if (!fill_wtx(wtx, ins.second)) {
1061 if (
chain().findBlock(
1063 FoundBlock().inActiveChain(active).height(height)) &&
1086 for (
const CTxIn &txin : wtx.
tx->vin) {
1087 auto it = mapWallet.find(txin.prevout.GetTxId());
1088 if (it != mapWallet.end()) {
1104 const TxId &txid = ptx->GetId();
1107 for (
const CTxIn &txin : ptx->vin) {
1108 std::pair<TxSpends::const_iterator, TxSpends::const_iterator>
1109 range = mapTxSpends.equal_range(txin.prevout);
1110 while (range.first != range.second) {
1111 if (range.first->second != txid) {
1113 "Transaction %s (in block %s) conflicts with wallet "
1114 "transaction %s (both spend %s:%i)\n",
1116 range.first->second.ToString(),
1117 range.first->first.GetTxId().ToString(),
1118 range.first->first.GetN());
1120 range.first->second);
1127 bool fExisted = mapWallet.count(txid) != 0;
1128 if (fExisted && !fUpdate) {
1141 for (
const CTxOut &txout : ptx->vout) {
1143 spk_man_pair.second->MarkUnusedAddresses(txout.
scriptPubKey);
1164 for (
const CTxIn &txin : tx->vin) {
1165 auto it = mapWallet.find(txin.prevout.GetTxId());
1166 if (it != mapWallet.end()) {
1167 it->second.MarkDirty();
1177 std::set<TxId> todo;
1178 std::set<TxId> done;
1181 auto it = mapWallet.find(txid);
1182 assert(it != mapWallet.end());
1190 while (!todo.empty()) {
1194 it = mapWallet.find(now);
1195 assert(it != mapWallet.end());
1199 assert(currentconfirm <= 0);
1212 TxSpends::const_iterator iter =
1213 mapTxSpends.lower_bound(COutPoint(now, 0));
1214 while (iter != mapTxSpends.end() && iter->first.GetTxId() == now) {
1215 if (!done.count(iter->second)) {
1216 todo.insert(iter->second);
1235 int conflictconfirms =
1236 (m_last_block_processed_height - conflicting_height + 1) * -1;
1241 if (conflictconfirms >= 0) {
1248 std::set<TxId> todo;
1249 std::set<TxId> done;
1253 while (!todo.empty()) {
1257 auto it = mapWallet.find(now);
1258 assert(it != mapWallet.end());
1261 if (conflictconfirms < currentconfirm) {
1272 TxSpends::const_iterator iter =
1273 mapTxSpends.lower_bound(COutPoint(now, 0));
1274 while (iter != mapTxSpends.end() && iter->first.GetTxId() == now) {
1275 if (!done.count(iter->second)) {
1276 todo.insert(iter->second);
1302 uint64_t mempool_sequence) {
1308 auto it = mapWallet.find(tx->GetId());
1309 if (it != mapWallet.end()) {
1310 it->second.fInMempool =
true;
1316 uint64_t mempool_sequence) {
1318 auto it = mapWallet.find(tx->GetId());
1319 if (it != mapWallet.end()) {
1320 it->second.fInMempool =
false;
1351 {CWalletTx::Status::UNCONFIRMED, 0,
1360 m_last_block_processed_height = height;
1361 m_last_block_processed = block_hash;
1362 for (
size_t index = 0; index < block.
vtx.size(); index++) {
1364 block_hash, int(index)});
1379 m_last_block_processed_height = height - 1;
1383 {CWalletTx::Status::UNCONFIRMED, 0,
1392void CWallet::BlockUntilSyncedToCurrentChain()
const {
1407 std::map<TxId, CWalletTx>::const_iterator mi =
1408 mapWallet.find(txin.prevout.GetTxId());
1409 if (mi != mapWallet.end()) {
1411 if (txin.prevout.GetN() < prev.
tx->vout.size()) {
1412 if (
IsMine(prev.
tx->vout[txin.prevout.GetN()]) & filter) {
1413 return prev.
tx->vout[txin.prevout.GetN()].nValue;
1435 result = std::max(result, spk_man_pair.second->IsMine(script));
1442 for (
const CTxOut &txout : tx.vout) {
1458 for (
const CTxIn &txin : tx.vin) {
1461 throw std::runtime_error(std::string(__func__) +
1462 ": value out of range");
1473 result &= spk_man->IsHDEnabled();
1485 if (spk_man && spk_man->CanGetAddresses(internal)) {
1496 throw std::runtime_error(std::string(__func__) +
1497 ": writing wallet flags failed");
1510 throw std::runtime_error(std::string(__func__) +
1511 ": writing wallet flags failed");
1539 throw std::runtime_error(std::string(__func__) +
1540 ": writing wallet flags failed");
1549 bool use_max_sig)
const {
1554 std::unique_ptr<SigningProvider> provider =
1564 scriptPubKey, sigdata)) {
1575 const std::vector<CTxOut> &txouts,
1576 bool use_max_sig)
const {
1579 for (
const auto &txout : txouts) {
1590 int64_t timestamp) {
1595 LOCK(spk_man->cs_KeyStore);
1596 return spk_man->ImportScripts(scripts, timestamp);
1600 const int64_t timestamp) {
1605 LOCK(spk_man->cs_KeyStore);
1606 return spk_man->ImportPrivKeys(privkey_map, timestamp);
1610 const std::vector<CKeyID> &ordered_pubkeys,
1611 const std::map<CKeyID, CPubKey> &pubkey_map,
1612 const std::map<
CKeyID, std::pair<CPubKey, KeyOriginInfo>> &key_origins,
1613 const bool add_keypool,
const bool internal,
const int64_t timestamp) {
1618 LOCK(spk_man->cs_KeyStore);
1619 return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins,
1620 add_keypool, internal, timestamp);
1624 const std::set<CScript> &script_pub_keys,
1625 const bool have_solving_data,
1626 const bool apply_label,
1627 const int64_t timestamp) {
1632 LOCK(spk_man->cs_KeyStore);
1633 if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data,
1639 for (
const CScript &script : script_pub_keys) {
1664 int start_height = 0;
1668 FoundBlock().hash(start_block).height(start_height));
1677 start_block, start_height, {} , reserver, update);
1710 const BlockHash &start_block,
int start_height,
1737 double progress_current = progress_begin;
1738 int block_height = start_height;
1740 if (progress_end - progress_begin > 0.0) {
1742 (progress_end - progress_begin);
1748 if (block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
1750 strprintf(
"%s " +
_(
"Rescanning...").translated,
1757 block_height, progress_current);
1766 bool block_still_active =
false;
1767 bool next_block =
false;
1771 .inActiveChain(block_still_active)
1773 .inActiveChain(next_block)
1774 .hash(next_block_hash)));
1778 if (!block_still_active) {
1785 for (
size_t posInBlock = 0; posInBlock < block.
vtx.size();
1788 block_height, block_hash,
1791 {CWalletTx::Status::CONFIRMED, block_height,
1792 block_hash, int(posInBlock)},
1805 if (max_height && block_height >= *max_height) {
1816 block_hash = next_block_hash;
1821 const BlockHash prev_tip_hash = tip_hash;
1823 if (!max_height && prev_tip_hash != tip_hash) {
1836 block_height, progress_current);
1838 }
else if (block_height &&
chain().shutdownRequested()) {
1840 "Rescan interrupted by shutdown request at block %d. Progress=%f\n",
1841 block_height, progress_current);
1859 std::map<int64_t, CWalletTx *> mapSorted;
1863 for (std::pair<const TxId, CWalletTx> &item : mapWallet) {
1864 const TxId &wtxid = item.first;
1871 mapSorted.insert(std::make_pair(wtx.
nOrderPos, &wtx));
1876 for (
const std::pair<const int64_t, CWalletTx *> &item : mapSorted) {
1878 std::string unused_err_string;
1884 std::string &err_string,
1927 std::set<TxId> result;
1947 if (!
chain().isReadyToBroadcast()) {
1964 int submitted_tx_count = 0;
1970 for (std::pair<const TxId, CWalletTx> &item : mapWallet) {
1978 std::string unused_err_string;
1980 ++submitted_tx_count;
1985 if (submitted_tx_count > 0) {
1986 WalletLogPrintf(
"%s: resubmit %u unconfirmed transactions\n", __func__,
1987 submitted_tx_count);
1994 for (
const std::shared_ptr<CWallet> &pwallet :
GetWallets()) {
1995 pwallet->ResendWalletTransactions();
2009 std::map<COutPoint, Coin> coins;
2010 for (
auto &input : tx.
vin) {
2011 auto mi = mapWallet.find(input.prevout.GetTxId());
2012 if (mi == mapWallet.end() ||
2013 input.prevout.GetN() >= mi->second.tx->vout.size()) {
2017 coins[input.prevout] =
2021 std::map<int, std::string> input_errors;
2026 const std::map<COutPoint, Coin> &coins,
2028 std::map<int, std::string> &input_errors)
const {
2033 if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2044 if (legacy_spk_man &&
2045 legacy_spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2054 bool sign,
bool bip32derivs)
const {
2057 for (
size_t i = 0; i < psbtx.
tx->vin.size(); ++i) {
2058 const CTxIn &txin = psbtx.
tx->vin[i];
2067 const TxId &txid = txin.prevout.GetTxId();
2068 const auto it = mapWallet.find(txid);
2069 if (it != mapWallet.end()) {
2071 CTxOut utxo = wtx.
tx->vout[txin.prevout.GetN()];
2081 spk_man->FillPSBT(psbtx, sighash_type, sign, bip32derivs);
2089 for (
const auto &input : psbtx.
inputs) {
2098 std::string &str_sig)
const {
2102 if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
2103 return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
2111 const std::vector<CRecipient> &vecSend)
const {
2114 return *change_type;
2128 std::vector<std::pair<std::string, std::string>> orderForm,
2139 wtx.
mapValue = std::move(mapValue);
2147 for (
const CTxIn &txin : tx->vin) {
2148 CWalletTx &coin = mapWallet.at(txin.prevout.GetTxId());
2155 CWalletTx &wtx = mapWallet.at(tx->GetId());
2163 std::string err_string;
2165 WalletLogPrintf(
"CommitTransaction(): Transaction cannot be broadcast "
2166 "immediately, %s\n",
2178 if (
database->Rewrite(
"\x04pool")) {
2180 spk_man_pair.second->RewriteDB();
2191 return nLoadWalletRet;
2198 std::vector<TxId> &txIdsOut) {
2202 for (
const TxId &txid : txIdsOut) {
2203 const auto &it = mapWallet.find(txid);
2204 wtxOrdered.erase(it->second.m_it_wtxOrdered);
2205 for (
const auto &txin : it->second.tx->vin) {
2206 mapTxSpends.erase(txin.prevout);
2208 mapWallet.erase(it);
2213 if (
database->Rewrite(
"\x04pool")) {
2215 spk_man_pair.second->RewriteDB();
2221 return nZapSelectTxRet;
2231 const std::string &strName,
2232 const std::string &strPurpose) {
2233 bool fUpdated =
false;
2237 std::map<CTxDestination, CAddressBookData>::iterator mi =
2238 m_address_book.find(address);
2239 fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
2240 m_address_book[address].SetLabel(strName);
2242 if (!strPurpose.empty()) {
2243 m_address_book[address].purpose = strPurpose;
2250 if (!strPurpose.empty() && !batch.
WritePurpose(address, strPurpose)) {
2253 return batch.
WriteName(address, strName);
2257 const std::string &strName,
2258 const std::string &strPurpose) {
2277 "%s called with IsMine address, NOT SUPPORTED. Please "
2278 "report this bug! %s\n",
2279 __func__, PACKAGE_BUGREPORT);
2283 for (
const std::pair<const std::string, std::string> &item :
2284 m_address_book[address].destdata) {
2287 m_address_book.erase(address);
2300 unsigned int count = 0;
2302 count += spk_man->KeypoolCountExternalKeys();
2311 unsigned int count = 0;
2313 count += spk_man->GetKeyPoolSize();
2322 res &= spk_man->TopUp(kpSize);
2331 bool result =
false;
2335 result = spk_man->GetNewDestination(type, dest,
error);
2349 std::string &
error) {
2355 error =
_(
"Error: Keypool ran out, please call keypoolrefill first")
2366 int64_t oldestKey = std::numeric_limits<int64_t>::max();
2369 std::min(oldestKey, spk_man_pair.second->GetOldestKeyPoolTime());
2375 const std::set<CTxDestination> &destinations) {
2376 for (
auto &entry : mapWallet) {
2382 for (
size_t i = 0; i < wtx.
tx->vout.size(); i++) {
2386 destinations.count(dst)) {
2394std::set<CTxDestination>
2397 std::set<CTxDestination> result;
2398 for (
const std::pair<const CTxDestination, CAddressBookData> &item :
2400 if (item.second.IsChange()) {
2404 const std::string &strName = item.second.GetLabel();
2405 if (strName == label) {
2406 result.insert(address);
2453 setLockedCoins.insert(output);
2458 setLockedCoins.erase(output);
2463 setLockedCoins.clear();
2469 return setLockedCoins.count(outpoint) > 0;
2474 for (COutPoint outpoint : setLockedCoins) {
2475 vOutpts.push_back(outpoint);
2483 mapKeyBirth.clear();
2486 std::map<CKeyID, const CWalletTx::Confirmation *> mapKeyFirstBlock;
2497 assert(spk_man !=
nullptr);
2501 for (
const auto &entry : spk_man->mapKeyMetadata) {
2502 if (entry.second.nCreateTime) {
2503 mapKeyBirth[entry.first] = entry.second.nCreateTime;
2509 if (mapKeyBirth.count(keyid) == 0) {
2510 mapKeyFirstBlock[keyid] = &max_confirm;
2515 if (mapKeyFirstBlock.empty()) {
2520 for (
const auto &entry : mapWallet) {
2525 for (
const CTxOut &txout : wtx.
tx->vout) {
2527 for (
const auto &keyid :
2530 auto rit = mapKeyFirstBlock.find(keyid);
2531 if (rit != mapKeyFirstBlock.end() &&
2533 rit->second->block_height) {
2543 for (
const auto &entry : mapKeyFirstBlock) {
2580 int64_t latestEntry = 0;
2584 int64_t latestTolerated = latestNow + 300;
2586 for (
auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
2596 if (nSmartTime <= latestTolerated) {
2597 latestEntry = nSmartTime;
2598 if (nSmartTime > latestNow) {
2599 latestNow = nSmartTime;
2605 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
2616 const std::string &key,
const std::string &value) {
2617 if (std::get_if<CNoDestination>(&dest)) {
2621 m_address_book[dest].destdata.insert(std::make_pair(key, value));
2626 const std::string &key) {
2627 if (!m_address_book[dest].destdata.erase(key)) {
2635 const std::string &value) {
2636 m_address_book[dest].destdata.insert(std::make_pair(key, value));
2640 std::string *value)
const {
2641 std::map<CTxDestination, CAddressBookData>::const_iterator i =
2642 m_address_book.find(dest);
2643 if (i != m_address_book.end()) {
2644 CAddressBookData::StringMap::const_iterator j =
2645 i->second.destdata.find(key);
2646 if (j != i->second.destdata.end()) {
2657std::vector<std::string>
2659 std::vector<std::string> values;
2660 for (
const auto &address : m_address_book) {
2661 for (
const auto &data : address.second.destdata) {
2663 values.emplace_back(data.second);
2670std::unique_ptr<WalletDatabase>
2681 fs::file_type path_type = fs::symlink_status(wallet_path).type();
2682 if (!(path_type == fs::file_type::not_found ||
2683 path_type == fs::file_type::directory ||
2684 (path_type == fs::file_type::symlink &&
2685 fs::is_directory(wallet_path)) ||
2686 (path_type == fs::file_type::regular &&
2689 strprintf(
"Invalid -wallet path '%s'. -wallet path should point to "
2690 "a directory where wallet.dat and "
2691 "database/log.?????????? files can be stored, a location "
2692 "where such a directory could be created, "
2693 "or (for backwards compatibility) the name of an "
2694 "existing data file in -walletdir (%s)",
2699 return MakeDatabase(wallet_path, options, status, error_string);
2702std::shared_ptr<CWallet>
2704 std::unique_ptr<WalletDatabase> database,
2706 std::vector<bilingual_str> &warnings) {
2707 const std::string &walletFile =
database->Filename();
2712 std::shared_ptr<CWallet> walletInstance(
2714 DBErrors nLoadWalletRet = walletInstance->LoadWallet();
2718 strprintf(
_(
"Error loading %s: Wallet corrupted"), walletFile);
2724 strprintf(
_(
"Error reading %s! All keys read correctly, but "
2725 "transaction data or address book entries might be "
2726 "missing or incorrect."),
2730 _(
"Error loading %s: Wallet requires newer version of %s"),
2731 walletFile, PACKAGE_NAME);
2735 _(
"Wallet needed to be rewritten: restart %s to complete"),
2746 const bool fFirstRun =
2747 walletInstance->m_spk_managers.empty() &&
2755 walletInstance->AddWalletFlags(wallet_creation_flags);
2759 walletInstance->SetupLegacyScriptPubKeyMan();
2762 if (!(wallet_creation_flags &
2764 LOCK(walletInstance->cs_wallet);
2766 walletInstance->SetupDescriptorScriptPubKeyMans();
2772 walletInstance->GetActiveScriptPubKeyMans()) {
2773 if (!spk_man->SetupGeneration()) {
2774 error =
_(
"Unable to generate initial keys");
2787 "disabled during creation"),
2790 }
else if (walletInstance->IsWalletFlagSet(
2792 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
2793 if (spk_man->HavePrivateKeys()) {
2795 strprintf(
_(
"Warning: Private keys detected in wallet {%s} "
2796 "with disabled private keys"),
2811 _(
"This is the minimum transaction fee you pay "
2812 "on every transaction."));
2814 walletInstance->m_min_fee =
CFeeRate(n);
2818 const std::string max_aps_fee{
gArgs.
GetArg(
"-maxapsfee",
"")};
2820 if (max_aps_fee ==
"-1") {
2829 _(
"This is the maximum transaction fee you pay (in addition to"
2830 " the normal fee) to prioritize partial spend avoidance over"
2831 " regular coin selection."));
2833 walletInstance->m_max_aps_fee = n;
2840 strprintf(
_(
"Invalid amount for -fallbackfee=<amount>: '%s'"),
2847 _(
"This is the transaction fee you may pay when "
2848 "fee estimates are not available."));
2850 walletInstance->m_fallback_fee =
CFeeRate(nFeePerK);
2853 walletInstance->m_allow_fallback_fee =
2854 walletInstance->m_fallback_fee.GetFeePerK() !=
Amount::zero();
2864 _(
"This is the transaction fee you will pay if "
2865 "you send a transaction."));
2867 walletInstance->m_pay_tx_fee =
CFeeRate(nFeePerK, 1000);
2870 "(must be at least %s)"),
2884 warnings.push_back(
_(
"-maxtxfee is set very high! Fees this large "
2885 "could be paid on a single transaction."));
2889 _(
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at "
2890 "least the minrelay fee of %s to prevent stuck "
2895 walletInstance->m_default_max_tx_fee = nMaxFee;
2901 _(
"The wallet will avoid paying less than the minimum relay fee."));
2904 walletInstance->m_spend_zero_conf_change =
2909 walletInstance->WalletLogPrintf(
"Wallet completed loading in %15dms\n",
2913 walletInstance->TopUpKeyPool();
2915 LOCK(walletInstance->cs_wallet);
2923 for (
auto &load_wallet : g_load_wallet_fns) {
2928 walletInstance->SetBroadcastTransactions(
2932 walletInstance->WalletLogPrintf(
"setKeyPool.size() = %u\n",
2933 walletInstance->GetKeyPoolSize());
2934 walletInstance->WalletLogPrintf(
"mapWallet.size() = %u\n",
2935 walletInstance->mapWallet.size());
2936 walletInstance->WalletLogPrintf(
"m_address_book.size() = %u\n",
2937 walletInstance->m_address_book.size());
2940 return walletInstance;
2945 std::vector<bilingual_str> &warnings) {
2946 LOCK(walletInstance->cs_wallet);
2949 assert(!walletInstance->m_chain || walletInstance->m_chain == &
chain);
2950 walletInstance->m_chain = &
chain;
2960 walletInstance->m_chain_notifications_handler =
2963 int rescan_height = 0;
2968 if (
const std::optional<int> fork_height =
2970 rescan_height = *fork_height;
2977 walletInstance->m_last_block_processed =
2979 walletInstance->m_last_block_processed_height = *tip_height;
2981 walletInstance->m_last_block_processed.
SetNull();
2982 walletInstance->m_last_block_processed_height = -1;
2985 if (tip_height && *tip_height != rescan_height) {
2990 int block_height = *tip_height;
2991 while (block_height > 0 &&
2993 rescan_height != block_height) {
2997 if (rescan_height != block_height) {
3010 ?
_(
"Prune: last wallet synchronisation goes beyond "
3011 "pruned data. You need to -reindex (download the "
3012 "whole blockchain again in case of pruned node)")
3013 :
strprintf(
_(
"Error loading wallet. Wallet requires "
3014 "blocks to be downloaded, "
3015 "and software does not currently support "
3016 "loading wallets while "
3017 "blocks are being downloaded out of "
3018 "order when using assumeutxo "
3019 "snapshots. Wallet should be able to "
3020 "load successfully after "
3021 "node sync reaches height %s"),
3028 walletInstance->WalletLogPrintf(
3029 "Rescanning last %i blocks (from block %i)...\n",
3030 *tip_height - rescan_height, rescan_height);
3034 std::optional<int64_t> time_first_key;
3035 for (
auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
3036 int64_t time = spk_man->GetTimeFirstKey();
3037 if (!time_first_key || time < *time_first_key) {
3038 time_first_key = time;
3041 if (time_first_key) {
3052 ->ScanForWalletTransactions(
3054 {} , reserver,
true )
3056 error =
_(
"Failed to rescan the wallet during initialization");
3061 walletInstance->database->IncrementUpdateCounter();
3069 bool allow_change)
const {
3070 const auto &address_book_it = m_address_book.find(dest);
3071 if (address_book_it == m_address_book.end()) {
3074 if ((!allow_change) && address_book_it->second.IsChange()) {
3077 return &address_book_it->second;
3082 int nMaxVersion = version;
3084 if (nMaxVersion == 0) {
3094 error =
_(
"Cannot downgrade wallet");
3108 error =
_(
"Cannot upgrade a non HD split wallet without upgrading to "
3109 "support pre split keypool. Please use version 200300 or no "
3110 "version specified.");
3115 if (!spk_man->Upgrade(prev_version,
error)) {
3169 assert(chain_depth >= 0);
3189 return vMasterKey.empty();
3199 if (!vMasterKey.empty()) {
3202 sizeof(
decltype(vMasterKey)::value_type));
3215 if (!spk_man_pair.second->CheckDecryptionKey(vMasterKeyIn,
3220 vMasterKey = vMasterKeyIn;
3227 std::set<ScriptPubKeyMan *> spk_mans;
3228 for (
bool internal : {
false,
true}) {
3232 spk_mans.insert(spk_man);
3240 std::set<ScriptPubKeyMan *> spk_mans;
3242 spk_mans.insert(spk_man_pair.second.get());
3248 bool internal)
const {
3249 const std::map<OutputType, ScriptPubKeyMan *> &spk_managers =
3251 std::map<OutputType, ScriptPubKeyMan *>::const_iterator it =
3252 spk_managers.find(type);
3253 if (it == spk_managers.end()) {
3255 "%s scriptPubKey Manager for output type %d does not exist\n",
3256 internal ?
"Internal" :
"External",
static_cast<int>(type));
3262std::set<ScriptPubKeyMan *>
3265 std::set<ScriptPubKeyMan *> spk_mans;
3267 if (spk_man_pair.second->CanProvide(script, sigdata)) {
3268 spk_mans.insert(spk_man_pair.second.get());
3277 if (spk_man_pair.second->CanProvide(script, sigdata)) {
3278 return spk_man_pair.second.get();
3291std::unique_ptr<SigningProvider>
3297std::unique_ptr<SigningProvider>
3301 if (spk_man_pair.second->CanProvide(script, sigdata)) {
3302 return spk_man_pair.second->GetSolvingProvider(script);
3345 return cb(vMasterKey);
3355 spk_man->NotifyCanGetAddressesChanged.connect(
3362 auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(
3380 for (
bool internal : {
false,
true}) {
3383 std::make_unique<DescriptorScriptPubKeyMan>(*
this, internal);
3386 throw std::runtime_error(
3387 std::string(__func__) +
3388 ": Wallet is locked, cannot setup new descriptors");
3390 if (!spk_manager->CheckDecryptionKey(vMasterKey) &&
3391 !spk_manager->Encrypt(vMasterKey,
nullptr)) {
3392 throw std::runtime_error(
3393 std::string(__func__) +
3394 ": Could not encrypt new descriptors");
3397 spk_manager->SetupDescriptorGeneration(master_key, t);
3398 uint256 id = spk_manager->GetID();
3410 throw std::runtime_error(std::string(__func__) +
3411 ": writing active ScriptPubKeyMan id failed");
3425 "Setting spkMan to active: id = %s, type = %d, internal = %d\n",
3426 id.
ToString(),
static_cast<int>(type),
static_cast<int>(internal));
3429 auto &spk_mans_other =
3432 spk_man->SetInternal(internal);
3433 spk_mans[type] = spk_man;
3435 const auto it = spk_mans_other.find(type);
3436 if (it != spk_mans_other.end() && it->second == spk_man) {
3437 spk_mans_other.erase(type);
3446 if (spk_man !=
nullptr && spk_man->GetID() ==
id) {
3448 "Deactivate spkMan: id = %s, type = %d, internal = %d\n",
3449 id.
ToString(),
static_cast<int>(type),
static_cast<int>(internal));
3453 throw std::runtime_error(
3454 std::string(__func__) +
3455 ": erasing active ScriptPubKeyMan id failed");
3460 spk_mans.erase(type);
3472 return spk_man !=
nullptr;
3482 spk_man_pair.second.get());
3494 const std::string &label,
bool internal) {
3499 "Cannot add WalletDescriptor to a non-descriptor wallet\n");
3507 spk_man->UpdateWalletDescriptor(desc);
3510 std::make_unique<DescriptorScriptPubKeyMan>(*
this, desc);
3511 spk_man = new_spk_man.get();
3518 for (
const auto &entry : signing_provider.
keys) {
3519 const CKey &key = entry.second;
3520 spk_man->AddDescriptorKey(key, key.
GetPubKey());
3524 if (!spk_man->TopUp()) {
3532 auto script_pub_keys = spk_man->GetScriptPubKeys();
3533 if (script_pub_keys.empty()) {
3535 "Could not generate scriptPubKeys (cache is empty)\n");
3546 spk_man->WriteDescriptor();
bool MoneyRange(const Amount nValue)
static constexpr Amount SATOSHI
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
const CChainParams & Params()
Return the currently selected parameters.
#define CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
std::vector< CTransactionRef > vtx
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Encryption/decryption context with key information.
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< uint8_t > &vchCiphertext) const
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< uint8_t > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
bool Decrypt(const std::vector< uint8_t > &vchCiphertext, CKeyingMaterial &vchPlaintext) const
Fee rate in satoshis per kilobyte: Amount / kB.
std::string ToString() const
Amount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
An encapsulated secp256k1 private key.
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
A reference to a CKey: the Hash160 of its serialized public key.
A key from a CWallet's keypool.
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
CPubKey vchPubKey
The public key.
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
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.
std::vector< uint8_t > vchSalt
unsigned int nDerivationMethod
0 = EVP_sha512() 1 = scrypt()
unsigned int nDeriveIterations
std::vector< uint8_t > vchCryptedKey
A mutable version of CTransaction.
An encapsulated public key.
An output of a transaction.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const
Get the SigningProvider for a script.
std::atomic< int64_t > m_best_block_time
BlockHash GetLastBlockHash() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::set< ScriptPubKeyMan * > GetScriptPubKeyMans(const CScript &script, SignatureData &sigdata) const
Get all of the ScriptPubKeyMans for a script given additional information in sigdata (populated by e....
bool HaveChain() const
Interface to assert chain access.
int GetTxBlocksToMaturity(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool DummySignTx(CMutableTransaction &txNew, const std::set< CTxOut > &txouts, bool use_max_sig=false) const
void ConnectScriptPubKeyManNotifiers()
Connect the signals from ScriptPubKeyMans to the signals in CWallet.
void AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Adds the active ScriptPubKeyMan for the specified type and internal.
void SetupLegacyScriptPubKeyMan()
Make a LegacyScriptPubKeyMan and set it for all types, internal, and external.
bool AddDestData(WalletBatch &batch, const CTxDestination &dest, const std::string &key, const std::string &value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Adds a destination data tuple to the store, and saves it to disk When adding new fields,...
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
const std::string GetDisplayName() const override
Returns a bracketed wallet name for displaying in logs, will return [default wallet] if the wallet ha...
MasterKeyMap mapMasterKeys
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...
bool IsTxImmatureCoinBase(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
static std::shared_ptr< CWallet > Create(interfaces::Chain *chain, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bilingual_str &error, std::vector< bilingual_str > &warnings)
Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error.
bool Unlock(const CKeyingMaterial &vMasterKeyIn, bool accept_no_keys=false)
bool GetBroadcastTransactions() const
Inquire whether this wallet broadcasts transactions.
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
interfaces::Chain & chain() const
Interface for accessing chain state.
void SetupDescriptorScriptPubKeyMans() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Create new DescriptorScriptPubKeyMans and add them to the wallet.
WalletDatabase & GetDatabase() override
interfaces::Chain * m_chain
Interface for accessing chain state.
bool WithEncryptionKey(const std::function< bool(const CKeyingMaterial &)> &cb) const override
Pass the encryption key to cb().
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
std::map< OutputType, ScriptPubKeyMan * > m_external_spk_managers
void DeactivateScriptPubKeyMan(const uint256 &id, OutputType type, bool internal)
Remove specified ScriptPubKeyMan from set of active SPK managers.
bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Look up a destination data tuple in the store, return true if found false otherwise.
bool IsLegacy() const
Determine if we are a legacy wallet.
std::atomic< bool > fAbortRescan
std::map< uint256, std::unique_ptr< ScriptPubKeyMan > > m_spk_managers
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Loads an active ScriptPubKeyMan for the specified type and internal.
boost::signals2::signal< void(CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)> NotifyAddressBookChanged
Address book entry changed.
int GetLastBlockHeight() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get last block processed height.
boost::signals2::signal< void(CWallet *wallet)> NotifyStatusChanged
Wallet status (encrypted, locked) changed.
OutputType m_default_address_type
DescriptorScriptPubKeyMan * GetDescriptorScriptPubKeyMan(const WalletDescriptor &desc) const
Return the DescriptorScriptPubKeyMan for a WalletDescriptor if it is already in the wallet.
static bool AttachChain(const std::shared_ptr< CWallet > &wallet, interfaces::Chain &chain, 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...
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
LegacyScriptPubKeyMan * GetLegacyScriptPubKeyMan() const
Get the LegacyScriptPubKeyMan which is used for all types, internal, and external.
std::atomic< uint64_t > m_wallet_flags
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
check whether we are allowed to upgrade (or already support) to the named feature
bool BackupWallet(const std::string &strDest) const
unsigned int ComputeTimeSmart(const CWalletTx &wtx) const
Compute smart timestamp for a transaction being added to the wallet.
void WalletLogPrintfToBeContinued(std::string fmt, Params... parameters) const
std::unique_ptr< WalletDatabase > database
Internal database handle.
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.
std::set< ScriptPubKeyMan * > GetActiveScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans in m_internal_spk_managers and m_external_spk_managers.
std::vector< std::string > GetDestValues(const std::string &prefix) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get all destination values matching a prefix.
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
bool IsLocked() const override
std::map< OutputType, ScriptPubKeyMan * > m_internal_spk_managers
std::atomic< double > m_scanning_progress
int GetVersion() const
get the current wallet format (the oldest client version guaranteed to understand this wallet)
void GetKeyBirthTimes(std::map< CKeyID, int64_t > &mapKeyBirth) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool EraseDestData(WalletBatch &batch, const CTxDestination &dest, const std::string &key) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Erases a destination data tuple in the store and on disk.
boost::signals2::signal< void(CWallet *wallet, const TxId &txid, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
bool HasEncryptionKeys() const override
CWallet(interfaces::Chain *chain, const std::string &name, std::unique_ptr< WalletDatabase > _database)
Construct wallet with specified name and database implementation.
Amount m_default_max_tx_fee
Absolute maximum transaction fee (in satoshis) used by default for the wallet.
bool UpgradeWallet(int version, bilingual_str &error)
Upgrade the wallet.
bool fBroadcastTransactions
ScriptPubKeyMan * GetScriptPubKeyMan(const OutputType &type, bool internal) const
Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
std::set< ScriptPubKeyMan * > GetAllScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans.
std::multimap< int64_t, CWalletTx * > TxItems
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.
unsigned int nMasterKeyMaxID
std::function< bool(CWalletTx &wtx, bool new_tx)> UpdateWalletTxFn
Callback for updating transaction metadata in mapWallet.
void postInitProcess()
Wallet post-init setup Gives the wallet a chance to register repetitive tasks and complete post-init ...
const CAddressBookData * FindAddressBookEntry(const CTxDestination &, bool allow_change=false) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
A transaction with a bunch of additional info that only the owner cares about.
mapValue_t mapValue
Key/value map with information about the transaction.
bool isUnconfirmed() const
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet.
bool IsEquivalentTo(const CWalletTx &tx) const
bool isConflicted() const
std::vector< std::pair< std::string, std::string > > vOrderForm
bool fFromMe
From me flag is set to 1 for transactions that were created by the wallet on this bitcoin node,...
unsigned int fTimeReceivedIsTxTime
void MarkDirty()
make sure balances are recalculated
bool m_is_cache_empty
This flag is true if all m_amounts caches are empty.
std::multimap< int64_t, CWalletTx * >::const_iterator m_it_wtxOrdered
unsigned int nTimeReceived
time received by this node
int64_t nOrderPos
position in ordered transaction list
bool HasWalletDescriptor(const WalletDescriptor &desc) const
RecursiveMutex cs_KeyStore
Different type to mark Mutex at global scope.
std::set< CKeyID > GetKeys() const override
A wrapper to reserve an address from a wallet.
bool fInternal
Whether this is from the internal (change output) keypool.
ScriptPubKeyMan * m_spk_man
The ScriptPubKeyMan to reserve from.
int64_t nIndex
The index of the address's key in the keypool.
CTxDestination address
The destination.
const CWallet *const pwallet
The wallet to reserve from.
A class implementing ScriptPubKeyMan manages some (or all) scriptPubKeys used in a wallet.
virtual bool TopUp(unsigned int size=0)
Fills internal address pool.
virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination &address, int64_t &index, CKeyPool &keypool)
virtual void KeepDestination(int64_t index, const OutputType &type)
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr)
Signature hash type wrapper class.
void push_back(UniValue val)
const std::vector< UniValue > & getValues() const
Access to the wallet database.
bool TxnCommit()
Commit current transaction.
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
bool WriteName(const CTxDestination &address, const std::string &strName)
bool WritePurpose(const CTxDestination &address, const std::string &purpose)
bool WriteMinVersion(int nVersion)
bool ErasePurpose(const CTxDestination &address)
bool EraseDestData(const CTxDestination &address, const std::string &key)
Erase destination data tuple from wallet database.
bool WriteWalletFlags(const uint64_t flags)
bool ReadBestBlock(CBlockLocator &locator)
bool WriteOrderPosNext(int64_t nOrderPosNext)
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
bool WriteTx(const CWalletTx &wtx)
bool TxnBegin()
Begin a new transaction.
bool TxnAbort()
Abort current transaction.
bool EraseName(const CTxDestination &address)
bool WriteBestBlock(const CBlockLocator &locator)
DBErrors ZapSelectTx(std::vector< TxId > &txIdsIn, std::vector< TxId > &txIdsOut)
DBErrors LoadWallet(CWallet *pwallet)
bool WriteDestData(const CTxDestination &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
Descriptor with some wallet metadata.
std::shared_ptr< Descriptor > descriptor
RAII object to check and reserve a wallet rescan.
std::string ToString() const
std::string GetHex() const
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
virtual CBlockLocator getTipLocator()=0
Get locator for the current chain tip.
virtual std::optional< int > getHeight()=0
Get current chain height, not including genesis block (returns 0 if chain only contains genesis block...
virtual BlockHash getBlockHash(int height)=0
Get block hash. Height must be valid or this function will abort.
virtual bool findBlock(const BlockHash &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
virtual std::unique_ptr< Handler > handleNotifications(std::shared_ptr< Notifications > notifications)=0
Register handler for notifications.
virtual bool updateRwSetting(const std::string &name, const util::SettingsValue &value, bool write=true)=0
Write a setting to <datadir>/settings.json.
virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock &block={})=0
Find first block in the chain with timestamp >= the given time and height >= than the given height,...
virtual bool broadcastTransaction(const Config &config, const CTransactionRef &tx, const Amount &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 util::SettingsValue getRwSetting(const std::string &name)=0
Return <datadir>/settings.json setting value.
virtual double guessVerificationProgress(const BlockHash &block_hash)=0
Estimate fraction of total transactions verified if blocks up to the specified block hash are verifie...
virtual const CChainParams & params() const =0
This Chain's parameters.
virtual bool havePruned()=0
Check if any block has been pruned.
virtual bool hasAssumedValidChain()=0
Return true if an assumed-valid chain is in use.
virtual bool findAncestorByHeight(const BlockHash &block_hash, int ancestor_height, const FoundBlock &ancestor_out={})=0
Find ancestor of block at specified height and optionally return ancestor information.
virtual void initMessage(const std::string &message)=0
Send init message.
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 bool haveBlockOnDisk(int height)=0
Check that the block is available on disk (i.e.
virtual void requestMempoolTransactions(Notifications ¬ifications)=0
Synchronously send transactionAddedToMempool notifications about all current mempool transactions to ...
virtual void waitForNotificationsIfTipChanged(const BlockHash &old_tip)=0
Wait for pending notifications to be processed unless block hash points to the current chain tip.
virtual CFeeRate relayMinFee()=0
Relay current minimum fee (from -minrelaytxfee settings).
Helper for findBlock to selectively return pieces of block data.
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
const Config & GetConfig()
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule).
const unsigned int WALLET_CRYPTO_SALT_SIZE
std::vector< uint8_t, secure_allocator< uint8_t > > CKeyingMaterial
const unsigned int WALLET_CRYPTO_KEY_SIZE
bilingual_str AmountHighWarn(const std::string &optname)
bilingual_str AmountErrMsg(const std::string &optname, const std::string &strValue)
void LockCoin(const COutPoint &output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
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 ...
size_t KeypoolCountExternalKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void KeepDestination()
Keep the address.
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::set< CTxDestination > GetLabelAddresses(const std::string &label) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool IsLockedCoin(const COutPoint &outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const
void UnlockCoin(const COutPoint &output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
OutputType TransactionChangeType(const std::optional< OutputType > &change_type, const std::vector< CRecipient > &vecSend) const
bool SignTransaction(CMutableTransaction &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void ReturnDestination()
Return reserved address.
bool GetNewChangeDestination(const OutputType type, CTxDestination &dest, std::string &error)
void UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool TopUpKeyPool(unsigned int kpSize=0)
bool SetAddressBookWithDB(WalletBatch &batch, const CTxDestination &address, const std::string &strName, const std::string &strPurpose)
TransactionError FillPSBT(PartiallySignedTransaction &psbtx, bool &complete, SigHashType sighash_type=SigHashType().withForkId(), bool sign=true, bool bip32derivs=true) const
Fills out a PSBT with information from the wallet.
bool GetReservedDestination(CTxDestination &pubkey, bool internal)
Reserve an address.
int64_t GetOldestKeyPoolTime() const
bool DelAddressBook(const CTxDestination &address)
bool GetNewDestination(const OutputType type, const std::string label, CTxDestination &dest, std::string &error)
DBErrors ZapSelectTx(std::vector< TxId > &txIdsIn, std::vector< TxId > &txIdsOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector< std::pair< std::string, std::string > > orderForm, bool broadcast=true)
Add the transaction to the wallet and maybe attempt to broadcast it.
bool AddWalletFlags(uint64_t flags)
Overwrite all flags by the given uint64_t.
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)
void blockConnected(const CBlock &block, int height) override
bool LoadToWallet(const TxId &txid, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void MarkConflicted(const BlockHash &hashBlock, int conflicting_height, const TxId &txid)
Mark a transaction (and its in-wallet descendants) as conflicting with a particular block.
void Flush()
Flush wallet (bitdb flush)
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
bool SetMaxVersion(int nVersion)
change which version we're allowed to upgrade to (note that this does not immediately imply upgrading...
std::set< TxId > GetConflicts(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get wallet transactions that conflict with given transaction (spend same outputs)
bool SubmitTxMemoryPoolAndRelay(const 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.
void AddToSpends(const COutPoint &outpoint, const TxId &wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void SyncTransaction(const CTransactionRef &tx, CWalletTx::Confirmation confirm, bool update_tx=true) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Used by TransactionAddedToMemorypool/BlockConnected/Disconnected/ScanForWalletTransactions.
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
CWalletTx * AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation &confirm, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true)
bool HasWalletSpend(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Check if a given transaction has any of its outputs spent by another transaction in the wallet.
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
void BlockUntilSyncedToCurrentChain() const LOCKS_EXCLUDED(void SetWalletFlag(uint64_t flags)
Blocks until the wallet state is up-to-date to /at least/ the current chain at the time this function...
bool IsFromMe(const CTransaction &tx) const
should probably be renamed to IsRelevantToMe
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
isminetype IsMine(const CTxDestination &dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool LoadWalletFlags(uint64_t flags)
Loads the flags into the wallet.
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)
bool CanGetAddresses(bool internal=false) const
Returns true if the wallet can give out new addresses.
ScanResult ScanForWalletTransactions(const BlockHash &start_block, int start_height, std::optional< int > max_height, const WalletRescanReserver &reserver, bool fUpdate)
Scan the block chain (starting in start_block) for transactions from or to us.
bool IsSpentKey(const TxId &txid, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool TransactionCanBeAbandoned(const TxId &txid) const
Return whether transaction can be abandoned.
const CChainParams & GetChainParams() const override
Amount GetDebit(const CTxIn &txin, const isminefilter &filter) const
Returns amount of debit if the input matches the filter, otherwise returns 0.
void MarkInputsDirty(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Mark a transaction's inputs dirty, thus forcing the outputs to be recomputed.
bool AddToWalletIfInvolvingMe(const CTransactionRef &tx, CWalletTx::Confirmation confirm, bool fUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Add a transaction to the wallet, or update it.
bool IsSpent(const COutPoint &outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Outpoint is spent if any non-conflicted transaction, spends it:
void ReacceptWalletTransactions() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void UnsetWalletFlagWithDB(WalletBatch &batch, uint64_t flag)
Unsets a wallet flag and saves it to disk.
void SyncMetaData(std::pair< TxSpends::iterator, TxSpends::iterator >) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool EncryptWallet(const SecureString &strWalletPassphrase)
void updatedBlockTip() override
void UnsetWalletFlag(uint64_t flag)
Unsets a single wallet flag.
void transactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override
bool IsWalletFlagSet(uint64_t flag) const override
Check if a certain wallet flag is set.
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver &reserver, bool update)
Scan active chain for relevant transactions after importing keys.
bool AbandonTransaction(const TxId &txid)
Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent.
void UnsetBlankWalletFlag(WalletBatch &batch) override
Unset the blank wallet flag and saves it to disk.
void SetSpentKeyState(WalletBatch &batch, const TxId &txid, unsigned int n, bool used, std::set< CTxDestination > &tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void transactionAddedToMempool(const CTransactionRef &tx, uint64_t mempool_sequence) override
DBErrors ReorderTransactions()
void blockDisconnected(const CBlock &block, int height) override
void Close()
Close wallet database.
int64_t IncOrderPosNext(WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Increment the next transaction order id.
const CWalletTx * GetWalletTx(const TxId &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void ResendWalletTransactions()
void SetMinVersion(enum WalletFeature, WalletBatch *batch_in=nullptr, bool fExplicit=false) override
signify that a particular wallet feature is now used.
std::set< TxId > GetTxConflicts(const CWalletTx &wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig=false) const
void chainStateFlushed(const CBlockLocator &loc) override
isminetype
IsMine() return codes.
bool error(const char *fmt, const Args &...args)
@ PRIVATE_KEY_NOT_AVAILABLE
bool ParseMoney(const std::string &money_string, Amount &nRet)
Parse an amount denoted in full coins.
static auto quoted(const std::string &s)
static std::string PathToString(const path &path)
Convert path object to byte string.
static path PathFromString(const std::string &string)
Convert byte string to path object.
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
std::unique_ptr< Wallet > MakeWallet(const std::shared_ptr< CWallet > &wallet)
Return implementation of Wallet interface.
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
const std::string & FormatOutputType(OutputType type)
const std::array< OutputType, 1 > OUTPUT_TYPES
std::shared_ptr< const CTransaction > CTransactionRef
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
void GetStrongRandBytes(Span< uint8_t > bytes) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
void UpdateInput(CTxIn &input, const SignatureData &data)
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
void ReplaceAll(std::string &in_out, const std::string &search, const std::string &substitute)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
static constexpr Amount zero() noexcept
A BlockHash is a unqiue identifier for a block.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
void SetSeed(Span< const std::byte > seed)
std::optional< int > last_scanned_height
BlockHash last_scanned_block
Hash and height of most recent block that was successfully scanned.
enum CWallet::ScanResult::@20 status
BlockHash last_failed_block
Hash of the most recent block that could not be scanned due to read errors or pruning.
Confirmation includes tx status and a triplet of {block height/block hash/tx index in block} at which...
SecureString create_passphrase
std::map< CKeyID, CKey > keys
A version of CTransaction with the PSBT format.
std::vector< PSBTInput > inputs
std::optional< CMutableTransaction > tx
A TxId is the identifier of a transaction.
#define WAIT_LOCK(cs, name)
#define AssertLockNotHeld(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string ShellEscape(const std::string &arg)
int64_t GetTimeMillis()
Returns the system time (not mockable)
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
bilingual_str _(const char *psz)
Translation function.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
@ BLOCK
Removed for block.
@ CONFLICT
Removed for conflict with in-block transaction.
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
std::map< std::string, std::string > mapValue_t
constexpr Amount HIGH_TX_FEE_PER_KB
Discourage users to set fees higher than this amount (in satoshis) per kB.
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
constexpr OutputType DEFAULT_ADDRESS_TYPE
Default for -addresstype.
constexpr Amount HIGH_MAX_TX_FEE
-maxtxfee will warn if called with a higher fee than this amount (in satoshis)
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE
Default for -spendzeroconfchange.
static constexpr uint64_t KNOWN_WALLET_FLAGS
static const bool DEFAULT_WALLETBROADCAST
constexpr Amount HIGH_APS_FEE
discourage APS fee higher than this amount
std::unique_ptr< interfaces::Handler > HandleLoadWallet(LoadWalletFn load_wallet)
bool RemoveWallet(const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
static void ReleaseWallet(CWallet *wallet)
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
const std::map< uint64_t, std::string > WALLET_FLAG_CAVEATS
void MaybeResendWalletTxs()
Called periodically by the schedule thread.
static std::vector< std::shared_ptr< CWallet > > vpwallets GUARDED_BY(cs_wallets)
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
static std::condition_variable g_wallet_release_cv
static GlobalMutex g_loading_wallet_mutex
RecursiveMutex cs_wallets
bool AddWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Add wallet name to persistent configuration so it will be loaded on startup.
bool RemoveWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Remove wallet name from persistent configuration so it will not be loaded on startup.
static void UpdateWalletSetting(interfaces::Chain &chain, const std::string &wallet_name, std::optional< bool > load_on_startup, std::vector< bilingual_str > &warnings)
static GlobalMutex g_wallet_release_mutex
std::shared_ptr< CWallet > GetWallet(const std::string &name)
std::vector< std::shared_ptr< CWallet > > GetWallets()
bool AddWallet(const std::shared_ptr< CWallet > &wallet)
std::shared_ptr< CWallet > LoadWallet(interfaces::Chain &chain, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
std::shared_ptr< CWallet > CreateWallet(interfaces::Chain &chain, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
DBErrors
Error statuses for the wallet database.
fs::path GetWalletDir()
Get the path of the wallet directory.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_AVOID_REUSE
@ WALLET_FLAG_KEY_ORIGIN_METADATA
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
WalletFeature
(client) version numbers for particular wallet features
@ FEATURE_PRE_SPLIT_KEYPOOL