|
Bitcoin Core
22.99.0
P2P Digital Currency
|
Go to the documentation of this file.
47 #include <boost/algorithm/string/replace.hpp>
54 "You need to rescan the blockchain in order to correctly mark used "
55 "destinations in the past. Until this is done, some destinations may "
56 "be considered unused, even if the opposite is the case."
65 if (value.isStr() && value.get_str() == wallet_name)
return true;
74 if (!setting_value.
isArray())
return true;
77 if (!value.isStr() || value.get_str() != wallet_name) new_value.
push_back(value);
79 if (new_value.
size() == setting_value.
size())
return true;
84 const std::string& wallet_name,
85 std::optional<bool> load_on_startup,
86 std::vector<bilingual_str>& warnings)
88 if (!load_on_startup)
return;
90 warnings.emplace_back(
Untranslated(
"Wallet load on startup setting could not be updated, so wallet may not be loaded next node startup."));
92 warnings.emplace_back(
Untranslated(
"Wallet load on startup setting could not be updated, so wallet may still be loaded next node startup."));
114 std::vector<std::shared_ptr<CWallet>>::const_iterator i = std::find(
context.wallets.begin(),
context.wallets.end(),
wallet);
115 if (i !=
context.wallets.end())
return false;
117 wallet->ConnectScriptPubKeyManNotifiers();
118 wallet->NotifyCanGetAddressesChanged();
130 wallet->m_chain_notifications_handler.reset();
132 std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(
context.wallets.begin(),
context.wallets.end(),
wallet);
133 if (i ==
context.wallets.end())
return false;
144 std::vector<bilingual_str> warnings;
157 for (
const std::shared_ptr<CWallet>&
wallet :
context.wallets) {
166 auto it =
context.wallet_load_fns.emplace(
context.wallet_load_fns.end(), std::move(load_wallet));
180 wallet->WalletLogPrintf(
"Releasing wallet\n");
186 if (g_unloading_wallet_set.erase(
name) == 0) {
200 auto it = g_unloading_wallet_set.insert(
name);
212 while (g_unloading_wallet_set.count(
name) == 1) {
219 std::shared_ptr<CWallet> LoadWalletInternal(WalletContext&
context,
const std::string&
name, std::optional<bool> load_on_start,
const DatabaseOptions& options,
DatabaseStatus& status,
bilingual_str&
error, std::vector<bilingual_str>& warnings)
236 wallet->postInitProcess();
242 }
catch (
const std::runtime_error& e) {
253 if (!result.second) {
274 if (!passphrase.empty()) {
280 error =
Untranslated(
"Private keys must be disabled when using an external signer");
287 error =
Untranslated(
"Descriptor support must be enabled when using an external signer");
302 error =
Untranslated(
"Passphrase provided but private keys are disabled. A passphrase is only used to encrypt private keys, so cannot be used for wallets with private keys disabled.");
318 if (!
wallet->EncryptWallet(passphrase)) {
325 if (!
wallet->Unlock(passphrase)) {
335 wallet->SetupDescriptorScriptPubKeyMans();
337 for (
auto spk_man :
wallet->GetActiveScriptPubKeyMans()) {
338 if (!spk_man->SetupGeneration()) {
352 wallet->postInitProcess();
380 auto wallet_file = wallet_path /
"wallet.dat";
381 fs::copy_file(backup_file, wallet_file, fs::copy_options::none);
386 fs::remove(wallet_file);
387 fs::remove(wallet_path);
401 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
402 if (it == mapWallet.end())
404 return &(it->second);
418 spk_man->UpgradeKeyMetadata();
442 for (
const MasterKeyMap::value_type& pMasterKey :
mapMasterKeys)
444 if(!crypter.
SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
446 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
448 if (
Unlock(_vMasterKey, accept_no_keys)) {
472 if(!crypter.
SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
474 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
479 crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
480 pMasterKey.second.nDeriveIterations =
static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(
GetTimeMillis() - nStartTime))));
483 crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
484 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations +
static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(
GetTimeMillis() - nStartTime)))) / 2;
486 if (pMasterKey.second.nDeriveIterations < 25000)
487 pMasterKey.second.nDeriveIterations = 25000;
489 WalletLogPrintf(
"Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
491 if (!crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
493 if (!crypter.
Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
515 if (nWalletVersion >= nVersion)
517 nWalletVersion = nVersion;
521 if (nWalletVersion > 40000)
530 std::set<uint256> result;
533 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
534 if (it == mapWallet.end())
538 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
540 for (
const CTxIn& txin : wtx.
tx->vin)
542 if (mapTxSpends.count(txin.
prevout) <= 1)
544 range = mapTxSpends.equal_range(txin.
prevout);
545 for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
546 result.insert(_it->second);
554 auto iter = mapTxSpends.lower_bound(
COutPoint(txid, 0));
555 return (iter != mapTxSpends.end() && iter->first.hash == txid);
574 int nMinOrderPos = std::numeric_limits<int>::max();
576 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
577 const CWalletTx* wtx = &mapWallet.at(it->second);
589 for (TxSpends::iterator it = range.first; it != range.second; ++it)
591 const uint256& hash = it->second;
593 if (copyFrom == copyTo)
continue;
594 assert(copyFrom &&
"Oldest wallet transaction in range assumed to have been found.");
614 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
615 range = mapTxSpends.equal_range(outpoint);
617 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
619 const uint256& wtxid = it->second;
620 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
621 if (mit != mapWallet.end()) {
623 if (depth > 0 || (depth == 0 && !mit->second.isAbandoned()))
632 mapTxSpends.insert(std::make_pair(outpoint, wtxid));
641 std::pair<TxSpends::iterator, TxSpends::iterator> range;
642 range = mapTxSpends.equal_range(outpoint);
649 auto it = mapWallet.find(wtxid);
650 assert(it != mapWallet.end());
655 for (
const CTxIn& txin : thisTx.
tx->vin)
698 delete encrypted_batch;
699 encrypted_batch =
nullptr;
705 auto spk_man = spk_man_pair.second.get();
706 if (!spk_man->Encrypt(_vMasterKey, encrypted_batch)) {
708 delete encrypted_batch;
709 encrypted_batch =
nullptr;
720 delete encrypted_batch;
721 encrypted_batch =
nullptr;
727 delete encrypted_batch;
728 encrypted_batch =
nullptr;
731 Unlock(strWalletPassphrase);
738 if (spk_man->IsHDEnabled()) {
739 if (!spk_man->SetupGeneration(
true)) {
770 typedef std::multimap<int64_t, CWalletTx*>
TxItems;
773 for (
auto& entry : mapWallet)
780 std::vector<int64_t> nOrderPosOffsets;
781 for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it)
788 nOrderPos = nOrderPosNext++;
789 nOrderPosOffsets.push_back(nOrderPos);
796 int64_t nOrderPosOff = 0;
797 for (
const int64_t& nOffsetStart : nOrderPosOffsets)
799 if (nOrderPos >= nOffsetStart)
802 nOrderPos += nOrderPosOff;
803 nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
821 int64_t nRet = nOrderPosNext++;
834 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
835 item.second.MarkDirty();
843 auto mi = mapWallet.find(originalHash);
846 assert(mi != mapWallet.end());
882 tx_destinations.insert(dst);
905 assert(spk_man !=
nullptr);
906 for (
const auto& keyid :
GetAffectedKeys(srctx->
tx->vout[n].scriptPubKey, *spk_man)) {
935 std::set<CTxDestination> tx_destinations;
937 for (
const CTxIn& txin : tx->vin) {
946 auto ret = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(tx, state));
948 bool fInsertedNew = ret.second;
949 bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew);
960 if (state.index() != wtx.
m_state.index()) {
972 if (tx->HasWitness() && !wtx.
tx->HasWitness()) {
979 WalletLogPrintf(
"AddToWallet %s %s%s\n", hash.
ToString(), (fInsertedNew ?
"new" :
""), (fUpdated ?
"update" :
""));
982 if (fInsertedNew || fUpdated)
994 std::string strCmd =
m_args.
GetArg(
"-walletnotify",
"");
998 boost::replace_all(strCmd,
"%s", hash.
GetHex());
1001 boost::replace_all(strCmd,
"%b", conf->confirmed_block_hash.GetHex());
1002 boost::replace_all(strCmd,
"%h",
ToString(conf->confirmed_block_height));
1004 boost::replace_all(strCmd,
"%b",
"unconfirmed");
1005 boost::replace_all(strCmd,
"%h",
"-1");
1015 std::thread
t(runCommand, strCmd);
1025 const auto& ins = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(
nullptr,
TxStateInactive{}));
1027 if (!fill_wtx(wtx, ins.second)) {
1033 auto lookup_block = [&](
const uint256& hash,
int& height,
TxState& state) {
1045 lookup_block(conf->confirmed_block_hash, conf->confirmed_block_height, wtx.
m_state);
1047 lookup_block(conf->conflicting_block_hash, conf->conflicting_block_height, wtx.
m_state);
1054 for (
const CTxIn& txin : wtx.
tx->vin) {
1056 if (it != mapWallet.end()) {
1072 if (
auto* conf = std::get_if<TxStateConfirmed>(&state)) {
1074 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.
prevout);
1075 while (range.first != range.second) {
1076 if (range.first->second != tx.
GetHash()) {
1077 WalletLogPrintf(
"Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.
GetHash().
ToString(), conf->confirmed_block_hash.ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
1078 MarkConflicted(conf->confirmed_block_hash, conf->confirmed_block_height, range.first->second);
1085 bool fExisted = mapWallet.count(tx.
GetHash()) != 0;
1086 if (fExisted && !fUpdate)
return false;
1098 for (
auto &dest : spk_man->MarkUnusedAddresses(txout.
scriptPubKey)) {
1100 if (!dest.internal.has_value()) {
1105 if (!dest.internal.has_value())
continue;
1119 TxState tx_state = std::visit([](
auto&& s) ->
TxState {
return s; }, state);
1135 for (
const CTxIn& txin : tx->vin) {
1137 if (it != mapWallet.end()) {
1138 it->second.MarkDirty();
1149 std::set<uint256> todo;
1150 std::set<uint256> done;
1153 auto it = mapWallet.find(hashTx);
1154 assert(it != mapWallet.end());
1160 todo.insert(hashTx);
1162 while (!todo.empty()) {
1166 auto it = mapWallet.find(now);
1167 assert(it != mapWallet.end());
1171 assert(currentconfirm <= 0);
1181 TxSpends::const_iterator iter = mapTxSpends.lower_bound(
COutPoint(now, 0));
1182 while (iter != mapTxSpends.end() && iter->first.hash == now) {
1183 if (!done.count(iter->second)) {
1184 todo.insert(iter->second);
1201 int conflictconfirms = (m_last_block_processed_height - conflicting_height + 1) * -1;
1206 if (conflictconfirms >= 0)
1212 std::set<uint256> todo;
1213 std::set<uint256> done;
1215 todo.insert(hashTx);
1217 while (!todo.empty()) {
1221 auto it = mapWallet.find(now);
1222 assert(it != mapWallet.end());
1225 if (conflictconfirms < currentconfirm) {
1232 TxSpends::const_iterator iter = mapTxSpends.lower_bound(
COutPoint(now, 0));
1233 while (iter != mapTxSpends.end() && iter->first.hash == now) {
1234 if (!done.count(iter->second)) {
1235 todo.insert(iter->second);
1261 auto it = mapWallet.find(tx->GetHash());
1262 if (it != mapWallet.end()) {
1269 auto it = mapWallet.find(tx->GetHash());
1270 if (it != mapWallet.end()) {
1309 m_last_block_processed_height = height;
1310 m_last_block_processed = block_hash;
1311 for (
size_t index = 0; index < block.
vtx.size(); index++) {
1325 m_last_block_processed_height = height - 1;
1337 void CWallet::BlockUntilSyncedToCurrentChain()
const {
1353 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.
prevout.
hash);
1354 if (mi != mapWallet.end())
1382 result = std::max(result, spk_man_pair.second->IsMine(script));
1408 throw std::runtime_error(std::string(__func__) +
": value out of range");
1416 bool result =
false;
1418 if (!spk_man->IsHDEnabled())
return false;
1430 if (spk_man && spk_man->CanGetAddresses(
internal)) {
1437 void CWallet::SetWalletFlag(uint64_t
flags)
1442 throw std::runtime_error(std::string(__func__) +
": writing wallet flags failed");
1456 throw std::runtime_error(std::string(__func__) +
": writing wallet flags failed");
1487 throw std::runtime_error(std::string(__func__) +
": writing wallet flags failed");
1516 if (target_weight < txin_weight) {
1519 if (target_weight == txin_weight) {
1524 int64_t add_weight = target_weight - txin_weight;
1534 if ((add_weight >= 253 && add_weight < 263)
1535 || (add_weight > std::numeric_limits<uint16_t>::max() && add_weight <= std::numeric_limits<uint16_t>::max() + 10)
1536 || (add_weight > std::numeric_limits<uint32_t>::max() && add_weight <= std::numeric_limits<uint32_t>::max() + 10)) {
1537 int64_t first_weight = add_weight / 3;
1538 add_weight -= first_weight;
1556 for (
const auto& txout : txouts)
1570 const std::unique_ptr<SigningProvider> provider =
GetSolvingProvider(txout.scriptPubKey);
1571 if (!provider || !
DummySignInput(*provider, txin, txout, use_max_sig)) {
1588 LOCK(spk_man->cs_KeyStore);
1589 return spk_man->ImportScripts(scripts, timestamp);
1598 LOCK(spk_man->cs_KeyStore);
1599 return spk_man->ImportPrivKeys(privkey_map, timestamp);
1602 bool CWallet::ImportPubKeys(
const std::vector<CKeyID>& ordered_pubkeys,
const std::map<CKeyID, CPubKey>& pubkey_map,
const std::map<
CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins,
const bool add_keypool,
const bool internal,
const int64_t timestamp)
1608 LOCK(spk_man->cs_KeyStore);
1609 return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins, add_keypool,
internal, timestamp);
1612 bool CWallet::ImportScriptPubKeys(
const std::string& label,
const std::set<CScript>& script_pub_keys,
const bool have_solving_data,
const bool apply_label,
const int64_t timestamp)
1618 LOCK(spk_man->cs_KeyStore);
1619 if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data, timestamp)) {
1624 for (
const CScript& script : script_pub_keys) {
1648 int start_height = 0;
1693 uint256 block_hash = start_block;
1705 double progress_current = progress_begin;
1706 int block_height = start_height;
1708 if (progress_end - progress_begin > 0.0) {
1709 m_scanning_progress = (progress_current - progress_begin) / (progress_end - progress_begin);
1713 if (block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
1718 WalletLogPrintf(
"Still rescanning. At block %d. Progress=%f\n", block_height, progress_current);
1727 bool block_still_active =
false;
1728 bool next_block =
false;
1734 if (!block_still_active) {
1741 for (
size_t posInBlock = 0; posInBlock < block.
vtx.size(); ++posInBlock) {
1752 if (max_height && block_height >= *max_height) {
1763 block_hash = next_block_hash;
1768 const uint256 prev_tip_hash = tip_hash;
1770 if (!max_height && prev_tip_hash != tip_hash) {
1778 WalletLogPrintf(
"Rescan aborted at block %d. Progress=%f\n", block_height, progress_current);
1780 }
else if (block_height &&
chain().shutdownRequested()) {
1781 WalletLogPrintf(
"Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height, progress_current);
1794 std::map<int64_t, CWalletTx*> mapSorted;
1797 for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
1798 const uint256& wtxid = item.first;
1805 mapSorted.insert(std::make_pair(wtx.
nOrderPos, &wtx));
1810 for (
const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
1812 std::string unused_err_string;
1847 std::set<uint256> result;
1851 result.erase(myHash);
1869 if (!
chain().isReadyToBroadcast())
return;
1879 int submitted_tx_count = 0;
1885 for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
1891 std::string unused_err_string;
1896 if (submitted_tx_count > 0) {
1897 WalletLogPrintf(
"%s: resubmit %u unconfirmed transactions\n", __func__, submitted_tx_count);
1906 pwallet->ResendWalletTransactions();
1921 std::map<COutPoint, Coin> coins;
1922 for (
auto& input : tx.
vin) {
1923 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
1924 if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
1929 coins[input.prevout] =
Coin(wtx.
tx->vout[input.prevout.n], prev_height, wtx.
IsCoinBase());
1931 std::map<int, bilingual_str> input_errors;
1941 if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
1958 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
1959 const CTxIn& txin = psbtx.
tx->vin[i];
1969 const auto it = mapWallet.find(txhash);
1970 if (it != mapWallet.end()) {
1981 int n_signed_this_spkm = 0;
1982 TransactionError res = spk_man->FillPSBT(psbtx, txdata, sighash_type, sign, bip32derivs, &n_signed_this_spkm, finalize);
1988 (*n_signed) += n_signed_this_spkm;
1994 for (
const auto& input : psbtx.
inputs) {
2006 if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
2007 return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
2017 return *change_type;
2026 bool any_wpkh{
false};
2028 bool any_pkh{
false};
2030 for (
const auto& recipient : vecSend) {
2031 std::vector<std::vector<uint8_t>> dummy;
2045 if (has_bech32m_spkman && any_tr) {
2050 if (has_bech32_spkman && any_wpkh) {
2055 if (has_p2sh_segwit_spkman && any_sh) {
2061 if (has_legacy_spkman && any_pkh) {
2066 if (has_bech32m_spkman) {
2069 if (has_bech32_spkman) {
2086 wtx.
mapValue = std::move(mapValue);
2094 for (
const CTxIn& txin : tx->vin) {
2102 CWalletTx& wtx = mapWallet.at(tx->GetHash());
2109 std::string err_string;
2111 WalletLogPrintf(
"CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
2126 spk_man_pair.second->RewriteDB();
2136 return nLoadWalletRet;
2143 for (
const uint256& hash : vHashOut) {
2144 const auto& it = mapWallet.find(hash);
2145 wtxOrdered.erase(it->second.m_it_wtxOrdered);
2146 for (
const auto& txin : it->second.tx->vin)
2147 mapTxSpends.erase(txin.prevout);
2148 mapWallet.erase(it);
2157 spk_man_pair.second->RewriteDB();
2163 return nZapSelectTxRet;
2172 bool fUpdated =
false;
2176 std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find(address);
2177 fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
2178 m_address_book[address].SetLabel(strName);
2179 if (!strPurpose.empty())
2180 m_address_book[address].purpose = strPurpose;
2211 for (
const std::pair<const std::string, std::string> &item : m_address_book[address].destdata)
2215 m_address_book.erase(address);
2230 if (legacy_spk_man) {
2231 return legacy_spk_man->KeypoolCountExternalKeys();
2234 unsigned int count = 0;
2236 count += spk_man.second->GetKeyPoolSize();
2246 unsigned int count = 0;
2248 count += spk_man->GetKeyPoolSize();
2258 res &= spk_man->TopUp(kpSize);
2267 bool result =
false;
2271 result = spk_man->GetNewDestination(type, dest,
error);
2300 return std::nullopt;
2303 std::optional<int64_t> oldest_key{std::numeric_limits<int64_t>::max()};
2305 oldest_key = std::min(oldest_key, spk_man_pair.second->GetOldestKeyPoolTime());
2311 for (
auto& entry : mapWallet) {
2314 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
2327 std::set<CTxDestination> result;
2328 for (
const std::pair<const CTxDestination, CAddressBookData>& item : m_address_book)
2330 if (item.second.IsChange())
continue;
2332 const std::string& strName = item.second.GetLabel();
2333 if (strName == label)
2334 result.insert(address);
2385 if (signer_spk_man ==
nullptr) {
2389 return signer_spk_man->DisplayAddress(scriptPubKey, signer);
2397 setLockedCoins.insert(output);
2407 bool was_locked = setLockedCoins.erase(output);
2408 if (batch && was_locked) {
2417 bool success =
true;
2419 for (
auto it = setLockedCoins.begin(); it != setLockedCoins.end(); ++it) {
2422 setLockedCoins.clear();
2431 return (setLockedCoins.count(outpt) > 0);
2437 for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
2438 it != setLockedCoins.end(); it++) {
2440 vOutpts.push_back(outpt);
2448 mapKeyBirth.clear();
2451 std::map<CKeyID, const TxStateConfirmed*> mapKeyFirstBlock;
2458 assert(spk_man !=
nullptr);
2462 for (
const auto& entry : spk_man->mapKeyMetadata) {
2463 if (entry.second.nCreateTime) {
2464 mapKeyBirth[entry.first] = entry.second.nCreateTime;
2470 if (mapKeyBirth.count(keyid) == 0)
2471 mapKeyFirstBlock[keyid] = &max_confirm;
2475 if (mapKeyFirstBlock.empty())
2479 for (
const auto& entry : mapWallet) {
2484 for (
const CTxOut &txout : wtx.
tx->vout) {
2488 auto rit = mapKeyFirstBlock.find(keyid);
2489 if (rit != mapKeyFirstBlock.end() && conf->confirmed_block_height < rit->second->confirmed_block_height) {
2499 for (
const auto& entry : mapKeyFirstBlock) {
2531 std::optional<uint256> block_hash;
2533 block_hash = conf->confirmed_block_hash;
2535 block_hash = conf->conflicting_block_hash;
2541 int64_t block_max_time;
2542 if (
chain().findBlock(*block_hash,
FoundBlock().time(blocktime).maxTime(block_max_time))) {
2543 if (rescanning_old_block) {
2544 nTimeSmart = block_max_time;
2547 int64_t latestEntry = 0;
2550 int64_t latestTolerated = latestNow + 300;
2552 for (
auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
2562 if (nSmartTime <= latestTolerated) {
2563 latestEntry = nSmartTime;
2564 if (nSmartTime > latestNow) {
2565 latestNow = nSmartTime;
2571 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
2582 const std::string key{
"used"};
2583 if (std::get_if<CNoDestination>(&dest))
2587 if (
auto* data =
util::FindKey(m_address_book, dest)) data->destdata.erase(key);
2591 const std::string value{
"1"};
2592 m_address_book[dest].destdata.insert(std::make_pair(key, value));
2598 m_address_book[dest].destdata.insert(std::make_pair(key, value));
2603 const std::string key{
"used"};
2604 std::map<CTxDestination, CAddressBookData>::const_iterator i = m_address_book.find(dest);
2605 if(i != m_address_book.end())
2607 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
2608 if(j != i->second.destdata.end())
2618 const std::string
prefix{
"rr"};
2619 std::vector<std::string>
values;
2620 for (
const auto& address : m_address_book) {
2621 for (
const auto& data : address.second.destdata) {
2623 values.emplace_back(data.second);
2632 const std::string key{
"rr" +
id};
2634 if (value.empty()) {
2653 fs::file_type path_type = fs::symlink_status(wallet_path).type();
2654 if (!(path_type == fs::file_type::not_found || path_type == fs::file_type::directory ||
2655 (path_type == fs::file_type::symlink && fs::is_directory(wallet_path)) ||
2658 "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
2659 "database/log.?????????? files can be stored, a location where such a directory could be created, "
2660 "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
2665 return MakeDatabase(wallet_path, options, status, error_string);
2672 const std::string& walletFile = database->Filename();
2678 bool rescan_required =
false;
2679 DBErrors nLoadWalletRet = walletInstance->LoadWallet();
2682 error =
strprintf(
_(
"Error loading %s: Wallet corrupted"), walletFile);
2687 warnings.push_back(
strprintf(
_(
"Error reading %s! All keys read correctly, but transaction data"
2688 " or address book entries might be missing or incorrect."),
2700 warnings.push_back(
strprintf(
_(
"Error reading %s! Transaction data may be missing or incorrect."
2701 " Rescanning wallet."), walletFile));
2702 rescan_required =
true;
2711 const bool fFirstRun = walletInstance->m_spk_managers.empty() &&
2719 walletInstance->AddWalletFlags(wallet_creation_flags);
2723 walletInstance->SetupLegacyScriptPubKeyMan();
2727 LOCK(walletInstance->cs_wallet);
2729 walletInstance->SetupDescriptorScriptPubKeyMans();
2733 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
2734 if (!spk_man->SetupGeneration()) {
2735 error =
_(
"Unable to generate initial keys");
2747 error =
strprintf(
_(
"Error loading %s: Private keys can only be disabled during creation"), walletFile);
2750 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
2751 if (spk_man->HavePrivateKeys()) {
2752 warnings.push_back(
strprintf(
_(
"Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
2758 if (!
args.
GetArg(
"-addresstype",
"").empty()) {
2764 walletInstance->m_default_address_type = parsed.value();
2767 if (!
args.
GetArg(
"-changetype",
"").empty()) {
2773 walletInstance->m_default_change_type = parsed.value();
2778 if (!min_tx_fee || min_tx_fee.value() == 0) {
2783 _(
"This is the minimum transaction fee you pay on every transaction."));
2786 walletInstance->m_min_fee =
CFeeRate{min_tx_fee.value()};
2790 const std::string max_aps_fee{
args.
GetArg(
"-maxapsfee",
"")};
2791 if (max_aps_fee ==
"-1") {
2792 walletInstance->m_max_aps_fee = -1;
2793 }
else if (std::optional<CAmount> max_fee =
ParseMoney(max_aps_fee)) {
2796 _(
"This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection."));
2798 walletInstance->m_max_aps_fee = max_fee.value();
2807 if (!fallback_fee) {
2812 _(
"This is the transaction fee you may pay when fee estimates are not available."));
2814 walletInstance->m_fallback_fee =
CFeeRate{fallback_fee.value()};
2818 walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.
GetFeePerK() != 0;
2827 _(
"This is the transaction fee you may discard if change is smaller than dust at this level"));
2829 walletInstance->m_discard_rate =
CFeeRate{discard_fee.value()};
2839 _(
"This is the transaction fee you will pay if you send a transaction."));
2842 walletInstance->m_pay_tx_fee =
CFeeRate{pay_tx_fee.value(), 1000};
2845 error =
strprintf(
_(
"Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
2857 warnings.push_back(
_(
"-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
2861 error =
strprintf(
_(
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
2866 walletInstance->m_default_max_tx_fee = max_fee.value();
2870 if (std::optional<CAmount> consolidate_feerate =
ParseMoney(
args.
GetArg(
"-consolidatefeerate",
""))) {
2871 walletInstance->m_consolidate_feerate =
CFeeRate(*consolidate_feerate);
2880 _(
"The wallet will avoid paying less than the minimum relay fee."));
2887 walletInstance->WalletLogPrintf(
"Wallet completed loading in %15dms\n",
GetTimeMillis() - nStart);
2890 walletInstance->TopUpKeyPool();
2898 for (
auto& load_wallet :
context.wallet_load_fns) {
2904 LOCK(walletInstance->cs_wallet);
2906 walletInstance->WalletLogPrintf(
"setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
2907 walletInstance->WalletLogPrintf(
"mapWallet.size() = %u\n", walletInstance->mapWallet.size());
2908 walletInstance->WalletLogPrintf(
"m_address_book.size() = %u\n", walletInstance->m_address_book.size());
2911 return walletInstance;
2916 LOCK(walletInstance->cs_wallet);
2918 assert(!walletInstance->m_chain || walletInstance->m_chain == &
chain);
2919 walletInstance->m_chain = &
chain;
2929 walletInstance->m_chain_notifications_handler = walletInstance->chain().
handleNotifications(walletInstance);
2932 int rescan_height = 0;
2933 if (!rescan_required)
2939 rescan_height = *fork_height;
2947 walletInstance->m_last_block_processed_height = *tip_height;
2949 walletInstance->m_last_block_processed.
SetNull();
2950 walletInstance->m_last_block_processed_height = -1;
2953 if (tip_height && *tip_height != rescan_height)
2956 int block_height = *tip_height;
2957 while (block_height > 0 &&
chain.
haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
2961 if (rescan_height != block_height) {
2968 error =
_(
"Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
2974 walletInstance->WalletLogPrintf(
"Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
2978 std::optional<int64_t> time_first_key;
2979 for (
auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
2980 int64_t time = spk_man->GetTimeFirstKey();
2981 if (!time_first_key || time < *time_first_key) time_first_key = time;
2983 if (time_first_key) {
2990 error =
_(
"Failed to rescan the wallet during initialization");
2995 walletInstance->GetDatabase().IncrementUpdateCounter();
3003 const auto& address_book_it = m_address_book.find(dest);
3004 if (address_book_it == m_address_book.end())
return nullptr;
3005 if ((!allow_change) && address_book_it->second.IsChange()) {
3008 return &address_book_it->second;
3020 if (version < prev_version) {
3021 error =
strprintf(
_(
"Cannot downgrade wallet from version %i to version %i. Wallet version unchanged."), prev_version, version);
3029 error =
strprintf(
_(
"Cannot upgrade a non HD split wallet from version %i to version %i without upgrading to support pre-split keypool. Please use version %i or no version specified."), prev_version, version,
FEATURE_PRE_SPLIT_KEYPOOL);
3037 if (!spk_man->Upgrade(prev_version, version,
error)) {
3093 assert(chain_depth >= 0);
3114 return vMasterKey.empty();
3136 if (!spk_man_pair.second->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) {
3140 vMasterKey = vMasterKeyIn;
3148 std::set<ScriptPubKeyMan*> spk_mans;
3149 for (
bool internal : {
false,
true}) {
3153 spk_mans.insert(spk_man);
3162 std::set<ScriptPubKeyMan*> spk_mans;
3164 spk_mans.insert(spk_man_pair.second.get());
3172 std::map<OutputType, ScriptPubKeyMan*>::const_iterator it = spk_managers.find(type);
3173 if (it == spk_managers.end()) {
3181 std::set<ScriptPubKeyMan*> spk_mans;
3184 if (spk_man_pair.second->CanProvide(script, sigdata)) {
3185 spk_mans.insert(spk_man_pair.second.get());
3208 if (spk_man_pair.second->CanProvide(script, sigdata)) {
3209 return spk_man_pair.second->GetSolvingProvider(script);
3291 for (
bool internal : {
false,
true}) {
3296 throw std::runtime_error(std::string(__func__) +
": Wallet is locked, cannot setup new descriptors");
3298 if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey,
nullptr)) {
3299 throw std::runtime_error(std::string(__func__) +
": Could not encrypt new descriptors");
3302 spk_manager->SetupDescriptorGeneration(master_key,
t,
internal);
3303 uint256 id = spk_manager->GetID();
3315 if (!signer_res.
isObject())
throw std::runtime_error(std::string(__func__) +
": Unexpected result");
3316 for (
bool internal : {
false,
true}) {
3317 const UniValue& descriptor_vals =
find_value(signer_res,
internal ?
"internal" :
"receive");
3318 if (!descriptor_vals.
isArray())
throw std::runtime_error(std::string(__func__) +
": Unexpected result");
3320 std::string desc_str = desc_val.getValStr();
3322 std::string desc_error;
3323 std::unique_ptr<Descriptor> desc =
Parse(desc_str, keys, desc_error,
false);
3324 if (desc ==
nullptr) {
3325 throw std::runtime_error(std::string(__func__) +
": Invalid descriptor \"" + desc_str +
"\" (" + desc_error +
")");
3327 if (!desc->GetOutputType()) {
3332 spk_manager->SetupDescriptor(std::move(desc));
3333 uint256 id = spk_manager->GetID();
3345 throw std::runtime_error(std::string(__func__) +
": writing active ScriptPubKeyMan id failed");
3356 WalletLogPrintf(
"Setting spkMan to active: id = %s, type = %d, internal = %d\n",
id.
ToString(),
static_cast<int>(type),
static_cast<int>(
internal));
3360 spk_mans[type] = spk_man;
3362 const auto it = spk_mans_other.find(type);
3363 if (it != spk_mans_other.end() && it->second == spk_man) {
3364 spk_mans_other.erase(type);
3373 if (spk_man !=
nullptr && spk_man->GetID() ==
id) {
3374 WalletLogPrintf(
"Deactivate spkMan: id = %s, type = %d, internal = %d\n",
id.
ToString(),
static_cast<int>(type),
static_cast<int>(
internal));
3377 throw std::runtime_error(std::string(__func__) +
": erasing active ScriptPubKeyMan id failed");
3381 spk_mans.erase(type);
3393 return spk_man !=
nullptr;
3413 return std::nullopt;
3418 return std::nullopt;
3422 if (!desc_spk_man) {
3423 throw std::runtime_error(std::string(__func__) +
": unexpected ScriptPubKeyMan type.");
3426 LOCK(desc_spk_man->cs_desc_man);
3427 const auto& type = desc_spk_man->GetWalletDescriptor().descriptor->GetOutputType();
3428 assert(type.has_value());
3438 WalletLogPrintf(
"Cannot add WalletDescriptor to a non-descriptor wallet\n");
3445 spk_man->UpdateWalletDescriptor(desc);
3448 spk_man = new_spk_man.get();
3455 for (
const auto& entry : signing_provider.
keys) {
3456 const CKey& key = entry.second;
3457 spk_man->AddDescriptorKey(key, key.
GetPubKey());
3461 if (!spk_man->TopUp()) {
3469 auto script_pub_keys = spk_man->GetScriptPubKeys();
3470 if (script_pub_keys.empty()) {
3471 WalletLogPrintf(
"Could not generate scriptPubKeys (cache is empty)\n");
3482 spk_man->WriteDescriptor();
std::set< ScriptPubKeyMan * > GetScriptPubKeyMans(const CScript &script) const
Get all the ScriptPubKeyMans for a script.
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
static const bool DEFAULT_WALLETBROADCAST
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.
static void ReleaseWallet(CWallet *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 IsFromMe(const CTransaction &tx) const
should probably be renamed to IsRelevantToMe
bool IsExternalSelected(const COutPoint &output) const
An input of a transaction.
boost::signals2::signal< void()> NotifyCanGetAddressesChanged
Keypool has new keys.
bool fFromMe
From me flag is set to 1 for transactions that were created by the wallet on this bitcoin node,...
void updatedBlockTip() override
const CWallet *const pwallet
The wallet to reserve from.
bool IsEquivalentTo(const CWalletTx &tx) const
True if only scriptSigs are different.
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
CTxDestination address
The destination.
const std::vector< CTxIn > vin
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
const uint256 & GetHash() const
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< unsigned char > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
virtual double guessVerificationProgress(const uint256 &block_hash)=0
Estimate fraction of total transactions verified if blocks up to the specified block hash are verifie...
static bool exists(const path &p)
std::function< bool(CWalletTx &wtx, bool new_tx)> UpdateWalletTxFn
Callback for updating transaction metadata in mapWallet.
bilingual_str _(const char *psz)
Translation function.
bool SetAddressUsed(WalletBatch &batch, const CTxDestination &dest, bool used) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool m_pre_split
Whether this key was generated for a keypool before the wallet was upgraded to HD-split.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
bool LoadToWallet(const uint256 &hash, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void MarkConflicted(const uint256 &hashBlock, int conflicting_height, const uint256 &hashTx)
Mark a transaction (and its in-wallet descendants) as conflicting with a particular block.
static constexpr auto OUTPUT_TYPES
bool fInternal
Whether this is from the internal (change output) keypool.
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
bool FillInputToWeight(CTxIn &txin, int64_t target_weight)
std::underlying_type< isminetype >::type isminefilter
used for bitflags of isminetype
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
void UnsetWalletFlagWithDB(WalletBatch &batch, uint64_t flag)
Unsets a wallet flag and saves it to disk.
int GetVersion() const
get the current wallet format (the oldest client version guaranteed to understand this wallet)
const unsigned int WALLET_CRYPTO_SALT_SIZE
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
interfaces::Chain & chain() const
Interface for accessing chain state.
std::atomic< bool > fAbortRescan
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
void DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Remove specified ScriptPubKeyMan from set of active SPK managers.
bool AddWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule)
RAII object to check and reserve a wallet rescan.
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
virtual bool Rewrite(const char *pszSkip=nullptr)=0
Rewrite the entire database on disk, with the exception of key pszSkip if non-zero.
#define PACKAGE_BUGREPORT
bool SetAddressBookWithDB(WalletBatch &batch, const CTxDestination &address, const std::string &strName, const std::string &strPurpose)
CWalletTx * AddToWallet(CTransactionRef tx, const TxState &state, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true, bool rescanning_old_block=false)
const std::string & FormatOutputType(OutputType type)
std::optional< bool > IsInternalScriptPubKeyMan(ScriptPubKeyMan *spk_man) const
Returns whether the provided ScriptPubKeyMan is internal.
static std::condition_variable g_wallet_release_cv
bool WriteMinVersion(int nVersion)
A key from a CWallet's keypool.
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
int64_t nOrderPos
position in ordered transaction list
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
std::unique_ptr< interfaces::Handler > HandleLoadWallet(WalletContext &context, LoadWalletFn load_wallet)
bool UpgradeWallet(int version, bilingual_str &error)
Upgrade the wallet.
std::optional< int64_t > GetOldestKeyPoolTime() const
virtual void Close()=0
Flush to the database file and close the database.
static const std::unordered_set< OutputType > LEGACY_OUTPUT_TYPES
OutputTypes supported by the LegacyScriptPubKeyMan.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static void UpdateWalletSetting(interfaces::Chain &chain, const std::string &wallet_name, std::optional< bool > load_on_startup, std::vector< bilingual_str > &warnings)
bool HasWalletSpend(const uint256 &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 WriteLockedUTXO(const COutPoint &output)
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< unsigned char > &vchCiphertext) const
std::map< OutputType, ScriptPubKeyMan * > m_internal_spk_managers
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const
bool DelAddressBook(const CTxDestination &address)
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
bool MarkReplaced(const uint256 &originalHash, const uint256 &newHash)
Mark a transaction as replaced by another transaction (e.g., BIP 125).
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
check whether we support the named feature
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.
bool WriteOrderPosNext(int64_t nOrderPosNext)
std::map< CKeyID, CKey > keys
std::vector< PSBTInput > inputs
void MaybeResendWalletTxs(WalletContext &context)
Called periodically by the schedule thread.
bool SignTransaction(CMutableTransaction &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Fetch the inputs and sign with SIGHASH_ALL.
void SyncMetaData(std::pair< TxSpends::iterator, TxSpends::iterator >) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
static auto quoted(const std::string &s)
An interface to be implemented by keystores that support signing.
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)
virtual void Flush()=0
Make sure all changes are flushed to database file.
virtual std::unique_ptr< Handler > handleNotifications(std::shared_ptr< Notifications > notifications)=0
Register handler for notifications.
static const unsigned int DEFAULT_TX_CONFIRM_TARGET
-txconfirmtarget default
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
std::set< ScriptPubKeyMan * > GetActiveScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans in m_internal_spk_managers and m_external_spk_managers.
bool MoneyRange(const CAmount &nValue)
bool CanGetAddresses(bool internal=false) const
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
bool WriteBestBlock(const CBlockLocator &locator)
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
isminetype IsMine(const CTxDestination &dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
int confirmed_block_height
bool HasInputWeight(const COutPoint &outpoint) const
DBErrors
Error statuses for the wallet database.
virtual std::optional< int > getHeight()=0
Get current chain height, not including genesis block (returns 0 if chain only contains genesis block...
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
int64_t GetInputWeight(const COutPoint &outpoint) const
A reference to a CKey: the Hash160 of its serialized public key.
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
static std::string PathToString(const path &path)
Convert path object to a byte string.
int64_t nNextResend
The next scheduled rebroadcast of wallet transactions.
bool Unlock(const CKeyingMaterial &vMasterKeyIn, bool accept_no_keys=false)
std::shared_ptr< const CTransaction > CTransactionRef
bool TxnAbort()
Abort current transaction.
virtual bool findAncestorByHeight(const uint256 &block_hash, int ancestor_height, const FoundBlock &ancestor_out={})=0
Find ancestor of block at specified height and optionally return ancestor information.
std::set< ScriptPubKeyMan * > GetAllScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans.
bool LoadWalletFlags(uint64_t flags)
Loads the flags into the wallet.
A transaction with a bunch of additional info that only the owner cares about.
virtual bool Backup(const std::string &strDest) const =0
Back up the entire database to a file.
bool GetNewChangeDestination(const OutputType type, CTxDestination &dest, bilingual_str &error)
virtual util::SettingsValue getRwSetting(const std::string &name)=0
Return <datadir>/settings.json setting value.
bool HasWalletDescriptor(const WalletDescriptor &desc) const
const CWalletTx * GetWalletTx(const uint256 &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool EraseName(const std::string &strAddress)
std::shared_ptr< CWallet > wallet
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
#define Assert(val)
Identity function.
bool LockCoin(const COutPoint &output, WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Fee rate in satoshis per kilobyte: CAmount / kB.
unsigned int nMasterKeyMaxID
static constexpr uint64_t KNOWN_WALLET_FLAGS
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
void MarkDirty()
make sure balances are recalculated
mapValue_t mapValue
Key/value map with information about the transaction.
void transactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override
The basic transaction that is broadcasted on the network and contained in blocks.
bool DisplayAddress(const CTxDestination &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Display address on an external signer.
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
const CAddressBookData * FindAddressBookEntry(const CTxDestination &, bool allow_change=false) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bilingual_str AmountErrMsg(const std::string &optname, const std::string &strValue)
bool GetNewDestination(const OutputType type, const std::string label, CTxDestination &dest, bilingual_str &error)
CScriptWitness scriptWitness
Only serialized through CTransaction.
bool IsSpentKey(const uint256 &hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
void ConnectScriptPubKeyManNotifiers()
Connect the signals from ScriptPubKeyMans to the signals in CWallet.
bilingual_str AmountHighWarn(const std::string &optname)
void transactionAddedToMempool(const CTransactionRef &tx, uint64_t mempool_sequence) override
void MarkInputsDirty(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Mark a transaction's inputs dirty, thus forcing the outputs to be recomputed.
void SetSeed(Span< const uint8_t > seed)
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
@ WALLET_FLAG_EXTERNAL_SIGNER
Indicates that the wallet needs an external signer.
bool IsLocked() const override
static uint256 TxStateSerializedBlockHash(const TxState &state)
Get TxState serialized block hash. Inverse of TxStateInterpretSerialized.
static void RefreshMempoolStatus(CWalletTx &tx, interfaces::Chain &chain)
Refresh mempool status so the wallet is in an internally consistent state and immediately knows the t...
Encryption/decryption context with key information.
WalletFeature
(client) version numbers for particular wallet features
virtual bool havePruned()=0
Check if any block has been pruned.
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
UniValue GetDescriptors(const int account)
Get receive and change Descriptor(s) from device for a given account.
bool AbandonTransaction(const uint256 &hashTx)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
bool TxnCommit()
Commit current transaction.
static bool AttachChain(const std::shared_ptr< CWallet > &wallet, interfaces::Chain &chain, const bool rescan_required, bilingual_str &error, std::vector< bilingual_str > &warnings)
Catch wallet up to current chain, scanning new blocks, updating the best block locator and m_last_blo...
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver &reserver, bool update)
Scan active chain for relevant transactions after importing keys.
void ReacceptWalletTransactions() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
bool Decrypt(const std::vector< unsigned char > &vchCiphertext, CKeyingMaterial &vchPlaintext) const
bool RemoveWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Remove wallet name from persistent configuration so it will not be loaded on startup.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
#define AssertLockNotHeld(cs)
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
std::variant< TxStateConfirmed, TxStateInMempool, TxStateInactive > SyncTxState
Subset of states transaction sync logic is implemented to handle.
An output of a transaction.
FlatSigningProvider m_external_provider
SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs.
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
unsigned int fTimeReceivedIsTxTime
MasterKeyMap mapMasterKeys
bool AddToWalletIfInvolvingMe(const CTransactionRef &tx, const SyncTxState &state, bool fUpdate, bool rescanning_old_block) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Add a transaction to the wallet, or update it.
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
State of transaction added to mempool.
bool IsLegacy() const
Determine if we are a legacy wallet.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
virtual uint256 getBlockHash(int height)=0
Get block hash. Height must be valid or this function will abort.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
bool ReadBestBlock(CBlockLocator &locator)
bool WriteWalletFlags(const uint64_t flags)
WalletDatabase & GetDatabase() const override
const std::vector< CTxOut > vout
int64_t nTime
The time at which the key was generated. Set in AddKeypoolPubKeyWithDB.
const unsigned int WALLET_CRYPTO_KEY_SIZE
int GetTxDepthInMainChain(const CWalletTx &wtx) const NO_THREAD_SAFETY_ANALYSIS
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
virtual void waitForNotificationsIfTipChanged(const uint256 &old_tip)=0
Wait for pending notifications to be processed unless block hash points to the current chain tip.
std::map< OutputType, ScriptPubKeyMan * > m_external_spk_managers
bool HaveChain() const
Interface to assert chain access.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
ScriptPubKeyMan * m_spk_man
The ScriptPubKeyMan to reserve from. Based on type when GetReservedDestination is called.
@ PRIVATE_KEY_NOT_AVAILABLE
std::optional< DatabaseFormat > require_format
std::set< uint256 > GetTxConflicts(const CWalletTx &wtx) const NO_THREAD_SAFETY_ANALYSIS
DBErrors ReorderTransactions()
DBErrors LoadWallet(CWallet *pwallet)
constexpr CAmount HIGH_MAX_TX_FEE
-maxtxfee will warn if called with a higher fee than this amount (in satoshis)
State of rejected transaction that conflicts with a confirmed block.
unsigned int ComputeTimeSmart(const CWalletTx &wtx, bool rescanning_old_block) const
Compute smart timestamp for a transaction being added to the wallet.
std::shared_ptr< CWallet > GetWallet(WalletContext &context, const std::string &name)
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...
bool BackupWallet(const std::string &strDest) const
std::optional< CMutableTransaction > tx
std::set< CTxDestination > GetLabelAddresses(const std::string &label) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
CWallet(interfaces::Chain *chain, const std::string &name, const ArgsManager &args, std::unique_ptr< WalletDatabase > database)
Construct wallet with specified name and database implementation.
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Access to the wallet database.
int64_t CAmount
Amount in satoshis (Can be negative)
std::string GetHex() const
std::atomic< double > m_scanning_progress
void postInitProcess()
Wallet post-init setup Gives the wallet a chance to register repetitive tasks and complete post-init ...
constexpr CAmount HIGH_TX_FEE_PER_KB
Discourage users to set fees higher than this amount (in satoshis) per kB.
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Loads an active ScriptPubKeyMan for the specified type and internal.
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
virtual CFeeRate relayMinFee()=0
Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key.
@ WALLET_FLAG_AVOID_REUSE
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)
void ResendWalletTransactions()
static path PathFromString(const std::string &string)
Convert byte string to path object.
unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
bool IsAddressUsed(const CTxDestination &dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
virtual bool broadcastTransaction(const CTransactionRef &tx, const CAmount &max_tx_fee, bool relay, std::string &err_string)=0
Transaction is added to memory pool, if the transaction fee is below the amount specified by max_tx_f...
void blockConnected(const CBlock &block, int height) override
@ WALLET_FLAG_LAST_HARDENED_XPUB_CACHED
virtual bool updateRwSetting(const std::string &name, const util::SettingsValue &value, bool write=true)=0
Write a setting to <datadir>/settings.json.
Helper for findBlock to selectively return pieces of block data.
@ FAILED_INVALID_BACKUP_FILE
std::string ToString() const
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
bool WriteTx(const CWalletTx &wtx)
unsigned int nDerivationMethod
0 = EVP_sha512() 1 = scrypt()
CPubKey GetPubKey() const
Compute the public key from a private key.
void GetStrongRandBytes(unsigned char *buf, int num) noexcept
Gather entropy from various sources, feed it into the internal PRNG, and generate random data using i...
Serialized script, used inside transaction inputs and outputs.
void SetTx(CTransactionRef arg)
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
void UpgradeDescriptorCache() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade DescriptorCaches.
virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination &address, int64_t &index, CKeyPool &keypool, bilingual_str &error)
std::variant< TxStateConfirmed, TxStateInMempool, TxStateConflicted, TxStateInactive, TxStateUnrecognized > TxState
All possible CWalletTx states.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
ScanResult ScanForWalletTransactions(const uint256 &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.
virtual void KeepDestination(int64_t index, const OutputType &type)
void AddToSpends(const COutPoint &outpoint, const uint256 &wtxid, WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
constexpr CAmount HIGH_APS_FEE
discourage APS fee higher than this amount
CPubKey vchPubKey
The public key.
std::map< uint256, std::unique_ptr< ScriptPubKeyMan > > m_spk_managers
boost::signals2::signal< void(bool fHaveWatchOnly)> NotifyWatchonlyChanged
Watch-only address added.
boost::signals2::signal< void(const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)> NotifyAddressBookChanged
Address book entry changed.
static Mutex g_loading_wallet_mutex
@ WALLET_FLAG_KEY_ORIGIN_METADATA
@ FEATURE_PRE_SPLIT_KEYPOOL
bool UnlockCoin(const COutPoint &output, WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
static Mutex g_wallet_release_mutex
unsigned int nDeriveIterations
RecursiveMutex cs_wallet
Main wallet lock.
Enables interaction with an external signing device or service, such as a hardware wallet.
int64_t IncOrderPosNext(WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Increment the next transaction order id.
void Flush()
Flush wallet (bitdb flush)
OutputType m_default_address_type
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
bool TxnBegin()
Begin a new transaction.
State of transaction not confirmed or conflicting with a known block and not in the mempool.
bool GetReservedDestination(CTxDestination &pubkey, bool internal, bilingual_str &error)
Reserve an address.
void UnsetBlankWalletFlag(WalletBatch &batch) override
Unset the blank wallet flag and saves it to disk.
boost::signals2::signal< void(const std::string &title, int nProgress)> ShowProgress
Show progress e.g.
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet.
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
std::vector< std::string > GetAddressReceiveRequests() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
A wrapper to reserve an address from a wallet.
void SyncTransaction(const CTransactionRef &tx, const SyncTxState &state, bool update_tx=true, bool rescanning_old_block=false) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
An encapsulated public key.
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
void KeepDestination()
Keep the address. Do not return it's key to the keypool when this object goes out of scope.
WalletFeature GetClosestWalletFeature(int version)
ScriptPubKeyMan * GetScriptPubKeyMan(const OutputType &type, bool internal) const
Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
std::vector< CTransactionRef > vtx
bool fBroadcastTransactions
Whether this wallet will submit newly created transactions to the node's mempool and prompt rebroadca...
bool GetBroadcastTransactions() const
Inquire whether this wallet broadcasts transactions.
void Close()
Close wallet database.
static int TxStateSerializedIndex(const TxState &state)
Get TxState serialized block index. Inverse of TxStateInterpretSerialized.
const std::string GetDisplayName() const override
Returns a bracketed wallet name for displaying in logs, will return [default wallet] if the wallet ha...
An encapsulated private key.
virtual void ReloadDbEnv()=0
const ArgsManager & m_args
Provider of aplication-wide arguments.
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
void blockDisconnected(const CBlock &block, int height) override
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
LegacyScriptPubKeyMan * GetLegacyScriptPubKeyMan() const
Get the LegacyScriptPubKeyMan which is used for all types, internal, and external.
virtual bool isInMempool(const uint256 &txid)=0
Check if transaction is in mempool.
size_t KeypoolCountExternalKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
boost::signals2::signal< void(CWallet *wallet)> NotifyStatusChanged
Wallet status (encrypted, locked) changed.
std::multimap< int64_t, CWalletTx * >::const_iterator m_it_wtxOrdered
static const bool DEFAULT_WALLET_RBF
-walletrbf default
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)
bool WriteName(const std::string &strAddress, const std::string &strName)
A version of CTransaction with the PSBT format.
bool EraseLockedUTXO(const COutPoint &output)
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
std::optional< int > last_scanned_height
bool ErasePurpose(const std::string &strAddress)
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)
std::optional< CAmount > ParseMoney(const std::string &money_string)
Parse an amount denoted in full coins.
fs::path GetWalletDir()
Get the path of the wallet directory.
bool EncryptWallet(const SecureString &strWalletPassphrase)
virtual void initMessage(const std::string &message)=0
Send init message.
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)
void UpgradeDescriptorCache()
CAmount GetDebit(const CTxIn &txin, const isminefilter &filter) const
Returns amount of debit if the input matches the filter, otherwise returns 0.
void SetupDescriptorScriptPubKeyMans() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Create new DescriptorScriptPubKeyMans and add them to the wallet.
bool TopUpKeyPool(unsigned int kpSize=0)
boost::signals2::signal< void(const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
void SetMinVersion(enum WalletFeature, WalletBatch *batch_in=nullptr) override
signify that a particular wallet feature is now used.
bool AddWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Add wallet name to persistent configuration so it will be loaded on startup.
const CKeyingMaterial & GetEncryptionKey() const override
bool UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const
Get the SigningProvider for a script.
bool push_back(const UniValue &val)
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
static int64_t GetTransactionInputWeight(const CTxIn &txin)
static int g_sqlite_count GUARDED_BY(g_sqlite_mutex)=0
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
const std::vector< UniValue > & getValues() const
void chainStateFlushed(const CBlockLocator &loc) override
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
static ExternalSigner GetExternalSigner()
std::vector< unsigned char > vchCryptedKey
int GetTxBlocksToMaturity(const CWalletTx &wtx) const
void SetupLegacyScriptPubKeyMan()
Make a LegacyScriptPubKeyMan and set it for all types, internal, and external.
std::vector< std::pair< std::string, std::string > > vOrderForm
bool SubmitTxMemoryPoolAndRelay(CWalletTx &wtx, std::string &err_string, bool relay) const
Pass this transaction to node for mempool insertion and relay to peers if flag set to true.
void AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Adds the active ScriptPubKeyMan for the specified type and internal.
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE
Default for -spendzeroconfchange.
unsigned int nTimeReceived
time received by this node
virtual bool haveBlockOnDisk(int height)=0
Check that the block is available on disk (i.e.
bool EraseActiveScriptPubKeyMan(uint8_t type, bool internal)
enum wallet::CWallet::ScanResult::@17 status
void SetSpentKeyState(WalletBatch &batch, const uint256 &hash, unsigned int n, bool used, std::set< CTxDestination > &tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Descriptor with some wallet metadata.
virtual bool TopUp(unsigned int size=0)
Fills internal address pool.
const uint256 & GetHash() const
void UpdateInput(CTxIn &input, const SignatureData &data)
An outpoint - a combination of a transaction hash and an index n into its vout.
const UniValue & find_value(const UniValue &obj, const std::string &name)
std::multimap< int64_t, CWalletTx * > TxItems
std::vector< unsigned char > vchSalt
bool m_is_cache_empty
This flag is true if all m_amounts caches are empty.
bool HasEncryptionKeys() const override
std::atomic< uint64_t > m_wallet_flags
WalletFlags set on this wallet.
int64_t nIndex
The index of the address's key in the keypool.
std::unique_ptr< Wallet > MakeWallet(wallet::WalletContext &context, const std::shared_ptr< wallet::CWallet > &wallet)
Return implementation of Wallet interface.
bool IsSpent(const uint256 &hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Outpoint is spent if any non-conflicted transaction spends it:
WalletContext struct containing references to state shared between CWallet instances,...
virtual CBlockLocator getTipLocator()=0
Get locator for the current chain tip.
RecursiveMutex cs_KeyStore
const std::map< uint64_t, std::string > WALLET_FLAG_CAVEATS
State of transaction confirmed in a block.
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
@ BLOCK
Removed for block.
bool error(const char *fmt, const Args &... args)
virtual void requestMempoolTransactions(Notifications ¬ifications)=0
Synchronously send transactionAddedToMempool notifications about all current mempool transactions to ...
std::set< uint256 > GetConflicts(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get wallet transactions that conflict with given transaction (spend same outputs)
static bool copy_file(const path &from, const path &to, copy_options options)
A mutable version of CTransaction.
uint256 GetLastBlockHash() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
const UniValue & get_array() const
std::map< std::string, std::string > mapValue_t
SecureString create_passphrase
int GetLastBlockHeight() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get last block processed height.
void UnsetWalletFlag(uint64_t flag)
Unsets a single wallet flag.
virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination &addr)
DescriptorScriptPubKeyMan * GetDescriptorScriptPubKeyMan(const WalletDescriptor &desc) const
Return the DescriptorScriptPubKeyMan for a WalletDescriptor if it is already in the wallet.
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
interfaces::Chain * chain
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
std::atomic< int64_t > m_best_block_time
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector< std::pair< std::string, std::string >> orderForm)
Submit the transaction to the node's mempool and then relay to peers.
PrecomputedTransactionData PrecomputePSBTData(const PartiallySignedTransaction &psbt)
Compute a PrecomputedTransactionData object from a psbt.
void GetKeyBirthTimes(std::map< CKeyID, int64_t > &mapKeyBirth) const 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 ...
bool DummySignTx(CMutableTransaction &txNew, const std::set< CTxOut > &txouts, const CCoinControl *coin_control=nullptr) const
void ReturnDestination()
Return reserved address.
CAmount m_default_max_tx_fee
Absolute maximum transaction fee (in satoshis) used by default for the wallet.
bool SetAddressReceiveRequest(WalletBatch &batch, const CTxDestination &dest, const std::string &id, const std::string &value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool IsWalletFlagSet(uint64_t flag) const override
check if a certain wallet flag is set
@ CONFLICT
Removed for conflict with in-block transaction.
OutputType TransactionChangeType(const std::optional< OutputType > &change_type, const std::vector< CRecipient > &vecSend) const
std::string ShellEscape(const std::string &arg)
bool AddWalletFlags(uint64_t flags)
overwrite all flags by the given uint64_t returns false if unknown, non-tolerable flags are present
std::set< CKeyID > GetKeys() const override
std::optional< OutputType > ParseOutputType(const std::string &type)
int64_t GetTimeMillis()
Returns the system time (not mockable)
std::string EncodeDestination(const CTxDestination &dest)
bool IsTxImmatureCoinBase(const CWalletTx &wtx) const
std::vector< std::vector< unsigned char > > stack
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,...
bool TransactionCanBeAbandoned(const uint256 &hashTx) const
Return whether transaction can be abandoned.
#define WAIT_LOCK(cs, name)
std::shared_ptr< Descriptor > descriptor
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
bool DummySignInput(const SigningProvider &provider, CTxIn &tx_in, const CTxOut &txout, bool use_max_sig)
@ SIGHASH_DEFAULT
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
TransactionError FillPSBT(PartiallySignedTransaction &psbtx, bool &complete, int sighash_type=SIGHASH_DEFAULT, bool sign=true, bool bip32derivs=true, size_t *n_signed=nullptr, bool finalize=true) const
Fills out a PSBT with information from the wallet.
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.