9#include <chainparams.h>
55 "You need to rescan the blockchain in order to correctly mark used "
56 "destinations in the past. Until this is done, some destinations may "
57 "be considered unused, even if the opposite is the case."},
61 const std::string &wallet_name) {
67 if (value.isStr() && value.get_str() == wallet_name) {
76 const std::string &wallet_name) {
83 if (!value.isStr() || value.get_str() != wallet_name) {
87 if (new_value.
size() == setting_value.
size()) {
94 const std::string &wallet_name,
95 std::optional<bool> load_on_startup,
96 std::vector<bilingual_str> &warnings) {
97 if (!load_on_startup) {
101 warnings.emplace_back(
102 Untranslated(
"Wallet load on startup setting could not be updated, "
103 "so wallet may not be loaded next node startup."));
104 }
else if (!load_on_startup.value() &&
106 warnings.emplace_back(
107 Untranslated(
"Wallet load on startup setting could not be updated, "
108 "so wallet may still be loaded next node startup."));
115 std::vector<std::shared_ptr<CWallet>>::const_iterator i =
116 std::find(context.wallets.begin(), context.wallets.end(),
wallet);
117 if (i != context.wallets.end()) {
120 context.wallets.push_back(
wallet);
121 wallet->ConnectScriptPubKeyManNotifiers();
122 wallet->NotifyCanGetAddressesChanged();
127 const std::shared_ptr<CWallet> &
wallet,
128 std::optional<bool> load_on_start,
129 std::vector<bilingual_str> &warnings) {
136 wallet->m_chain_notifications_handler.reset();
139 std::vector<std::shared_ptr<CWallet>>::iterator i =
140 std::find(context.wallets.begin(), context.wallets.end(),
wallet);
141 if (i == context.wallets.end()) {
144 context.wallets.erase(i);
156 const std::shared_ptr<CWallet> &
wallet,
157 std::optional<bool> load_on_start) {
158 std::vector<bilingual_str> warnings;
164 return context.wallets;
168 const std::string &
name) {
170 for (
const std::shared_ptr<CWallet> &
wallet : context.wallets) {
178std::unique_ptr<interfaces::Handler>
181 auto it = context.wallet_load_fns.emplace(context.wallet_load_fns.end(),
182 std::move(load_wallet));
185 context.wallet_load_fns.erase(it);
190 const std::shared_ptr<CWallet> &
wallet) {
192 for (
auto &load_wallet : context.wallet_load_fns) {
200static std::set<std::string>
202static std::set<std::string>
208 wallet->WalletLogPrintf(
"Releasing wallet %s..\n",
name);
214 if (g_unloading_wallet_set.erase(
name) == 0) {
227 g_unloading_wallet_set.insert(
name);
236 while (g_unloading_wallet_set.count(
name) == 1) {
243std::shared_ptr<CWallet>
245 std::optional<bool> load_on_start,
247 bilingual_str &error, std::vector<bilingual_str> &warnings) {
249 std::unique_ptr<WalletDatabase> database =
252 error =
Untranslated(
"Wallet file verification failed.") +
258 std::shared_ptr<CWallet>
wallet =
270 wallet->postInitProcess();
276 }
catch (
const std::runtime_error &e) {
284std::shared_ptr<CWallet>
288 std::vector<bilingual_str> &warnings) {
290 return g_loading_wallet_set.insert(
name));
291 if (!result.second) {
296 auto wallet = LoadWalletInternal(context,
name, load_on_start, options,
297 status, error, warnings);
302std::shared_ptr<CWallet>
306 std::vector<bilingual_str> &warnings) {
315 if (!passphrase.empty()) {
321 std::unique_ptr<WalletDatabase> database =
324 error =
Untranslated(
"Wallet file verification failed.") +
331 if (!passphrase.empty() &&
334 "Passphrase provided but private keys are disabled. A passphrase "
335 "is only used to encrypt private keys, so cannot be used for "
336 "wallets with private keys disabled.");
343 std::shared_ptr<CWallet>
wallet =
345 wallet_creation_flags, error, warnings);
354 if (!passphrase.empty() &&
356 if (!
wallet->EncryptWallet(passphrase)) {
358 Untranslated(
"Error: Wallet created but failed to encrypt.");
364 if (!
wallet->Unlock(passphrase)) {
366 "Error: Wallet was encrypted but could not be unlocked");
375 wallet->SetupDescriptorScriptPubKeyMans();
377 for (
auto spk_man :
wallet->GetActiveScriptPubKeyMans()) {
378 if (!spk_man->SetupGeneration()) {
395 wallet->postInitProcess();
404std::shared_ptr<CWallet>
406 const std::string &wallet_name, std::optional<bool> load_on_start,
408 std::vector<bilingual_str> &warnings) {
414 auto wallet_file = wallet_path /
"wallet.dat";
415 std::shared_ptr<CWallet>
wallet;
426 "Failed to create database path '%s'. Database already exists.",
432 fs::copy_file(backup_file, wallet_file, fs::copy_options::none);
435 status, error, warnings);
436 }
catch (
const std::exception &e) {
438 if (!error.
empty()) {
444 fs::remove_all(wallet_path);
463 std::map<TxId, CWalletTx>::const_iterator it = mapWallet.find(txid);
464 if (it == mapWallet.end()) {
468 return &(it->second);
481 spk_man->UpgradeKeyMetadata();
486 bool accept_no_keys) {
492 for (
const MasterKeyMap::value_type &pMasterKey :
mapMasterKeys) {
494 strWalletPassphrase, pMasterKey.second.vchSalt,
495 pMasterKey.second.nDeriveIterations,
496 pMasterKey.second.nDerivationMethod)) {
499 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey,
504 if (
Unlock(_vMasterKey, accept_no_keys)) {
527 strOldWalletPassphrase, pMasterKey.second.vchSalt,
528 pMasterKey.second.nDeriveIterations,
529 pMasterKey.second.nDerivationMethod)) {
533 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey)) {
537 if (
Unlock(_vMasterKey)) {
539 auto start{SteadyClock::now()};
541 pMasterKey.second.vchSalt,
542 pMasterKey.second.nDeriveIterations,
543 pMasterKey.second.nDerivationMethod);
544 pMasterKey.second.nDeriveIterations =
static_cast<unsigned int>(
545 pMasterKey.second.nDeriveIterations * target /
546 (SteadyClock::now() - start));
548 start = SteadyClock::now();
550 pMasterKey.second.vchSalt,
551 pMasterKey.second.nDeriveIterations,
552 pMasterKey.second.nDerivationMethod);
553 pMasterKey.second.nDeriveIterations =
554 (pMasterKey.second.nDeriveIterations +
555 static_cast<unsigned int>(pMasterKey.second.nDeriveIterations *
557 (SteadyClock::now() - start))) /
560 if (pMasterKey.second.nDeriveIterations < 25000) {
561 pMasterKey.second.nDeriveIterations = 25000;
565 "Wallet passphrase changed to an nDeriveIterations of %i\n",
566 pMasterKey.second.nDeriveIterations);
569 strNewWalletPassphrase, pMasterKey.second.vchSalt,
570 pMasterKey.second.nDeriveIterations,
571 pMasterKey.second.nDerivationMethod)) {
575 if (!crypter.
Encrypt(_vMasterKey,
576 pMasterKey.second.vchCryptedKey)) {
606 if (nWalletVersion >= nVersion) {
612 if (fExplicit && nVersion > nWalletMaxVersion) {
616 nWalletVersion = nVersion;
618 if (nVersion > nWalletMaxVersion) {
619 nWalletMaxVersion = nVersion;
623 if (nWalletVersion > 40000) {
635 if (nWalletVersion > nVersion) {
639 nWalletMaxVersion = nVersion;
645 std::set<TxId> result;
648 std::map<TxId, CWalletTx>::const_iterator it = mapWallet.find(txid);
649 if (it == mapWallet.end()) {
655 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
657 for (
const CTxIn &txin : wtx.
tx->vin) {
658 if (mapTxSpends.count(txin.prevout) <= 1) {
663 range = mapTxSpends.equal_range(txin.prevout);
664 for (TxSpends::const_iterator _it = range.first; _it != range.second;
666 result.insert(_it->second);
675 auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
676 return (iter != mapTxSpends.end() && iter->first.GetTxId() == txid);
688 std::pair<TxSpends::iterator, TxSpends::iterator> range) {
693 int nMinOrderPos = std::numeric_limits<int>::max();
695 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
696 const CWalletTx *wtx = &mapWallet.at(it->second);
708 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
709 const TxId &txid = it->second;
711 if (copyFrom == copyTo) {
717 "Oldest wallet transaction in range assumed to have been found.");
739 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range =
740 mapTxSpends.equal_range(outpoint);
742 for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
743 const TxId &wtxid = it->second;
744 std::map<TxId, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
745 if (mit != mapWallet.end()) {
747 if (depth > 0 || (depth == 0 && !mit->second.isAbandoned())) {
758 mapTxSpends.insert(std::make_pair(outpoint, wtxid));
760 setLockedCoins.erase(outpoint);
762 std::pair<TxSpends::iterator, TxSpends::iterator> range;
763 range = mapTxSpends.equal_range(outpoint);
768 auto it = mapWallet.find(wtxid);
769 assert(it != mapWallet.end());
776 for (
const CTxIn &txin : thisTx.
tx->vin) {
798 auto start{SteadyClock::now()};
802 25000 * target / (SteadyClock::now() - start));
804 start = SteadyClock::now();
811 (SteadyClock::now() - start))) /
836 delete encrypted_batch;
837 encrypted_batch =
nullptr;
843 auto spk_man = spk_man_pair.second.get();
844 if (!spk_man->Encrypt(_vMasterKey, encrypted_batch)) {
846 delete encrypted_batch;
847 encrypted_batch =
nullptr;
859 delete encrypted_batch;
860 encrypted_batch =
nullptr;
867 delete encrypted_batch;
868 encrypted_batch =
nullptr;
871 Unlock(strWalletPassphrase);
879 if (spk_man->IsHDEnabled()) {
880 if (!spk_man->SetupGeneration(
true)) {
913 for (
auto &entry : mapWallet) {
919 std::vector<int64_t> nOrderPosOffsets;
920 for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) {
924 if (nOrderPos == -1) {
925 nOrderPos = nOrderPosNext++;
926 nOrderPosOffsets.push_back(nOrderPos);
932 int64_t nOrderPosOff = 0;
933 for (
const int64_t &nOffsetStart : nOrderPosOffsets) {
934 if (nOrderPos >= nOffsetStart) {
939 nOrderPos += nOrderPosOff;
940 nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
960 int64_t nRet = nOrderPosNext++;
972 for (std::pair<const TxId, CWalletTx> &item : mapWallet) {
973 item.second.MarkDirty();
978 unsigned int n,
bool used,
979 std::set<CTxDestination> &tx_destinations) {
992 tx_destinations.insert(dst);
994 }
else if (!used &&
GetDestData(dst,
"used",
nullptr)) {
1005 assert(srctx->
tx->vout.size() > n);
1015 assert(spk_man !=
nullptr);
1016 for (
const auto &keyid :
1031 bool fFlushOnClose) {
1036 const TxId &txid = tx->GetId();
1040 std::set<CTxDestination> tx_destinations;
1042 for (
const CTxIn &txin : tx->vin) {
1043 const COutPoint &op = txin.prevout;
1053 mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid),
1054 std::forward_as_tuple(tx));
1056 bool fInsertedNew = ret.second;
1057 bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew);
1068 if (!fInsertedNew) {
1084 (fInsertedNew ?
"new" :
""), (fUpdated ?
"update" :
""));
1087 if ((fInsertedNew || fUpdated) && !batch.
WriteTx(wtx)) {
1097#if defined(HAVE_SYSTEM)
1100 std::string strCmd =
gArgs.
GetArg(
"-walletnotify",
"");
1102 if (!strCmd.empty()) {
1104 if (confirm.
status == CWalletTx::Status::CONFIRMED) {
1120 std::thread t(runCommand, strCmd);
1131 mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid),
1132 std::forward_as_tuple(
nullptr));
1134 if (!fill_wtx(wtx, ins.second)) {
1142 if (
chain().findBlock(
1144 FoundBlock().inActiveChain(active).height(height)) &&
1167 for (
const CTxIn &txin : wtx.
tx->vin) {
1168 auto it = mapWallet.find(txin.prevout.GetTxId());
1169 if (it != mapWallet.end()) {
1185 const TxId &txid = ptx->GetId();
1188 for (
const CTxIn &txin : ptx->vin) {
1189 std::pair<TxSpends::const_iterator, TxSpends::const_iterator>
1190 range = mapTxSpends.equal_range(txin.prevout);
1191 while (range.first != range.second) {
1192 if (range.first->second != txid) {
1194 "Transaction %s (in block %s) conflicts with wallet "
1195 "transaction %s (both spend %s:%i)\n",
1197 range.first->second.ToString(),
1198 range.first->first.GetTxId().ToString(),
1199 range.first->first.GetN());
1201 range.first->second);
1208 bool fExisted = mapWallet.count(txid) != 0;
1209 if (fExisted && !fUpdate) {
1222 for (
const CTxOut &txout : ptx->vout) {
1224 spk_man_pair.second->MarkUnusedAddresses(txout.
scriptPubKey);
1245 for (
const CTxIn &txin : tx->vin) {
1246 auto it = mapWallet.find(txin.prevout.GetTxId());
1247 if (it != mapWallet.end()) {
1248 it->second.MarkDirty();
1258 std::set<TxId> todo;
1259 std::set<TxId> done;
1262 auto it = mapWallet.find(txid);
1263 assert(it != mapWallet.end());
1271 while (!todo.empty()) {
1275 it = mapWallet.find(now);
1276 assert(it != mapWallet.end());
1280 assert(currentconfirm <= 0);
1293 TxSpends::const_iterator iter =
1294 mapTxSpends.lower_bound(COutPoint(now, 0));
1295 while (iter != mapTxSpends.end() && iter->first.GetTxId() == now) {
1296 if (!done.count(iter->second)) {
1297 todo.insert(iter->second);
1316 int conflictconfirms =
1317 (m_last_block_processed_height - conflicting_height + 1) * -1;
1322 if (conflictconfirms >= 0) {
1329 std::set<TxId> todo;
1330 std::set<TxId> done;
1334 while (!todo.empty()) {
1338 auto it = mapWallet.find(now);
1339 assert(it != mapWallet.end());
1342 if (conflictconfirms < currentconfirm) {
1353 TxSpends::const_iterator iter =
1354 mapTxSpends.lower_bound(COutPoint(now, 0));
1355 while (iter != mapTxSpends.end() && iter->first.GetTxId() == now) {
1356 if (!done.count(iter->second)) {
1357 todo.insert(iter->second);
1383 uint64_t mempool_sequence) {
1389 auto it = mapWallet.find(tx->GetId());
1390 if (it != mapWallet.end()) {
1391 it->second.fInMempool =
true;
1397 uint64_t mempool_sequence) {
1399 auto it = mapWallet.find(tx->GetId());
1400 if (it != mapWallet.end()) {
1401 it->second.fInMempool =
false;
1432 {CWalletTx::Status::UNCONFIRMED, 0,
1445 m_last_block_processed_height = height;
1446 m_last_block_processed = block_hash;
1447 for (
size_t index = 0; index < block.
vtx.size(); index++) {
1449 block_hash, int(index)});
1464 m_last_block_processed_height = height - 1;
1468 {CWalletTx::Status::UNCONFIRMED, 0,
1477void CWallet::BlockUntilSyncedToCurrentChain()
const {
1492 std::map<TxId, CWalletTx>::const_iterator mi =
1493 mapWallet.find(txin.prevout.GetTxId());
1494 if (mi != mapWallet.end()) {
1496 if (txin.prevout.GetN() < prev.
tx->vout.size()) {
1497 if (
IsMine(prev.
tx->vout[txin.prevout.GetN()]) & filter) {
1498 return prev.
tx->vout[txin.prevout.GetN()].nValue;
1520 result = std::max(result, spk_man_pair.second->IsMine(
script));
1527 for (
const CTxOut &txout : tx.vout) {
1543 for (
const CTxIn &txin : tx.vin) {
1546 throw std::runtime_error(std::string(__func__) +
1547 ": value out of range");
1558 result &= spk_man->IsHDEnabled();
1570 if (spk_man && spk_man->CanGetAddresses(internal)) {
1581 throw std::runtime_error(std::string(__func__) +
1582 ": writing wallet flags failed");
1595 throw std::runtime_error(std::string(__func__) +
1596 ": writing wallet flags failed");
1624 throw std::runtime_error(std::string(__func__) +
1625 ": writing wallet flags failed");
1634 bool use_max_sig)
const {
1639 std::unique_ptr<SigningProvider> provider =
1649 scriptPubKey, sigdata)) {
1660 const std::vector<CTxOut> &txouts,
1661 bool use_max_sig)
const {
1664 for (
const auto &txout : txouts) {
1675 int64_t timestamp) {
1680 LOCK(spk_man->cs_KeyStore);
1681 return spk_man->ImportScripts(scripts, timestamp);
1685 const int64_t timestamp) {
1690 LOCK(spk_man->cs_KeyStore);
1691 return spk_man->ImportPrivKeys(privkey_map, timestamp);
1695 const std::vector<CKeyID> &ordered_pubkeys,
1696 const std::map<CKeyID, CPubKey> &pubkey_map,
1697 const std::map<
CKeyID, std::pair<CPubKey, KeyOriginInfo>> &key_origins,
1698 const bool add_keypool,
const bool internal,
const int64_t timestamp) {
1703 LOCK(spk_man->cs_KeyStore);
1704 return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins,
1705 add_keypool, internal, timestamp);
1709 const std::set<CScript> &script_pub_keys,
1710 const bool have_solving_data,
1711 const bool apply_label,
1712 const int64_t timestamp) {
1717 LOCK(spk_man->cs_KeyStore);
1718 if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data,
1724 for (
const CScript &
script : script_pub_keys) {
1749 int start_height = 0;
1753 FoundBlock().hash(start_block).height(start_height));
1762 start_block, start_height, {} , reserver, update);
1795 const BlockHash &start_block,
int start_height,
1822 double progress_current = progress_begin;
1823 int block_height = start_height;
1825 if (progress_end - progress_begin > 0.0) {
1827 (progress_end - progress_begin);
1833 if (block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
1835 strprintf(
"%s " +
_(
"Rescanning...").translated,
1842 block_height, progress_current);
1851 bool block_still_active =
false;
1852 bool next_block =
false;
1856 .inActiveChain(block_still_active)
1858 .inActiveChain(next_block)
1859 .hash(next_block_hash)));
1863 if (!block_still_active) {
1870 for (
size_t posInBlock = 0; posInBlock < block.
vtx.size();
1873 block_height, block_hash,
1876 {CWalletTx::Status::CONFIRMED, block_height,
1877 block_hash, int(posInBlock)},
1890 if (max_height && block_height >= *max_height) {
1901 block_hash = next_block_hash;
1906 const BlockHash prev_tip_hash = tip_hash;
1908 if (!max_height && prev_tip_hash != tip_hash) {
1921 block_height, progress_current);
1923 }
else if (block_height &&
chain().shutdownRequested()) {
1925 "Rescan interrupted by shutdown request at block %d. Progress=%f\n",
1926 block_height, progress_current);
1944 std::map<int64_t, CWalletTx *> mapSorted;
1948 for (std::pair<const TxId, CWalletTx> &item : mapWallet) {
1949 const TxId &wtxid = item.first;
1956 mapSorted.insert(std::make_pair(wtx.
nOrderPos, &wtx));
1961 for (
const std::pair<const int64_t, CWalletTx *> &item : mapSorted) {
1963 std::string unused_err_string;
1969 std::string &err_string,
2012 std::set<TxId> result;
2032 if (!
chain().isReadyToBroadcast()) {
2050 int submitted_tx_count = 0;
2056 for (std::pair<const TxId, CWalletTx> &item : mapWallet) {
2064 std::string unused_err_string;
2066 ++submitted_tx_count;
2071 if (submitted_tx_count > 0) {
2072 WalletLogPrintf(
"%s: resubmit %u unconfirmed transactions\n", __func__,
2073 submitted_tx_count);
2080 for (
const std::shared_ptr<CWallet> &pwallet :
GetWallets(context)) {
2081 pwallet->ResendWalletTransactions();
2095 std::map<COutPoint, Coin> coins;
2096 for (
auto &input : tx.
vin) {
2097 auto mi = mapWallet.find(input.prevout.GetTxId());
2098 if (mi == mapWallet.end() ||
2099 input.prevout.GetN() >= mi->second.tx->vout.size()) {
2103 coins[input.prevout] =
2107 std::map<int, std::string> input_errors;
2112 const std::map<COutPoint, Coin> &coins,
2114 std::map<int, std::string> &input_errors)
const {
2119 if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2130 if (legacy_spk_man &&
2131 legacy_spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2142 bool finalize)
const {
2145 for (
size_t i = 0; i < psbtx.
tx->vin.size(); ++i) {
2146 const CTxIn &txin = psbtx.
tx->vin[i];
2155 const TxId &txid = txin.prevout.GetTxId();
2156 const auto it = mapWallet.find(txid);
2157 if (it != mapWallet.end()) {
2159 if (txin.prevout.GetN() >= wtx.
tx->vout.size()) {
2160 return PSBTError::MISSING_INPUTS;
2163 input.
utxo = wtx.
tx->vout[txin.prevout.GetN()];
2170 const auto error{spk_man->FillPSBT(psbtx, sighash_type, sign,
2171 bip32derivs, finalize)};
2179 for (
const auto &input : psbtx.
inputs) {
2188 std::string &str_sig)
const {
2192 if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
2195 return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
2203 const std::vector<CRecipient> &vecSend)
const {
2206 return *change_type;
2220 std::vector<std::pair<std::string, std::string>> orderForm,
2231 wtx.
mapValue = std::move(mapValue);
2239 for (
const CTxIn &txin : tx->vin) {
2240 CWalletTx &coin = mapWallet.at(txin.prevout.GetTxId());
2247 CWalletTx &wtx = mapWallet.at(tx->GetId());
2255 std::string err_string;
2257 WalletLogPrintf(
"CommitTransaction(): Transaction cannot be broadcast "
2258 "immediately, %s\n",
2270 if (
database->Rewrite(
"\x04pool")) {
2272 spk_man_pair.second->RewriteDB();
2283 return nLoadWalletRet;
2290 std::vector<TxId> &txIdsOut) {
2294 for (
const TxId &txid : txIdsOut) {
2295 const auto &it = mapWallet.find(txid);
2296 wtxOrdered.erase(it->second.m_it_wtxOrdered);
2297 for (
const auto &txin : it->second.tx->vin) {
2298 mapTxSpends.erase(txin.prevout);
2300 mapWallet.erase(it);
2305 if (
database->Rewrite(
"\x04pool")) {
2307 spk_man_pair.second->RewriteDB();
2313 return nZapSelectTxRet;
2323 const std::string &strName,
2324 const std::string &strPurpose) {
2325 bool fUpdated =
false;
2329 std::map<CTxDestination, CAddressBookData>::iterator mi =
2330 m_address_book.find(address);
2331 fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
2332 m_address_book[address].SetLabel(strName);
2334 if (!strPurpose.empty()) {
2335 m_address_book[address].purpose = strPurpose;
2342 if (!strPurpose.empty() && !batch.
WritePurpose(address, strPurpose)) {
2345 return batch.
WriteName(address, strName);
2349 const std::string &strName,
2350 const std::string &strPurpose) {
2369 "%s called with IsMine address, NOT SUPPORTED. Please "
2370 "report this bug! %s\n",
2371 __func__, PACKAGE_BUGREPORT);
2375 for (
const std::pair<const std::string, std::string> &item :
2376 m_address_book[address].destdata) {
2379 m_address_book.erase(address);
2392 unsigned int count = 0;
2394 count += spk_man->KeypoolCountExternalKeys();
2403 unsigned int count = 0;
2405 count += spk_man->GetKeyPoolSize();
2414 res &= spk_man->TopUp(kpSize);
2428 auto op_dest = spk_man->GetNewDestination(type);
2444 _(
"Error: Keypool ran out, please call keypoolrefill first")};
2453 int64_t oldestKey = std::numeric_limits<int64_t>::max();
2456 std::min(oldestKey, spk_man_pair.second->GetOldestKeyPoolTime());
2462 const std::set<CTxDestination> &destinations) {
2463 for (
auto &entry : mapWallet) {
2469 for (
size_t i = 0; i < wtx.
tx->vout.size(); i++) {
2473 destinations.count(dst)) {
2481std::set<CTxDestination>
2484 std::set<CTxDestination> result;
2485 for (
const std::pair<const CTxDestination, CAddressBookData> &item :
2487 if (item.second.IsChange()) {
2491 const std::string &strName = item.second.GetLabel();
2492 if (strName == label) {
2493 result.insert(address);
2540 setLockedCoins.insert(output);
2545 setLockedCoins.erase(output);
2550 setLockedCoins.clear();
2556 return setLockedCoins.count(outpoint) > 0;
2561 for (COutPoint outpoint : setLockedCoins) {
2562 vOutpts.push_back(outpoint);
2570 mapKeyBirth.clear();
2573 std::map<CKeyID, const CWalletTx::Confirmation *> mapKeyFirstBlock;
2584 assert(spk_man !=
nullptr);
2588 for (
const auto &entry : spk_man->mapKeyMetadata) {
2589 if (entry.second.nCreateTime) {
2590 mapKeyBirth[entry.first] = entry.second.nCreateTime;
2596 if (mapKeyBirth.count(keyid) == 0) {
2597 mapKeyFirstBlock[keyid] = &max_confirm;
2602 if (mapKeyFirstBlock.empty()) {
2607 for (
const auto &entry : mapWallet) {
2612 for (
const CTxOut &txout : wtx.
tx->vout) {
2614 for (
const auto &keyid :
2617 auto rit = mapKeyFirstBlock.find(keyid);
2618 if (rit != mapKeyFirstBlock.end() &&
2620 rit->second->block_height) {
2630 for (
const auto &entry : mapKeyFirstBlock) {
2667 int64_t latestEntry = 0;
2671 int64_t latestTolerated = latestNow + 300;
2673 for (
auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
2683 if (nSmartTime <= latestTolerated) {
2684 latestEntry = nSmartTime;
2685 if (nSmartTime > latestNow) {
2686 latestNow = nSmartTime;
2692 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
2703 const std::string &key,
const std::string &value) {
2704 if (std::get_if<CNoDestination>(&dest)) {
2708 m_address_book[dest].destdata.insert(std::make_pair(key, value));
2713 const std::string &key) {
2714 if (!m_address_book[dest].destdata.erase(key)) {
2722 const std::string &value) {
2723 m_address_book[dest].destdata.insert(std::make_pair(key, value));
2727 std::string *value)
const {
2728 std::map<CTxDestination, CAddressBookData>::const_iterator i =
2729 m_address_book.find(dest);
2730 if (i != m_address_book.end()) {
2731 CAddressBookData::StringMap::const_iterator j =
2732 i->second.destdata.find(key);
2733 if (j != i->second.destdata.end()) {
2744std::vector<std::string>
2746 std::vector<std::string> values;
2747 for (
const auto &address : m_address_book) {
2748 for (
const auto &data : address.second.destdata) {
2750 values.emplace_back(data.second);
2757std::unique_ptr<WalletDatabase>
2768 fs::file_type path_type = fs::symlink_status(wallet_path).type();
2769 if (!(path_type == fs::file_type::not_found ||
2770 path_type == fs::file_type::directory ||
2771 (path_type == fs::file_type::symlink &&
2772 fs::is_directory(wallet_path)) ||
2773 (path_type == fs::file_type::regular &&
2776 strprintf(
"Invalid -wallet path '%s'. -wallet path should point to "
2777 "a directory where wallet.dat and "
2778 "database/log.?????????? files can be stored, a location "
2779 "where such a directory could be created, "
2780 "or (for backwards compatibility) the name of an "
2781 "existing data file in -walletdir (%s)",
2786 return MakeDatabase(wallet_path, options, status, error_string);
2789std::shared_ptr<CWallet>
2791 std::unique_ptr<WalletDatabase> database,
2793 std::vector<bilingual_str> &warnings) {
2795 const std::string &walletFile =
database->Filename();
2800 std::shared_ptr<CWallet> walletInstance(
2802 DBErrors nLoadWalletRet = walletInstance->LoadWallet();
2806 strprintf(
_(
"Error loading %s: Wallet corrupted"), walletFile);
2812 strprintf(
_(
"Error reading %s! All keys read correctly, but "
2813 "transaction data or address book entries might be "
2814 "missing or incorrect."),
2818 _(
"Error loading %s: Wallet requires newer version of %s"),
2819 walletFile, PACKAGE_NAME);
2823 _(
"Wallet needed to be rewritten: restart %s to complete"),
2827 error =
strprintf(
_(
"Error loading %s"), walletFile);
2834 const bool fFirstRun =
2835 walletInstance->m_spk_managers.empty() &&
2843 walletInstance->AddWalletFlags(wallet_creation_flags);
2847 walletInstance->SetupLegacyScriptPubKeyMan();
2850 if (!(wallet_creation_flags &
2852 LOCK(walletInstance->cs_wallet);
2854 walletInstance->SetupDescriptorScriptPubKeyMans();
2860 walletInstance->GetActiveScriptPubKeyMans()) {
2861 if (!spk_man->SetupGeneration()) {
2862 error =
_(
"Unable to generate initial keys");
2875 error =
strprintf(
_(
"Error loading %s: Private keys can only be "
2876 "disabled during creation"),
2879 }
else if (walletInstance->IsWalletFlagSet(
2881 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
2882 if (spk_man->HavePrivateKeys()) {
2884 strprintf(
_(
"Warning: Private keys detected in wallet {%s} "
2885 "with disabled private keys"),
2900 _(
"This is the minimum transaction fee you pay "
2901 "on every transaction."));
2903 walletInstance->m_min_fee =
CFeeRate(n);
2907 const std::string max_aps_fee{
gArgs.
GetArg(
"-maxapsfee",
"")};
2909 if (max_aps_fee ==
"-1") {
2918 _(
"This is the maximum transaction fee you pay (in addition to"
2919 " the normal fee) to prioritize partial spend avoidance over"
2920 " regular coin selection."));
2922 walletInstance->m_max_aps_fee = n;
2929 strprintf(
_(
"Invalid amount for -fallbackfee=<amount>: '%s'"),
2936 _(
"This is the transaction fee you may pay when "
2937 "fee estimates are not available."));
2939 walletInstance->m_fallback_fee =
CFeeRate(nFeePerK);
2942 walletInstance->m_allow_fallback_fee =
2943 walletInstance->m_fallback_fee.GetFeePerK() !=
Amount::zero();
2953 _(
"This is the transaction fee you will pay if "
2954 "you send a transaction."));
2956 walletInstance->m_pay_tx_fee =
CFeeRate(nFeePerK, 1000);
2958 error =
strprintf(
_(
"Invalid amount for -paytxfee=<amount>: '%s' "
2959 "(must be at least %s)"),
2973 warnings.push_back(
_(
"-maxtxfee is set very high! Fees this large "
2974 "could be paid on a single transaction."));
2978 _(
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at "
2979 "least the minrelay fee of %s to prevent stuck "
2984 walletInstance->m_default_max_tx_fee = nMaxFee;
2990 _(
"The wallet will avoid paying less than the minimum relay fee."));
2993 walletInstance->m_spend_zero_conf_change =
2998 walletInstance->WalletLogPrintf(
"Wallet completed loading in %15dms\n",
3002 walletInstance->TopUpKeyPool();
3006 walletInstance->m_chain_notifications_handler.reset();
3011 LOCK(walletInstance->cs_wallet);
3012 walletInstance->SetBroadcastTransactions(
3014 walletInstance->WalletLogPrintf(
"setKeyPool.size() = %u\n",
3015 walletInstance->GetKeyPoolSize());
3016 walletInstance->WalletLogPrintf(
"mapWallet.size() = %u\n",
3017 walletInstance->mapWallet.size());
3018 walletInstance->WalletLogPrintf(
"m_address_book.size() = %u\n",
3019 walletInstance->m_address_book.size());
3022 return walletInstance;
3027 std::vector<bilingual_str> &warnings) {
3028 LOCK(walletInstance->cs_wallet);
3031 assert(!walletInstance->m_chain || walletInstance->m_chain == &
chain);
3032 walletInstance->m_chain = &
chain;
3046 walletInstance->m_attaching_chain =
true;
3047 walletInstance->m_chain_notifications_handler =
3050 int rescan_height = 0;
3055 if (
const std::optional<int> fork_height =
3057 rescan_height = *fork_height;
3064 walletInstance->m_last_block_processed =
3066 walletInstance->m_last_block_processed_height = *tip_height;
3068 walletInstance->m_last_block_processed.
SetNull();
3069 walletInstance->m_last_block_processed_height = -1;
3072 if (tip_height && *tip_height != rescan_height) {
3077 int block_height = *tip_height;
3078 while (block_height > 0 &&
3080 rescan_height != block_height) {
3084 if (rescan_height != block_height) {
3097 ?
_(
"Prune: last wallet synchronisation goes beyond "
3098 "pruned data. You need to -reindex (download the "
3099 "whole blockchain again in case of pruned node)")
3100 :
strprintf(
_(
"Error loading wallet. Wallet requires "
3101 "blocks to be downloaded, "
3102 "and software does not currently support "
3103 "loading wallets while "
3104 "blocks are being downloaded out of "
3105 "order when using assumeutxo "
3106 "snapshots. Wallet should be able to "
3107 "load successfully after "
3108 "node sync reaches height %s"),
3115 walletInstance->WalletLogPrintf(
3116 "Rescanning last %i blocks (from block %i)...\n",
3117 *tip_height - rescan_height, rescan_height);
3121 std::optional<int64_t> time_first_key;
3122 for (
auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
3123 int64_t time = spk_man->GetTimeFirstKey();
3124 if (!time_first_key || time < *time_first_key) {
3125 time_first_key = time;
3128 if (time_first_key) {
3139 ->ScanForWalletTransactions(
3141 {} , reserver,
true )
3143 error =
_(
"Failed to rescan the wallet during initialization");
3148 walletInstance->m_attaching_chain =
false;
3151 walletInstance->database->IncrementUpdateCounter();
3153 walletInstance->m_attaching_chain =
false;
3160 bool allow_change)
const {
3161 const auto &address_book_it = m_address_book.find(dest);
3162 if (address_book_it == m_address_book.end()) {
3165 if ((!allow_change) && address_book_it->second.IsChange()) {
3168 return &address_book_it->second;
3173 int nMaxVersion = version;
3175 if (nMaxVersion == 0) {
3185 error =
_(
"Cannot downgrade wallet");
3199 error =
_(
"Cannot upgrade a non HD split wallet without upgrading to "
3200 "support pre split keypool. Please use version 200300 or no "
3201 "version specified.");
3206 if (!spk_man->Upgrade(prev_version, error)) {
3269 assert(chain_depth >= 0);
3289 return vMasterKey.empty();
3299 if (!vMasterKey.empty()) {
3302 sizeof(
decltype(vMasterKey)::value_type));
3315 if (!spk_man_pair.second->CheckDecryptionKey(vMasterKeyIn,
3320 vMasterKey = vMasterKeyIn;
3327 std::set<ScriptPubKeyMan *> spk_mans;
3328 for (
bool internal : {
false,
true}) {
3332 spk_mans.insert(spk_man);
3340 std::set<ScriptPubKeyMan *> spk_mans;
3342 spk_mans.insert(spk_man_pair.second.get());
3348 bool internal)
const {
3349 const std::map<OutputType, ScriptPubKeyMan *> &spk_managers =
3351 std::map<OutputType, ScriptPubKeyMan *>::const_iterator it =
3352 spk_managers.find(type);
3353 if (it == spk_managers.end()) {
3355 "%s scriptPubKey Manager for output type %d does not exist\n",
3356 internal ?
"Internal" :
"External",
static_cast<int>(type));
3362std::set<ScriptPubKeyMan *>
3365 std::set<ScriptPubKeyMan *> spk_mans;
3367 if (spk_man_pair.second->CanProvide(
script, sigdata)) {
3368 spk_mans.insert(spk_man_pair.second.get());
3377 if (spk_man_pair.second->CanProvide(
script, sigdata)) {
3378 return spk_man_pair.second.get();
3391std::unique_ptr<SigningProvider>
3397std::unique_ptr<SigningProvider>
3401 if (spk_man_pair.second->CanProvide(
script, sigdata)) {
3402 return spk_man_pair.second->GetSolvingProvider(
script);
3445 return cb(vMasterKey);
3455 spk_man->NotifyCanGetAddressesChanged.connect(
3462 auto spk_manager = std::unique_ptr<ScriptPubKeyMan>(
3480 for (
bool internal : {
false,
true}) {
3483 std::make_unique<DescriptorScriptPubKeyMan>(*
this, internal);
3486 throw std::runtime_error(
3487 std::string(__func__) +
3488 ": Wallet is locked, cannot setup new descriptors");
3490 if (!spk_manager->CheckDecryptionKey(vMasterKey) &&
3491 !spk_manager->Encrypt(vMasterKey,
nullptr)) {
3492 throw std::runtime_error(
3493 std::string(__func__) +
3494 ": Could not encrypt new descriptors");
3497 spk_manager->SetupDescriptorGeneration(master_key, t);
3498 uint256 id = spk_manager->GetID();
3510 throw std::runtime_error(std::string(__func__) +
3511 ": writing active ScriptPubKeyMan id failed");
3525 "Setting spkMan to active: id = %s, type = %d, internal = %d\n",
3526 id.
ToString(),
static_cast<int>(type),
static_cast<int>(internal));
3529 auto &spk_mans_other =
3532 spk_man->SetInternal(internal);
3533 spk_mans[type] = spk_man;
3535 const auto it = spk_mans_other.find(type);
3536 if (it != spk_mans_other.end() && it->second == spk_man) {
3537 spk_mans_other.erase(type);
3546 if (spk_man !=
nullptr && spk_man->GetID() ==
id) {
3548 "Deactivate spkMan: id = %s, type = %d, internal = %d\n",
3549 id.
ToString(),
static_cast<int>(type),
static_cast<int>(internal));
3553 throw std::runtime_error(
3554 std::string(__func__) +
3555 ": erasing active ScriptPubKeyMan id failed");
3560 spk_mans.erase(type);
3572 return spk_man !=
nullptr;
3582 spk_man_pair.second.get());
3594 const std::string &label,
bool internal) {
3599 "Cannot add WalletDescriptor to a non-descriptor wallet\n");
3607 spk_man->UpdateWalletDescriptor(desc);
3610 std::make_unique<DescriptorScriptPubKeyMan>(*
this, desc);
3611 spk_man = new_spk_man.get();
3618 for (
const auto &entry : signing_provider.
keys) {
3619 const CKey &key = entry.second;
3620 spk_man->AddDescriptorKey(key, key.
GetPubKey());
3624 if (!spk_man->TopUp()) {
3632 auto script_pub_keys = spk_man->GetScriptPubKeys();
3633 if (script_pub_keys.empty()) {
3635 "Could not generate scriptPubKeys (cache is empty)\n");
3646 spk_man->WriteDescriptor();
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.
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 virtualbyte: Amount / vB the feerate is represented internally as FeeFrac.
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.
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.
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.
std::atomic< bool > m_attaching_chain
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.
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)
Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error.
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
std::string GetDisplayName() const override
Returns a bracketed wallet name for displaying in logs, will return [default wallet] if the wallet ha...
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
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
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.
constexpr bool IsNull() const
constexpr uint8_t * begin()
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
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.
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)
util::Result< CTxDestination > GetNewDestination(const OutputType type, const std::string &label)
util::Result< CTxDestination > GetNewChangeDestination(const OutputType type)
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.
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)
bool GetReservedDestination(CTxDestination &pubkey, bool internal)
Reserve an address.
int64_t GetOldestKeyPoolTime() const
bool DelAddressBook(const CTxDestination &address)
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.
std::optional< common::PSBTError > FillPSBT(PartiallySignedTransaction &psbtx, bool &complete, SigHashType sighash_type=SigHashType().withForkId(), bool sign=true, bool bip32derivs=true, bool finalize=true) const
Fills out a PSBT with information from the wallet.
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)
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)
void blockConnected(ChainstateRole role, const CBlock &block, int height) override
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 chainStateFlushed(ChainstateRole role, const CBlockLocator &loc) override
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
isminetype
IsMine() return codes.
ChainstateRole
This enum describes the various roles a specific Chainstate instance can take.
bool ParseMoney(const std::string &money_string, Amount &nRet)
Parse an amount denoted in full coins.
bilingual_str AmountErrMsg(const std::string &optname, const std::string &strValue)
bilingual_str AmountHighWarn(const std::string &optname)
static path u8path(const std::string &utf8_str)
static auto quoted(const std::string &s)
static bool exists(const path &p)
static bool copy_file(const path &from, const path &to, copy_options options)
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)
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
void ReplaceAll(std::string &in_out, std::string_view search, std::string_view substitute)
Replace every non-overlapping occurrence of search with substitute, treating both literally; the repl...
std::string ToString(const T &t)
Locale-independent version of std::to_string.
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...
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
static std::string ToString(const CService &ip)
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.
@ PRIVATE_KEY_NOT_AVAILABLE
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.
BlockHash last_failed_block
Hash of the most recent block that could not be scanned due to read errors or pruning.
enum CWallet::ScanResult::@19 status
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.
WalletContext struct containing references to state shared between CWallet instances,...
interfaces::Chain * chain
#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.
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
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::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
@ FAILED_INVALID_BACKUP_FILE
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.
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(WalletContext &context, LoadWalletFn load_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
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
void MaybeResendWalletTxs(WalletContext &context)
Called periodically by the schedule thread.
static std::condition_variable g_wallet_release_cv
bool AddWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
static void FlushAndDeleteWallet(CWallet *wallet)
void WaitForDeleteWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly delete the wallet.
static GlobalMutex g_loading_wallet_mutex
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
bool AddWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Add wallet name to persistent configuration so it will be loaded on startup.
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)
bool RemoveWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Remove wallet name from persistent configuration so it will not be loaded on startup.
std::shared_ptr< CWallet > GetWallet(WalletContext &context, const std::string &name)
static void UpdateWalletSetting(interfaces::Chain &chain, const std::string &wallet_name, std::optional< bool > load_on_startup, std::vector< bilingual_str > &warnings)
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)
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)
static GlobalMutex g_wallet_release_mutex
static std::set< std::string > g_loading_wallet_set GUARDED_BY(g_loading_wallet_mutex)
void NotifyWalletLoaded(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
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