41 #include <boost/algorithm/string/replace.hpp>
47 "You need to rescan the blockchain in order to correctly mark used "
48 "destinations in the past. Until this is done, some destinations may "
49 "be considered unused, even if the opposite is the case."
56 static std::vector<std::shared_ptr<CWallet>> vpwallets
GUARDED_BY(cs_wallets);
57 static std::list<LoadWalletFn> g_load_wallet_fns
GUARDED_BY(cs_wallets);
64 if (value.isStr() && value.get_str() == wallet_name)
return true;
73 if (!setting_value.
isArray())
return true;
76 if (!value.isStr() || value.get_str() != wallet_name) new_value.
push_back(value);
78 if (new_value.
size() == setting_value.
size())
return true;
83 const std::string& wallet_name,
85 std::vector<bilingual_str>& warnings)
87 if (load_on_startup ==
nullopt)
return;
89 warnings.emplace_back(
Untranslated(
"Wallet load on startup setting could not be updated, so wallet may not be loaded next node startup."));
91 warnings.emplace_back(
Untranslated(
"Wallet load on startup setting could not be updated, so wallet may still be loaded next node startup."));
95 bool AddWallet(
const std::shared_ptr<CWallet>& wallet)
99 std::vector<std::shared_ptr<CWallet>>::const_iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
100 if (i != vpwallets.end())
return false;
101 vpwallets.push_back(wallet);
102 wallet->ConnectScriptPubKeyManNotifiers();
103 wallet->NotifyCanGetAddressesChanged();
112 std::string
name = wallet->GetName();
115 wallet->m_chain_notifications_handler.reset();
117 std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
118 if (i == vpwallets.end())
return false;
129 std::vector<bilingual_str> warnings;
142 for (
const std::shared_ptr<CWallet>& wallet : vpwallets) {
143 if (wallet->GetName() ==
name)
return wallet;
151 auto it = g_load_wallet_fns.emplace(g_load_wallet_fns.end(), std::move(load_wallet));
158 static std::set<std::string> g_loading_wallet_set
GUARDED_BY(g_loading_wallet_mutex);
159 static std::set<std::string> g_unloading_wallet_set
GUARDED_BY(g_wallet_release_mutex);
170 LOCK(g_wallet_release_mutex);
171 if (g_unloading_wallet_set.erase(name) == 0) {
182 const std::string
name = wallet->GetName();
184 LOCK(g_wallet_release_mutex);
185 auto it = g_unloading_wallet_set.insert(name);
191 wallet->NotifyUnload();
197 while (g_unloading_wallet_set.count(name) == 1) {
207 std::unique_ptr<WalletDatabase> database =
MakeWalletDatabase(name, options, status, error);
220 wallet->postInitProcess();
226 }
catch (
const std::runtime_error& e) {
236 auto result =
WITH_LOCK(g_loading_wallet_mutex,
return g_loading_wallet_set.insert(name));
237 if (!result.second) {
242 auto wallet = LoadWalletInternal(chain, name, load_on_start, options, status, error, warnings);
243 WITH_LOCK(g_loading_wallet_mutex, g_loading_wallet_set.erase(result.first));
258 if (!passphrase.empty()) {
263 std::unique_ptr<WalletDatabase> database =
MakeWalletDatabase(name, options, status, error);
272 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.");
278 std::shared_ptr<CWallet> wallet =
CWallet::Create(chain, name, std::move(database), wallet_creation_flags, error, warnings);
287 if (!wallet->EncryptWallet(passphrase)) {
288 error =
Untranslated(
"Error: Wallet created but failed to encrypt.");
294 if (!wallet->Unlock(passphrase)) {
295 error =
Untranslated(
"Error: Wallet was encrypted but could not be unlocked");
302 LOCK(wallet->cs_wallet);
303 if (wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
304 wallet->SetupDescriptorScriptPubKeyMans();
306 for (
auto spk_man : wallet->GetActiveScriptPubKeyMans()) {
307 if (!spk_man->SetupGeneration()) {
308 error =
Untranslated(
"Unable to generate initial keys");
321 wallet->postInitProcess();
343 std::map<uint256, CWalletTx>::const_iterator
it = mapWallet.find(hash);
344 if (it == mapWallet.end())
346 return &(it->second);
360 spk_man->UpgradeKeyMetadata();
371 for (
const MasterKeyMap::value_type& pMasterKey :
mapMasterKeys)
373 if(!crypter.
SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
375 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
377 if (
Unlock(_vMasterKey, accept_no_keys)) {
399 if(!crypter.
SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
401 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
406 crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
407 pMasterKey.second.nDeriveIterations =
static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(
GetTimeMillis() - nStartTime))));
410 crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
411 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations +
static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(
GetTimeMillis() - nStartTime)))) / 2;
413 if (pMasterKey.second.nDeriveIterations < 25000)
414 pMasterKey.second.nDeriveIterations = 25000;
416 WalletLogPrintf(
"Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
418 if (!crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
420 if (!crypter.
Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
442 if (nWalletVersion >= nVersion)
444 nWalletVersion = nVersion;
448 if (nWalletVersion > 40000)
457 std::set<uint256> result;
460 std::map<uint256, CWalletTx>::const_iterator
it = mapWallet.find(txid);
461 if (it == mapWallet.end())
465 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
467 for (
const CTxIn& txin : wtx.
tx->vin)
469 if (mapTxSpends.count(txin.
prevout) <= 1)
471 range = mapTxSpends.equal_range(txin.
prevout);
472 for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
473 result.insert(_it->second);
481 auto iter = mapTxSpends.lower_bound(
COutPoint(txid, 0));
482 return (iter != mapTxSpends.end() && iter->first.hash == txid);
501 int nMinOrderPos = std::numeric_limits<int>::max();
503 for (TxSpends::iterator
it = range.first;
it != range.second; ++
it) {
516 for (TxSpends::iterator
it = range.first;
it != range.second; ++
it)
520 if (copyFrom == copyTo)
continue;
521 assert(copyFrom &&
"Oldest wallet transaction in range assumed to have been found.");
541 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
542 range = mapTxSpends.equal_range(outpoint);
544 for (TxSpends::const_iterator
it = range.first;
it != range.second; ++
it)
547 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
548 if (mit != mapWallet.end()) {
549 int depth = mit->second.GetDepthInMainChain();
550 if (depth > 0 || (depth == 0 && !mit->second.isAbandoned()))
559 mapTxSpends.insert(std::make_pair(outpoint, wtxid));
561 setLockedCoins.erase(outpoint);
563 std::pair<TxSpends::iterator, TxSpends::iterator> range;
564 range = mapTxSpends.equal_range(outpoint);
571 auto it = mapWallet.find(wtxid);
572 assert(
it != mapWallet.end());
574 if (thisTx.IsCoinBase())
577 for (
const CTxIn& txin : thisTx.tx->vin)
620 delete encrypted_batch;
621 encrypted_batch =
nullptr;
627 auto spk_man = spk_man_pair.second.get();
628 if (!spk_man->Encrypt(_vMasterKey, encrypted_batch)) {
630 delete encrypted_batch;
631 encrypted_batch =
nullptr;
642 delete encrypted_batch;
643 encrypted_batch =
nullptr;
649 delete encrypted_batch;
650 encrypted_batch =
nullptr;
653 Unlock(strWalletPassphrase);
660 if (spk_man->IsHDEnabled()) {
661 if (!spk_man->SetupGeneration(
true)) {
675 database->ReloadDbEnv();
692 typedef std::multimap<int64_t, CWalletTx*>
TxItems;
695 for (
auto& entry : mapWallet)
702 std::vector<int64_t> nOrderPosOffsets;
703 for (TxItems::iterator
it = txByTime.begin();
it != txByTime.end(); ++
it)
710 nOrderPos = nOrderPosNext++;
711 nOrderPosOffsets.push_back(nOrderPos);
718 int64_t nOrderPosOff = 0;
719 for (
const int64_t& nOffsetStart : nOrderPosOffsets)
721 if (nOrderPos >= nOffsetStart)
724 nOrderPos += nOrderPosOff;
725 nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
743 int64_t nRet = nOrderPosNext++;
756 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
757 item.second.MarkDirty();
765 auto mi = mapWallet.find(originalHash);
768 assert(mi != mapWallet.end());
773 assert(wtx.mapValue.count(
"replaced_by_txid") == 0);
781 WalletLogPrintf(
"%s: Updating batch tx %s failed\n", __func__, wtx.GetHash().ToString());
801 tx_destinations.insert(dst);
803 }
else if (!used &&
GetDestData(dst,
"used",
nullptr)) {
815 assert(srctx->
tx->vout.size() > n);
825 assert(spk_man !=
nullptr);
826 for (
const auto& keyid :
GetAffectedKeys(srctx->
tx->vout[n].scriptPubKey, *spk_man)) {
855 std::set<CTxDestination> tx_destinations;
857 for (
const CTxIn& txin : tx->vin) {
866 auto ret = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(
this, tx));
868 bool fInsertedNew = ret.second;
869 bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew);
897 if (tx->HasWitness() && !wtx.
tx->HasWitness()) {
904 WalletLogPrintf(
"AddToWallet %s %s%s\n", hash.
ToString(), (fInsertedNew ?
"new" :
""), (fUpdated ?
"update" :
""));
907 if (fInsertedNew || fUpdated)
919 std::string strCmd =
gArgs.
GetArg(
"-walletnotify",
"");
923 boost::replace_all(strCmd,
"%s", hash.
GetHex());
932 std::thread t(runCommand, strCmd);
942 const auto& ins = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(
this,
nullptr));
944 if (!fill_wtx(wtx, ins.second)) {
971 for (
const CTxIn& txin : wtx.
tx->vin) {
973 if (
it != mapWallet.end()) {
991 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.
prevout);
992 while (range.first != range.second) {
993 if (range.first->second != tx.
GetHash()) {
994 WalletLogPrintf(
"Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.
GetHash().
ToString(), confirm.
hashBlock.
ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
1002 bool fExisted = mapWallet.count(tx.
GetHash()) != 0;
1003 if (fExisted && !fUpdate)
return false;
1015 spk_man_pair.second->MarkUnusedAddresses(txout.
scriptPubKey);
1036 for (
const CTxIn& txin : tx->vin) {
1038 if (
it != mapWallet.end()) {
1039 it->second.MarkDirty();
1050 std::set<uint256> todo;
1051 std::set<uint256> done;
1054 auto it = mapWallet.find(hashTx);
1055 assert(
it != mapWallet.end());
1057 if (origtx.GetDepthInMainChain() != 0 || origtx.InMempool()) {
1061 todo.insert(hashTx);
1063 while (!todo.empty()) {
1067 auto it = mapWallet.find(now);
1068 assert(
it != mapWallet.end());
1070 int currentconfirm = wtx.GetDepthInMainChain();
1072 assert(currentconfirm <= 0);
1074 if (currentconfirm == 0 && !wtx.isAbandoned()) {
1076 assert(!wtx.InMempool());
1082 TxSpends::const_iterator iter = mapTxSpends.lower_bound(
COutPoint(now, 0));
1083 while (iter != mapTxSpends.end() && iter->first.hash == now) {
1084 if (!done.count(iter->second)) {
1085 todo.insert(iter->second);
1102 int conflictconfirms = (m_last_block_processed_height - conflicting_height + 1) * -1;
1107 if (conflictconfirms >= 0)
1113 std::set<uint256> todo;
1114 std::set<uint256> done;
1116 todo.insert(hashTx);
1118 while (!todo.empty()) {
1122 auto it = mapWallet.find(now);
1123 assert(
it != mapWallet.end());
1125 int currentconfirm = wtx.GetDepthInMainChain();
1126 if (conflictconfirms < currentconfirm) {
1129 wtx.m_confirm.nIndex = 0;
1130 wtx.m_confirm.hashBlock = hashBlock;
1131 wtx.m_confirm.block_height = conflicting_height;
1132 wtx.setConflicted();
1136 TxSpends::const_iterator iter = mapTxSpends.lower_bound(
COutPoint(now, 0));
1137 while (iter != mapTxSpends.end() && iter->first.hash == now) {
1138 if (!done.count(iter->second)) {
1139 todo.insert(iter->second);
1165 auto it = mapWallet.find(tx->GetHash());
1166 if (it != mapWallet.end()) {
1167 it->second.fInMempool =
true;
1173 auto it = mapWallet.find(tx->GetHash());
1174 if (
it != mapWallet.end()) {
1175 it->second.fInMempool =
false;
1214 m_last_block_processed_height = height;
1215 m_last_block_processed = block_hash;
1216 for (
size_t index = 0; index < block.
vtx.size(); index++) {
1217 SyncTransaction(block.
vtx[index], {CWalletTx::Status::CONFIRMED, height, block_hash, (int)index});
1230 m_last_block_processed_height = height - 1;
1243 void CWallet::BlockUntilSyncedToCurrentChain()
const {
1257 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.
prevout.
hash);
1258 if (mi != mapWallet.end())
1273 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.
prevout.
hash);
1274 if (mi != mapWallet.end())
1302 result = std::max(result, spk_man_pair.second->IsMine(script));
1310 throw std::runtime_error(std::string(__func__) +
": value out of range");
1346 throw std::runtime_error(std::string(__func__) +
": value out of range");
1371 throw std::runtime_error(std::string(__func__) +
": value out of range");
1383 if (mi == mapWallet.end())
1404 throw std::runtime_error(std::string(__func__) +
": value out of range");
1417 throw std::runtime_error(std::string(__func__) +
": value out of range");
1427 result &= spk_man->IsHDEnabled();
1438 if (spk_man && spk_man->CanGetAddresses(
internal)) {
1450 throw std::runtime_error(std::string(__func__) +
": writing wallet flags failed");
1464 throw std::runtime_error(std::string(__func__) +
": writing wallet flags failed");
1495 throw std::runtime_error(std::string(__func__) +
": writing wallet flags failed");
1533 for (
const auto& txout : txouts)
1550 LOCK(spk_man->cs_KeyStore);
1551 return spk_man->ImportScripts(scripts, timestamp);
1560 LOCK(spk_man->cs_KeyStore);
1561 return spk_man->ImportPrivKeys(privkey_map, timestamp);
1564 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)
1570 LOCK(spk_man->cs_KeyStore);
1571 return spk_man->ImportPubKeys(ordered_pubkeys, pubkey_map, key_origins, add_keypool,
internal, timestamp);
1574 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)
1580 LOCK(spk_man->cs_KeyStore);
1581 if (!spk_man->ImportScriptPubKeys(script_pub_keys, have_solving_data, timestamp)) {
1586 for (
const CScript& script : script_pub_keys) {
1599 std::vector<CTxOut> txouts;
1600 for (
const CTxIn& input : tx.
vin) {
1601 const auto mi = wallet->mapWallet.find(input.
prevout.
hash);
1603 if (mi == wallet->mapWallet.end()) {
1606 assert(input.
prevout.
n < mi->second.tx->vout.size());
1607 txouts.emplace_back(mi->second.tx->vout[input.
prevout.
n]);
1616 if (!wallet->
DummySignTx(txNew, txouts, use_max_sig)) {
1636 listReceived.clear();
1644 nFee = nDebit - nValueOut;
1649 for (
unsigned int i = 0; i <
tx->vout.size(); ++i)
1662 else if (!(fIsMine & filter))
1679 listSent.push_back(output);
1682 if (fIsMine & filter)
1683 listReceived.push_back(output);
1701 int start_height = 0;
1704 WalletLogPrintf(
"%s: Rescanning last %i blocks\n", __func__, start ?
WITH_LOCK(cs_wallet,
return GetLastBlockHeight()) - start_height + 1 : 0);
1708 ScanResult result = ScanForWalletTransactions(start_block, start_height, {} , reserver, update);
1709 if (result.
status == ScanResult::FAILURE) {
1746 uint256 block_hash = start_block;
1749 WalletLogPrintf(
"Rescan started from block %s...\n", start_block.
ToString());
1751 fAbortRescan =
false;
1758 double progress_current = progress_begin;
1759 int block_height = start_height;
1760 while (!fAbortRescan && !chain().shutdownRequested()) {
1761 if (progress_end - progress_begin > 0.0) {
1762 m_scanning_progress = (progress_current - progress_begin) / (progress_end - progress_begin);
1764 m_scanning_progress = 0;
1766 if (block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
1767 ShowProgress(
strprintf(
"%s " +
_(
"Rescanning...").translated, GetDisplayName()), std::max(1, std::min(99, (
int)(m_scanning_progress * 100))));
1771 WalletLogPrintf(
"Still rescanning. At block %d. Progress=%f\n", block_height, progress_current);
1778 if (chain().findBlock(block_hash,
FoundBlock().data(block)) && !block.
IsNull()) {
1787 result.
status = ScanResult::FAILURE;
1790 for (
size_t posInBlock = 0; posInBlock < block.
vtx.size(); ++posInBlock) {
1791 SyncTransaction(block.
vtx[posInBlock], {CWalletTx::Status::CONFIRMED, block_height, block_hash, (int)posInBlock}, fUpdate);
1799 result.
status = ScanResult::FAILURE;
1802 if (max_height && block_height >= *max_height) {
1806 if (!next_block || reorg) {
1813 block_hash = next_block_hash;
1818 const uint256 prev_tip_hash = tip_hash;
1819 tip_hash =
WITH_LOCK(cs_wallet,
return GetLastBlockHash());
1820 if (!max_height && prev_tip_hash != tip_hash) {
1827 if (block_height && fAbortRescan) {
1828 WalletLogPrintf(
"Rescan aborted at block %d. Progress=%f\n", block_height, progress_current);
1829 result.
status = ScanResult::USER_ABORT;
1830 }
else if (block_height && chain().shutdownRequested()) {
1831 WalletLogPrintf(
"Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height, progress_current);
1832 result.
status = ScanResult::USER_ABORT;
1834 WalletLogPrintf(
"Rescan completed in %15dms\n",
GetTimeMillis() - start_time);
1842 if (!fBroadcastTransactions)
1844 std::map<int64_t, CWalletTx*> mapSorted;
1847 for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
1848 const uint256& wtxid = item.first;
1850 assert(wtx.
GetHash() == wtxid);
1855 mapSorted.insert(std::make_pair(wtx.
nOrderPos, &wtx));
1860 for (
const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
1862 std::string unused_err_string;
1897 std::set<uint256> result;
1902 result.erase(myHash);
1910 if (recalculate || !amount.m_cached[filter]) {
1914 return amount.m_value[filter];
1919 if (
tx->vin.empty())
1977 for (
unsigned int i = 0; i <
tx->vout.size(); i++)
1983 throw std::runtime_error(std::string(__func__) +
" : value out of range");
2020 std::set<uint256> trusted_parents;
2029 if (!chain().checkFinalTx(*wtx.
tx))
return false;
2031 if (nDepth >= 1)
return true;
2032 if (nDepth < 0)
return false;
2040 for (
const CTxIn& txin : wtx.
tx->vin)
2044 if (parent ==
nullptr)
return false;
2049 if (trusted_parents.count(parent->
GetHash()))
continue;
2051 if (!
IsTrusted(*parent, trusted_parents))
return false;
2052 trusted_parents.insert(parent->
GetHash());
2061 for (
auto& txin : tx1.vin) txin.scriptSig =
CScript();
2062 for (
auto& txin : tx2.vin) txin.scriptSig =
CScript();
2079 if (!chain().isReadyToBroadcast())
return;
2083 if (
GetTime() < nNextResend || !fBroadcastTransactions)
return;
2084 bool fFirst = (nNextResend == 0);
2086 nNextResend =
GetTime() + (12 * 60 * 60) +
GetRand(24 * 60 * 60);
2089 int submitted_tx_count = 0;
2095 for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
2100 if (wtx.
nTimeReceived > m_best_block_time - 5 * 60)
continue;
2101 std::string unused_err_string;
2106 if (submitted_tx_count > 0) {
2107 WalletLogPrintf(
"%s: resubmit %u unconfirmed transactions\n", __func__, submitted_tx_count);
2133 std::set<uint256> trusted_parents;
2134 for (
const auto& entry : mapWallet)
2137 const bool is_trusted{
IsTrusted(wtx, trusted_parents)};
2141 if (is_trusted && tx_depth >= min_depth) {
2145 if (!is_trusted && tx_depth == 0 && wtx.
InMempool()) {
2161 std::vector<COutput>
vCoins;
2162 AvailableCoins(vCoins,
true, coinControl);
2163 for (
const COutput& out : vCoins) {
2164 if (out.fSpendable) {
2165 balance += out.tx->tx->vout[out.i].nValue;
2183 std::set<uint256> trusted_parents;
2184 for (
const auto& entry : mapWallet)
2186 const uint256& wtxid = entry.first;
2205 bool safeTx =
IsTrusted(wtx, trusted_parents);
2222 if (nDepth == 0 && wtx.
mapValue.count(
"replaces_txid")) {
2234 if (nDepth == 0 && wtx.
mapValue.count(
"replaced_by_txid")) {
2238 if (fOnlySafe && !safeTx) {
2242 if (nDepth < min_depth || nDepth > max_depth) {
2246 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
2252 if (wtx.
tx->vout[i].nValue < nMinimumAmount || wtx.
tx->vout[i].nValue > nMaximumAmount)
2258 if (IsLockedCoin(entry.first, i))
2261 if (IsSpent(wtxid, i))
2270 if (!allow_used_addresses && IsSpentKey(wtxid, i)) {
2274 std::unique_ptr<SigningProvider> provider = GetSolvingProvider(wtx.
tx->vout[i].scriptPubKey);
2276 bool solvable = provider ?
IsSolvable(*provider, wtx.
tx->vout[i].scriptPubKey) :
false;
2279 vCoins.push_back(
COutput(&wtx, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->
fAllowWatchOnly)));
2283 nTotal += wtx.
tx->vout[i].nValue;
2285 if (nTotal >= nMinimumSumAmount) {
2291 if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) {
2302 std::map<CTxDestination, std::vector<COutput>> result;
2303 std::vector<COutput> availableCoins;
2305 AvailableCoins(availableCoins);
2307 for (
const COutput& coin : availableCoins) {
2310 ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
2311 result[address].emplace_back(std::move(coin));
2315 std::vector<COutPoint> lockedCoins;
2316 ListLockedCoins(lockedCoins);
2320 for (
const COutPoint& output : lockedCoins) {
2321 auto it = mapWallet.find(output.hash);
2322 if (
it != mapWallet.end()) {
2323 int depth =
it->second.GetDepthInMainChain();
2324 if (depth >= 0 && output.n <
it->second.tx->vout.size() &&
2325 IsMine(
it->second.tx->vout[output.n]) == is_mine_filter
2328 if (
ExtractDestination(FindNonChangeParentOutput(*
it->second.tx, output.n).scriptPubKey, address)) {
2329 result[address].emplace_back(
2330 &
it->second, output.n, depth,
true ,
true ,
false );
2344 while (IsChange(ptx->
vout[n]) && ptx->
vin.size() > 0) {
2346 auto it = mapWallet.find(prevout.
hash);
2347 if (
it == mapWallet.end() ||
it->second.tx->vout.size() <= prevout.
n ||
2348 !IsMine(
it->second.tx->vout[prevout.
n])) {
2351 ptx =
it->second.tx.get();
2354 return ptx->
vout[n];
2360 setCoinsRet.clear();
2363 std::vector<OutputGroup> utxo_pool;
2364 if (coin_selection_params.
use_bnb) {
2376 if (!group.EligibleForSpending(eligibility_filter))
continue;
2380 group.SetFees(
CFeeRate(0) , long_term_feerate);
2382 group.SetFees(coin_selection_params.
effective_fee, long_term_feerate);
2391 return SelectCoinsBnB(utxo_pool, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
2395 if (!group.EligibleForSpending(eligibility_filter))
continue;
2396 utxo_pool.push_back(group);
2399 return KnapsackSolver(nTargetValue, utxo_pool, setCoinsRet, nValueRet);
2405 std::vector<COutput>
vCoins(vAvailableCoins);
2406 CAmount value_to_select = nTargetValue;
2414 for (
const COutput& out : vCoins)
2416 if (!out.fSpendable)
2418 nValueRet += out.tx->tx->vout[out.i].nValue;
2419 setCoinsRet.insert(out.GetInputCoin());
2421 return (nValueRet >= nTargetValue);
2425 std::set<CInputCoin> setPresetCoins;
2426 CAmount nValueFromPresetInputs = 0;
2428 std::vector<COutPoint> vPresetInputs;
2430 for (
const COutPoint& outpoint : vPresetInputs)
2432 std::map<uint256, CWalletTx>::const_iterator
it = mapWallet.find(outpoint.hash);
2433 if (it != mapWallet.end())
2437 if (wtx.
tx->vout.size() <= outpoint.n) {
2443 if (coin.m_input_bytes <= 0) {
2446 coin.effective_value = coin.txout.nValue - coin_selection_params.
effective_fee.
GetFee(coin.m_input_bytes);
2447 if (coin_selection_params.
use_bnb) {
2448 value_to_select -= coin.effective_value;
2450 value_to_select -= coin.txout.nValue;
2452 setPresetCoins.insert(coin);
2459 for (std::vector<COutput>::iterator
it = vCoins.begin();
it != vCoins.end() && coin_control.
HasSelected();)
2461 if (setPresetCoins.count(
it->GetInputCoin()))
2462 it = vCoins.erase(
it);
2467 unsigned int limit_ancestor_count = 0;
2468 unsigned int limit_descendant_count = 0;
2470 size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
2471 size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
2482 std::vector<OutputGroup> groups = GroupOutputs(vCoins, !coin_control.
m_avoid_partial_spends, max_ancestors);
2484 bool res = value_to_select <= 0 ||
2485 SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(1, 6, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2486 SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(1, 1, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2487 (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(0, 1, 2), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2488 (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(0, 1, std::min((
size_t)4, max_ancestors/3), std::min((
size_t)4, max_descendants/3)), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2489 (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(0, 1, max_ancestors/2, max_descendants/2), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2490 (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(0, 1, max_ancestors-1, max_descendants-1), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2491 (m_spend_zero_conf_change && !fRejectLongChains && SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(0, 1, std::numeric_limits<uint64_t>::max()), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used));
2497 nValueRet += nValueFromPresetInputs;
2507 std::map<COutPoint, Coin> coins;
2508 for (
auto& input : tx.
vin) {
2509 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
2510 if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
2516 std::map<int, std::string> input_errors;
2526 if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2542 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
2543 const CTxIn& txin = psbtx.
tx->vin[i];
2553 const auto it = mapWallet.find(txhash);
2554 if (
it != mapWallet.end()) {
2565 int n_signed_this_spkm = 0;
2566 TransactionError res = spk_man->FillPSBT(psbtx, sighash_type, sign, bip32derivs, &n_signed_this_spkm);
2572 (*n_signed) += n_signed_this_spkm;
2578 for (
const auto& input : psbtx.
inputs) {
2589 for (
const auto& spk_man_pair : m_spk_managers) {
2590 if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
2591 return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
2599 std::vector<CRecipient> vecSend;
2602 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
2605 vecSend.push_back(recipient);
2620 if (!CreateTransaction(vecSend, tx_new, nFeeRet, nChangePosInOut, error, coinControl, fee_calc_out,
false)) {
2624 if (nChangePosInOut != -1) {
2625 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
2630 for (
unsigned int idx = 0; idx < tx.
vout.size(); idx++) {
2631 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
2635 for (
const CTxIn& txin : tx_new->vin) {
2637 tx.
vin.push_back(txin);
2654 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
2657 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
2691 locktime = block_height;
2698 locktime = std::max(0, (
int)locktime -
GetRandInt(100));
2713 return *change_type;
2724 for (
const auto& recipient : vecSend) {
2726 int witnessversion = 0;
2727 std::vector<unsigned char> witnessprogram;
2728 if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
2734 return m_default_address_type;
2738 const std::vector<CRecipient>& vecSend,
2741 int& nChangePosInOut,
2750 int nChangePosRequest = nChangePosInOut;
2751 unsigned int nSubtractFeeFromAmount = 0;
2752 for (
const auto& recipient : vecSend)
2754 if (nValue < 0 || recipient.nAmount < 0)
2756 error =
_(
"Transaction amounts must not be negative");
2759 nValue += recipient.nAmount;
2761 if (recipient.fSubtractFeeFromAmount)
2762 nSubtractFeeFromAmount++;
2764 if (vecSend.empty())
2766 error =
_(
"Transaction must have at least one recipient");
2775 std::set<CInputCoin> setCoins;
2779 std::vector<COutput> vAvailableCoins;
2789 if (!boost::get<CNoDestination>(&coin_control.
destChange)) {
2803 error =
_(
"Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.");
2811 CTxOut change_prototype_txout(0, scriptChange);
2826 bool pick_new_inputs =
true;
2831 coin_selection_params.
use_bnb =
true;
2836 nChangePosInOut = nChangePosRequest;
2841 CAmount nValueToSelect = nValue;
2842 if (nSubtractFeeFromAmount == 0)
2843 nValueToSelect += nFeeRet;
2849 for (
const auto& recipient : vecSend)
2851 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
2853 if (recipient.fSubtractFeeFromAmount)
2855 assert(nSubtractFeeFromAmount != 0);
2856 txout.
nValue -= nFeeRet / nSubtractFeeFromAmount;
2861 txout.
nValue -= nFeeRet % nSubtractFeeFromAmount;
2869 if (
IsDust(txout, chain().relayDustFee()))
2871 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
2874 error =
_(
"The transaction amount is too small to pay the fee");
2876 error =
_(
"The transaction amount is too small to send after the fee has been deducted");
2879 error =
_(
"Transaction amount too small");
2882 txNew.
vout.push_back(txout);
2886 bool bnb_used =
false;
2887 if (pick_new_inputs) {
2893 if (change_spend_size == -1) {
2899 if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coin_control, coin_selection_params, bnb_used))
2903 coin_selection_params.
use_bnb =
false;
2907 error =
_(
"Insufficient funds");
2915 const CAmount nChange = nValueIn - nValueToSelect;
2919 CTxOut newTxOut(nChange, scriptChange);
2924 if (
IsDust(newTxOut, discard_rate) || bnb_used)
2926 nChangePosInOut = -1;
2931 if (nChangePosInOut == -1)
2936 else if ((
unsigned int)nChangePosInOut > txNew.
vout.size())
2938 error =
_(
"Change index out of range");
2942 std::vector<CTxOut>::iterator position = txNew.
vout.begin()+nChangePosInOut;
2943 txNew.
vout.insert(position, newTxOut);
2946 nChangePosInOut = -1;
2951 for (
const auto& coin : setCoins) {
2957 error =
_(
"Signing transaction failed");
2961 nFeeNeeded =
GetMinimumFee(*
this, nBytes, coin_control, &feeCalc);
2964 error =
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
2968 if (nFeeRet >= nFeeNeeded) {
2979 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
2980 unsigned int tx_size_with_change = nBytes + coin_selection_params.
change_output_size + 2;
2981 CAmount fee_needed_with_change =
GetMinimumFee(*
this, tx_size_with_change, coin_control,
nullptr);
2983 if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
2984 pick_new_inputs =
false;
2985 nFeeRet = fee_needed_with_change;
2991 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
2992 CAmount extraFeePaid = nFeeRet - nFeeNeeded;
2993 std::vector<CTxOut>::iterator change_position = txNew.
vout.begin()+nChangePosInOut;
2994 change_position->nValue += extraFeePaid;
2995 nFeeRet -= extraFeePaid;
2999 else if (!pick_new_inputs) {
3004 error =
_(
"Transaction fee and change calculation failed");
3009 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3010 CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet;
3011 std::vector<CTxOut>::iterator change_position = txNew.
vout.begin()+nChangePosInOut;
3014 change_position->nValue -= additionalFeeNeeded;
3015 nFeeRet += additionalFeeNeeded;
3022 if (nSubtractFeeFromAmount > 0) {
3023 pick_new_inputs =
false;
3027 nFeeRet = nFeeNeeded;
3028 coin_selection_params.
use_bnb =
false;
3033 if (scriptChange.empty() && nChangePosInOut != -1) {
3040 std::vector<CInputCoin> selected_coins(setCoins.begin(), setCoins.end());
3052 for (
const auto& coin : selected_coins) {
3057 error =
_(
"Signing transaction failed");
3067 error =
_(
"Transaction too large");
3072 if (nFeeRet > m_default_max_tx_fee) {
3080 error =
_(
"Transaction has too long of a mempool chain");
3088 fee_calc_out = feeCalc;
3090 WalletLogPrintf(
"Fee Calculation: Fee:%d Bytes:%u Needed:%d Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
3102 const std::vector<CRecipient>& vecSend,
3105 int& nChangePosInOut,
3111 int nChangePosIn = nChangePosInOut;
3113 bool res = CreateTransactionInternal(vecSend, tx, nFeeRet, nChangePosInOut, error, coin_control, fee_calc_out, sign);
3119 int nChangePosInOut2 = nChangePosIn;
3121 if (CreateTransactionInternal(vecSend, tx2, nFeeRet2, nChangePosInOut2, error2, tmp_cc, fee_calc_out, sign)) {
3123 const bool use_aps = nFeeRet2 <= nFeeRet + m_max_aps_fee;
3124 WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n", nFeeRet, nFeeRet2, use_aps ?
"grouped" :
"non-grouped");
3128 nChangePosInOut = nChangePosInOut2;
3138 WalletLogPrintf(
"CommitTransaction:\n%s", tx->ToString());
3142 AddToWallet(tx, {}, [&](
CWalletTx& wtx,
bool new_tx) {
3145 wtx.
mapValue = std::move(mapValue);
3153 for (
const CTxIn& txin : tx->vin) {
3161 CWalletTx& wtx = mapWallet.at(tx->GetHash());
3163 if (!fBroadcastTransactions) {
3168 std::string err_string;
3170 WalletLogPrintf(
"CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
3179 fFirstRunRet =
false;
3183 if (database->Rewrite(
"\x04pool"))
3185 for (
const auto& spk_man_pair : m_spk_managers) {
3186 spk_man_pair.second->RewriteDB();
3194 assert(m_external_spk_managers.empty());
3195 assert(m_internal_spk_managers.empty());
3199 return nLoadWalletRet;
3208 for (
const uint256& hash : vHashOut) {
3209 const auto&
it = mapWallet.find(hash);
3210 wtxOrdered.erase(
it->second.m_it_wtxOrdered);
3211 for (
const auto& txin :
it->second.tx->vin)
3212 mapTxSpends.erase(txin.prevout);
3213 mapWallet.erase(
it);
3219 if (database->Rewrite(
"\x04pool"))
3221 for (
const auto& spk_man_pair : m_spk_managers) {
3222 spk_man_pair.second->RewriteDB();
3228 return nZapSelectTxRet;
3237 bool fUpdated =
false;
3241 std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find(address);
3242 fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
3243 m_address_book[address].SetLabel(strName);
3244 if (!strPurpose.empty())
3245 m_address_book[address].purpose = strPurpose;
3258 return SetAddressBookWithDB(batch, address, strName, strPurpose);
3270 if (IsMine(address)) {
3271 WalletLogPrintf(
"%s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n", __func__,
PACKAGE_BUGREPORT);
3276 for (
const std::pair<const std::string, std::string> &item : m_address_book[address].destdata)
3280 m_address_book.erase(address);
3294 unsigned int count = 0;
3295 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
3296 count += spk_man->KeypoolCountExternalKeys();
3306 unsigned int count = 0;
3307 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
3308 count += spk_man->GetKeyPoolSize();
3317 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
3318 res &= spk_man->TopUp(kpSize);
3327 bool result =
false;
3328 auto spk_man = GetScriptPubKeyMan(type,
false );
3331 result = spk_man->GetNewDestination(type, dest, error);
3336 SetAddressBook(dest, label,
"receive");
3349 error =
_(
"Error: Keypool ran out, please call keypoolrefill first").
translated;
3360 int64_t oldestKey = std::numeric_limits<int64_t>::max();
3361 for (
const auto& spk_man_pair : m_spk_managers) {
3362 oldestKey = std::min(oldestKey, spk_man_pair.second->GetOldestKeyPoolTime());
3368 for (
auto& entry : mapWallet) {
3371 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
3383 std::map<CTxDestination, CAmount> balances;
3387 std::set<uint256> trusted_parents;
3388 for (
const auto& walletEntry : mapWallet)
3390 const CWalletTx& wtx = walletEntry.second;
3402 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++)
3405 if (!IsMine(wtx.
tx->vout[i]))
3410 CAmount n = IsSpent(walletEntry.first, i) ? 0 : wtx.
tx->vout[i].nValue;
3411 balances[addr] += n;
3422 std::set< std::set<CTxDestination> > groupings;
3423 std::set<CTxDestination> grouping;
3425 for (
const auto& walletEntry : mapWallet)
3427 const CWalletTx& wtx = walletEntry.second;
3429 if (wtx.
tx->vin.size() > 0)
3431 bool any_mine =
false;
3433 for (
const CTxIn& txin : wtx.
tx->vin)
3440 grouping.insert(address);
3447 for (
const CTxOut& txout : wtx.
tx->vout)
3448 if (IsChange(txout))
3453 grouping.insert(txoutAddr);
3456 if (grouping.size() > 0)
3458 groupings.insert(grouping);
3464 for (
const auto& txout : wtx.
tx->vout)
3470 grouping.insert(address);
3471 groupings.insert(grouping);
3476 std::set< std::set<CTxDestination>* > uniqueGroupings;
3477 std::map< CTxDestination, std::set<CTxDestination>* > setmap;
3478 for (std::set<CTxDestination> _grouping : groupings)
3481 std::set< std::set<CTxDestination>* > hits;
3482 std::map< CTxDestination, std::set<CTxDestination>* >::iterator
it;
3484 if ((it = setmap.find(address)) != setmap.end())
3485 hits.insert((*it).second);
3488 std::set<CTxDestination>* merged =
new std::set<CTxDestination>(_grouping);
3489 for (std::set<CTxDestination>* hit : hits)
3491 merged->insert(hit->begin(), hit->end());
3492 uniqueGroupings.erase(hit);
3495 uniqueGroupings.insert(merged);
3499 setmap[element] = merged;
3502 std::set< std::set<CTxDestination> > ret;
3503 for (
const std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
3505 ret.insert(*uniqueGrouping);
3506 delete uniqueGrouping;
3515 std::set<CTxDestination> result;
3516 for (
const std::pair<const CTxDestination, CAddressBookData>& item : m_address_book)
3518 if (item.second.IsChange())
continue;
3520 const std::string& strName = item.second.GetLabel();
3521 if (strName == label)
3522 result.insert(address);
3540 if (!m_spk_man->GetReservedDestination(type,
internal, address, nIndex, keypool)) {
3552 m_spk_man->KeepDestination(nIndex, type);
3561 m_spk_man->ReturnDestination(nIndex, fInternal, address);
3570 setLockedCoins.insert(output);
3576 setLockedCoins.erase(output);
3582 setLockedCoins.clear();
3590 return (setLockedCoins.count(outpt) > 0);
3596 for (std::set<COutPoint>::iterator
it = setLockedCoins.begin();
3597 it != setLockedCoins.end();
it++) {
3599 vOutpts.push_back(outpt);
3607 mapKeyBirth.clear();
3610 assert(spk_man !=
nullptr);
3614 for (
const auto& entry : spk_man->mapKeyMetadata) {
3615 if (entry.second.nCreateTime) {
3616 mapKeyBirth[entry.first] = entry.second.nCreateTime;
3621 std::map<CKeyID, const CWalletTx::Confirmation*> mapKeyFirstBlock;
3623 max_confirm.
block_height = GetLastBlockHeight() > 144 ? GetLastBlockHeight() - 144 : 0;
3626 if (mapKeyBirth.count(keyid) == 0)
3627 mapKeyFirstBlock[keyid] = &max_confirm;
3631 if (mapKeyFirstBlock.empty())
3635 for (
const auto& entry : mapWallet) {
3640 for (
const CTxOut &txout : wtx.
tx->vout) {
3644 auto rit = mapKeyFirstBlock.find(keyid);
3654 for (
const auto& entry : mapKeyFirstBlock) {
3689 int64_t latestEntry = 0;
3692 int64_t latestTolerated = latestNow + 300;
3693 const TxItems& txOrdered = wtxOrdered;
3694 for (
auto it = txOrdered.rbegin();
it != txOrdered.rend(); ++
it) {
3704 if (nSmartTime <= latestTolerated) {
3705 latestEntry = nSmartTime;
3706 if (nSmartTime > latestNow) {
3707 latestNow = nSmartTime;
3713 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
3723 if (boost::get<CNoDestination>(&dest))
3726 m_address_book[dest].destdata.insert(std::make_pair(key, value));
3732 if (!m_address_book[dest].destdata.erase(key))
3739 m_address_book[dest].destdata.insert(std::make_pair(key, value));
3744 std::map<CTxDestination, CAddressBookData>::const_iterator i = m_address_book.find(dest);
3745 if(i != m_address_book.end())
3747 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
3748 if(j != i->second.destdata.end())
3760 std::vector<std::string> values;
3761 for (
const auto& address : m_address_book) {
3762 for (
const auto& data : address.second.destdata) {
3763 if (!data.first.compare(0, prefix.size(),
prefix)) {
3764 values.emplace_back(data.second);
3779 const fs::path& wallet_path = fs::absolute(name,
GetWalletDir());
3780 fs::file_type path_type = fs::symlink_status(wallet_path).type();
3781 if (!(path_type == fs::file_not_found || path_type == fs::directory_file ||
3782 (path_type == fs::symlink_file && fs::is_directory(wallet_path)) ||
3783 (path_type == fs::regular_file && fs::path(name).filename() == name))) {
3785 "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
3786 "database/log.?????????? files can be stored, a location where such a directory could be created, "
3787 "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
3792 return MakeDatabase(wallet_path, options, status, error_string);
3797 const std::string& walletFile = database->Filename();
3802 bool fFirstRun =
true;
3805 std::shared_ptr<CWallet> walletInstance(
new CWallet(&chain, name, std::move(database)),
ReleaseWallet);
3806 DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
3809 error =
strprintf(
_(
"Error loading %s: Wallet corrupted"), walletFile);
3814 warnings.push_back(
strprintf(
_(
"Error reading %s! All keys read correctly, but transaction data"
3815 " or address book entries might be missing or incorrect."),
3828 error =
strprintf(
_(
"Error loading %s"), walletFile);
3838 walletInstance->AddWalletFlags(wallet_creation_flags);
3842 walletInstance->SetupLegacyScriptPubKeyMan();
3846 LOCK(walletInstance->cs_wallet);
3848 walletInstance->SetupDescriptorScriptPubKeyMans();
3852 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
3853 if (!spk_man->SetupGeneration()) {
3854 error =
_(
"Unable to generate initial keys");
3864 error =
strprintf(
_(
"Error loading %s: Private keys can only be disabled during creation"), walletFile);
3866 }
else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
3867 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
3868 if (spk_man->HavePrivateKeys()) {
3869 warnings.push_back(
strprintf(
_(
"Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
3888 walletInstance->m_default_change_type = out_type;
3899 _(
"This is the minimum transaction fee you pay on every transaction."));
3901 walletInstance->m_min_fee =
CFeeRate(n);
3905 const std::string max_aps_fee{
gArgs.
GetArg(
"-maxapsfee",
"")};
3907 if (max_aps_fee ==
"-1") {
3915 _(
"This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection."));
3917 walletInstance->m_max_aps_fee = n;
3923 error =
strprintf(
_(
"Invalid amount for -fallbackfee=<amount>: '%s'"),
gArgs.
GetArg(
"-fallbackfee",
""));
3928 _(
"This is the transaction fee you may pay when fee estimates are not available."));
3930 walletInstance->m_fallback_fee =
CFeeRate(nFeePerK);
3933 walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
3938 error =
strprintf(
_(
"Invalid amount for -discardfee=<amount>: '%s'"),
gArgs.
GetArg(
"-discardfee",
""));
3943 _(
"This is the transaction fee you may discard if change is smaller than dust at this level"));
3945 walletInstance->m_discard_rate =
CFeeRate(nFeePerK);
3955 _(
"This is the transaction fee you will pay if you send a transaction."));
3957 walletInstance->m_pay_tx_fee =
CFeeRate(nFeePerK, 1000);
3958 if (walletInstance->m_pay_tx_fee < chain.
relayMinFee()) {
3959 error =
strprintf(
_(
"Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
3972 warnings.push_back(
_(
"-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
3975 error =
strprintf(
_(
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
3979 walletInstance->m_default_max_tx_fee = nMaxFee;
3984 _(
"The wallet will avoid paying less than the minimum relay fee."));
3991 walletInstance->WalletLogPrintf(
"Wallet completed loading in %15dms\n",
GetTimeMillis() - nStart);
3994 walletInstance->TopUpKeyPool();
3996 LOCK(walletInstance->cs_wallet);
4006 walletInstance->m_chain_notifications_handler = walletInstance->chain().handleNotifications(walletInstance);
4008 int rescan_height = 0;
4015 rescan_height = *fork_height;
4022 walletInstance->m_last_block_processed = chain.
getBlockHash(*tip_height);
4023 walletInstance->m_last_block_processed_height = *tip_height;
4025 walletInstance->m_last_block_processed.
SetNull();
4026 walletInstance->m_last_block_processed_height = -1;
4029 if (tip_height && *tip_height != rescan_height)
4038 int block_height = *tip_height;
4039 while (block_height > 0 && chain.
haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
4043 if (rescan_height != block_height) {
4044 error =
_(
"Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
4050 walletInstance->WalletLogPrintf(
"Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
4056 for (
auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
4057 int64_t time = spk_man->GetTimeFirstKey();
4058 if (!time_first_key || time < *time_first_key) time_first_key = time;
4060 if (time_first_key) {
4062 rescan_height = *first_block;
4068 if (!reserver.
reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.
getBlockHash(rescan_height), rescan_height, {} , reserver,
true ).status)) {
4069 error =
_(
"Failed to rescan the wallet during initialization");
4074 walletInstance->database->IncrementUpdateCounter();
4079 for (
auto& load_wallet : g_load_wallet_fns) {
4087 walletInstance->WalletLogPrintf(
"setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
4088 walletInstance->WalletLogPrintf(
"mapWallet.size() = %u\n", walletInstance->mapWallet.size());
4089 walletInstance->WalletLogPrintf(
"m_address_book.size() = %u\n", walletInstance->m_address_book.size());
4092 return walletInstance;
4097 const auto& address_book_it = m_address_book.find(dest);
4098 if (address_book_it == m_address_book.end())
return nullptr;
4099 if ((!allow_change) && address_book_it->second.IsChange()) {
4102 return &address_book_it->second;
4107 int prev_version = GetVersion();
4109 WalletLogPrintf(
"Performing wallet upgrade to %i\n",
FEATURE_LATEST);
4112 WalletLogPrintf(
"Allowing wallet upgrade up to %i\n", version);
4114 if (version < prev_version)
4116 error =
_(
"Cannot downgrade wallet");
4124 error =
_(
"Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use version 169900 or no version specified.");
4131 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
4132 if (!spk_man->Upgrade(prev_version, version, error)) {
4145 ReacceptWalletTransactions();
4153 return database->Backup(strDest);
4160 m_pre_split =
false;
4166 vchPubKey = vchPubKeyIn;
4167 fInternal = internalIn;
4168 m_pre_split =
false;
4185 assert(chain_depth >= 0);
4195 std::vector<OutputGroup>
CWallet::GroupOutputs(
const std::vector<COutput>& outputs,
bool single_coin,
const size_t max_ancestors)
const {
4196 std::vector<OutputGroup> groups;
4197 std::map<CTxDestination, OutputGroup> gmap;
4198 std::set<CTxDestination> full_groups;
4200 for (
const auto& output : outputs) {
4201 if (output.fSpendable) {
4203 CInputCoin input_coin = output.GetInputCoin();
4205 size_t ancestors, descendants;
4207 if (!single_coin &&
ExtractDestination(output.tx->tx->vout[output.i].scriptPubKey, dst)) {
4208 auto it = gmap.find(dst);
4209 if (
it != gmap.end()) {
4216 groups.push_back(
it->second);
4218 full_groups.insert(dst);
4220 it->second.Insert(input_coin, output.nDepth, output.tx->IsFromMe(
ISMINE_ALL), ancestors, descendants);
4222 gmap[dst].Insert(input_coin, output.nDepth, output.tx->IsFromMe(
ISMINE_ALL), ancestors, descendants);
4225 groups.emplace_back(input_coin, output.nDepth, output.tx->IsFromMe(
ISMINE_ALL), ancestors, descendants);
4230 for (
auto&
it : gmap) {
4231 auto& group =
it.second;
4232 if (full_groups.count(
it.first) > 0) {
4234 group.m_ancestors = max_ancestors - 1;
4236 groups.push_back(group);
4244 return HasEncryptionKeys();
4253 return vMasterKey.empty();
4266 NotifyStatusChanged(
this);
4274 for (
const auto& spk_man_pair : m_spk_managers) {
4275 if (!spk_man_pair.second->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) {
4279 vMasterKey = vMasterKeyIn;
4281 NotifyStatusChanged(
this);
4287 std::set<ScriptPubKeyMan*> spk_mans;
4288 for (
bool internal : {
false,
true}) {
4290 auto spk_man = GetScriptPubKeyMan(t,
internal);
4292 spk_mans.insert(spk_man);
4301 std::set<ScriptPubKeyMan*> spk_mans;
4302 for (
const auto& spk_man_pair : m_spk_managers) {
4303 spk_mans.insert(spk_man_pair.second.get());
4310 const std::map<OutputType, ScriptPubKeyMan*>& spk_managers =
internal ? m_internal_spk_managers : m_external_spk_managers;
4311 std::map<OutputType, ScriptPubKeyMan*>::const_iterator
it = spk_managers.find(type);
4312 if (it == spk_managers.end()) {
4313 WalletLogPrintf(
"%s scriptPubKey Manager for output type %d does not exist\n",
internal ?
"Internal" :
"External", static_cast<int>(type));
4321 std::set<ScriptPubKeyMan*> spk_mans;
4322 for (
const auto& spk_man_pair : m_spk_managers) {
4323 if (spk_man_pair.second->CanProvide(script, sigdata)) {
4324 spk_mans.insert(spk_man_pair.second.get());
4333 for (
const auto& spk_man_pair : m_spk_managers) {
4334 if (spk_man_pair.second->CanProvide(script, sigdata)) {
4335 return spk_man_pair.second.get();
4343 if (m_spk_managers.count(
id) > 0) {
4344 return m_spk_managers.at(
id).get();
4352 return GetSolvingProvider(script, sigdata);
4357 for (
const auto& spk_man_pair : m_spk_managers) {
4358 if (spk_man_pair.second->CanProvide(script, sigdata)) {
4359 return spk_man_pair.second->GetSolvingProvider(script);
4373 if (
it == m_internal_spk_managers.end())
return nullptr;
4379 SetupLegacyScriptPubKeyMan();
4380 return GetLegacyScriptPubKeyMan();
4385 if (!m_internal_spk_managers.empty() || !m_external_spk_managers.empty() || !m_spk_managers.empty() || IsWalletFlagSet(
WALLET_FLAG_DESCRIPTORS)) {
4391 m_internal_spk_managers[type] = spk_manager.get();
4392 m_external_spk_managers[type] = spk_manager.get();
4394 m_spk_managers[spk_manager->GetID()] = std::move(spk_manager);
4404 return !mapMasterKeys.empty();
4409 for (
const auto& spk_man : GetActiveScriptPubKeyMans()) {
4418 m_spk_managers[id] = std::move(spk_manager);
4427 seed_key.MakeNewKey(
true);
4428 CPubKey seed = seed_key.GetPubKey();
4429 assert(seed_key.VerifyPubKey(seed));
4433 master_key.
SetSeed(seed_key.begin(), seed_key.size());
4435 for (
bool internal : {
false,
true}) {
4440 throw std::runtime_error(std::string(__func__) +
": Wallet is locked, cannot setup new descriptors");
4442 if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey,
nullptr)) {
4443 throw std::runtime_error(std::string(__func__) +
": Could not encrypt new descriptors");
4446 spk_manager->SetupDescriptorGeneration(master_key, t);
4447 uint256 id = spk_manager->GetID();
4448 m_spk_managers[id] = std::move(spk_manager);
4449 AddActiveScriptPubKeyMan(
id, t,
internal);
4458 throw std::runtime_error(std::string(__func__) +
": writing active ScriptPubKeyMan id failed");
4460 LoadActiveScriptPubKeyMan(
id, type,
internal);
4465 WalletLogPrintf(
"Setting spkMan to active: id = %s, type = %d, internal = %d\n",
id.
ToString(), static_cast<int>(type), static_cast<int>(
internal));
4466 auto& spk_mans =
internal ? m_internal_spk_managers : m_external_spk_managers;
4467 auto spk_man = m_spk_managers.at(
id).get();
4468 spk_man->SetInternal(
internal);
4469 spk_mans[type] = spk_man;
4480 return spk_man !=
nullptr;
4485 for (
auto& spk_man_pair : m_spk_managers) {
4499 WalletLogPrintf(
"Cannot add WalletDescriptor to a non-descriptor wallet\n");
4507 auto old_spk_man = GetDescriptorScriptPubKeyMan(desc);
4509 WalletLogPrintf(
"Update existing descriptor: %s\n", desc.
descriptor->ToString());
4512 LOCK(old_spk_man->cs_desc_man);
4513 new_spk_man->SetCache(old_spk_man->GetWalletDescriptor().cache);
4517 auto old_spk_man_id = old_spk_man->GetID();
4518 for (
bool internal : {
false,
true}) {
4520 auto active_spk_man = GetScriptPubKeyMan(t,
internal);
4521 if (active_spk_man && active_spk_man->GetID() == old_spk_man_id) {
4523 m_internal_spk_managers.erase(t);
4525 m_external_spk_managers.erase(t);
4531 m_spk_managers.erase(old_spk_man_id);
4535 for (
const auto& entry : signing_provider.
keys) {
4536 const CKey& key = entry.second;
4537 new_spk_man->AddDescriptorKey(key, key.GetPubKey());
4541 if (!new_spk_man->TopUp()) {
4542 WalletLogPrintf(
"Could not top up scriptPubKeys\n");
4549 auto script_pub_keys = new_spk_man->GetScriptPubKeys();
4550 if (script_pub_keys.empty()) {
4551 WalletLogPrintf(
"Could not generate scriptPubKeys (cache is empty)\n");
4557 SetAddressBook(dest, label,
"receive");
4562 auto ret = new_spk_man.get();
4563 m_spk_managers[new_spk_man->GetID()] = std::move(new_spk_man);
4566 ret->WriteDescriptor();
std::shared_ptr< const CTransaction > CTransactionRef
bool TxnCommit()
Commit current transaction.
constexpr CAmount HIGH_APS_FEE
discourage APS fee higher than this amount
static int64_t GetTransactionWeight(const CTransaction &tx)
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, take care to consider how DelAddressBook should handle it!
bool WriteName(const std::string &strAddress, const std::string &strName)
virtual bool haveBlockOnDisk(int height)=0
Check that the block is available on disk (i.e.
std::function< bool(CWalletTx &wtx, bool new_tx)> UpdateWalletTxFn
Callback for updating transaction metadata in mapWallet.
std::unique_ptr< SigningProvider > GetSolvingProvider(const CScript &script) const
Get the SigningProvider for a script.
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
void SetupLegacyScriptPubKeyMan()
Make a LegacyScriptPubKeyMan and set it for all types, internal, and external.
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
Helper for findBlock to selectively return pieces of block data.
void GetAmounts(std::list< COutputEntry > &listReceived, std::list< COutputEntry > &listSent, CAmount &nFee, const isminefilter &filter) const
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< unsigned char > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
void Close()
Close wallet database.
const uint256 & GetHash() const
bool IsWalletFlagSet(uint64_t flag) const override
check if a certain wallet flag is set
const std::map< uint64_t, std::string > WALLET_FLAG_CAVEATS
virtual Optional< int > getHeight()=0
Get current chain height, not including genesis block (returns 0 if chain only contains genesis block...
void SetSpentKeyState(WalletBatch &batch, const uint256 &hash, unsigned int n, bool used, std::set< CTxDestination > &tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void blockConnected(const CBlock &block, int height) override
virtual void getPackageLimits(unsigned int &limit_ancestor_count, unsigned int &limit_descendant_count)=0
Get the node's package limits.
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
unsigned int nDerivationMethod
0 = EVP_sha512() 1 = scrypt()
bool IsLegacy() const
Determine if we are a legacy wallet.
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
bool ErasePurpose(const std::string &strAddress)
bool IsFromMe(const CTransaction &tx) const
should probably be renamed to IsRelevantToMe
CAmount GetAvailableCredit(bool fUseCache=true, const isminefilter &filter=ISMINE_SPENDABLE) const NO_THREAD_SAFETY_ANALYSIS
static std::vector< std::shared_ptr< CWallet > > vpwallets GUARDED_BY(cs_wallets)
bool m_is_cache_empty
This flag is true if all m_amounts caches are empty.
virtual bool updateRwSetting(const std::string &name, const util::SettingsValue &value)=0
Write a setting to /settings.json.
void WalletLogPrintf(std::string fmt, Params...parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
static const uint32_t MAX_BIP125_RBF_SEQUENCE
CAmount GetCredit(const CTxOut &txout, const isminefilter &filter) const
bool DummySignTx(CMutableTransaction &txNew, const std::set< CTxOut > &txouts, bool use_max_sig=false) const
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
bool ReadBestBlock(CBlockLocator &locator)
std::map< std::string, std::string > mapValue_t
bool IsAllFromMe(const CTransaction &tx, const isminefilter &filter) const
Returns whether all of the inputs match the filter.
bilingual_str AmountErrMsg(const std::string &optname, const std::string &strValue)
std::shared_ptr< Descriptor > descriptor
CAmount GetImmatureWatchOnlyCredit(const bool fUseCache=true) const
CAmount GetAvailableBalance(const CCoinControl *coinControl=nullptr) const
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
virtual 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...
void UpgradeKeyMetadata() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo.
const unsigned int WALLET_CRYPTO_KEY_SIZE
constexpr CAmount HIGH_MAX_TX_FEE
-maxtxfee will warn if called with a higher fee than this amount (in satoshis)
void UnlockCoin(const COutPoint &output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
void SetMinVersion(enum WalletFeature, WalletBatch *batch_in=nullptr) override
signify that a particular wallet feature is now used.
std::shared_ptr< CWallet > GetWallet(const std::string &name)
void postInitProcess()
Wallet post-init setup Gives the wallet a chance to register repetitive tasks and complete post-init ...
isminetype IsMine(const CTxDestination &dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
TransactionError FillPSBT(PartiallySignedTransaction &psbtx, bool &complete, int sighash_type=1, bool sign=true, bool bip32derivs=true, size_t *n_signed=nullptr) const
Fills out a PSBT with information from the wallet.
std::map< CTxDestination, std::vector< COutput > > ListCoins() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Return list of available coins and locked coins grouped by non-change output address.
ScriptPubKeyMan * GetScriptPubKeyMan(const OutputType &type, bool internal) const
Get the ScriptPubKeyMan for the given OutputType and internal/external chain.
size_t change_output_size
std::atomic< int64_t > m_best_block_time
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
virtual uint256 getBlockHash(int height)=0
Get block hash. Height must be valid or this function will abort.
int64_t GetTimeMillis()
Returns the system time (not mockable)
Optional< T > MakeOptional(bool condition, T &&value)
Substitute for C++17 std::make_optional.
static const CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
static Mutex g_wallet_release_mutex
bool AddWallet(const std::shared_ptr< CWallet > &wallet)
Encryption/decryption context with key information.
RecursiveMutex cs_KeyStore
virtual Optional< int > findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256 *hash)=0
Return height of the first block in the chain with timestamp equal or greater than the given time and...
const CTxOut & FindNonChangeParentOutput(const CTransaction &tx, int output) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Find non-change parent output.
CAmount m_mine_untrusted_pending
Untrusted, but in mempool (pending)
Optional< CMutableTransaction > tx
std::vector< unsigned char > vchCryptedKey
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
CAmount m_value[ISMINE_ENUM_ELEMENTS]
std::map< CKeyID, CKey > keys
bool WriteMinVersion(int nVersion)
virtual int64_t getAdjustedTime()=0
Get adjusted time.
bool AddWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Add wallet name to persistent configuration so it will be loaded on startup.
void ReacceptWalletTransactions() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
void AvailableCoins(std::vector< COutput > &vCoins, bool fOnlySafe=true, const CCoinControl *coinControl=nullptr, const CAmount &nMinimumAmount=1, const CAmount &nMaximumAmount=MAX_MONEY, const CAmount &nMinimumSumAmount=MAX_MONEY, const uint64_t nMaximumCount=0) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
populate vCoins with vector of available COutputs.
bool SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &target_value, const CAmount &cost_of_change, std::set< CInputCoin > &out_set, CAmount &value_ret, CAmount not_input_fees)
static const uint32_t SEQUENCE_FINAL
const std::vector< UniValue > & getValues() const
std::string GetHex() const
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
virtual bool isInitialBlockDownload()=0
Check if in IBD.
bool MoneyRange(const CAmount &nValue)
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
CAmount GetMinimumFee(const CWallet &wallet, unsigned int nTxBytes, const CCoinControl &coin_control, FeeCalculation *feeCalc)
Estimate the minimum fee considering user set parameters and the required fee.
bool IsChange(const CTxOut &txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
static CTransactionRef MakeTransactionRef()
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
int64_t nOrderPos
position in ordered transaction list
bool Decrypt(const std::vector< unsigned char > &vchCiphertext, CKeyingMaterial &vchPlaintext) const
std::multimap< int64_t, CWalletTx * >::const_iterator m_it_wtxOrdered
CFeeRate GetDiscardRate(const CWallet &wallet)
Return the maximum feerate for discarding change.
void blockDisconnected(const CBlock &block, int height) override
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule) ...
const CKeyingMaterial & GetEncryptionKey() const override
bool CanGetAddresses(bool internal=false) const
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
bool HasWalletDescriptor(const WalletDescriptor &desc) const
CAmount m_mine_trusted
Trusted, at depth=GetBalance.min_depth or more.
CAmount m_watchonly_untrusted_pending
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
static auto & nullopt
Substitute for C++17 std::nullopt.
int m_min_depth
Minimum chain depth value for coin availability.
Use sat/vB fee rate unit.
CAmount m_watchonly_immature
WalletFeature GetClosestWalletFeature(int version)
void MarkDirty()
make sure balances are recalculated
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
std::vector< std::shared_ptr< CWallet > > GetWallets()
bool IsLocked() const override
void MaybeResendWalletTxs()
Called periodically by the schedule thread.
bilingual_str TransactionErrorString(const TransactionError err)
int64_t GetTxTime() const
A version of CTransaction with the PSBT format.
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
bool TxnBegin()
Begin a new transaction.
CAmount m_default_max_tx_fee
Absolute maximum transaction fee (in satoshis) used by default for the wallet.
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
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.
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
bool WriteTx(const CWalletTx &wtx)
const CWalletTx * GetWalletTx(const uint256 &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
static RecursiveMutex cs_wallets
bool ParseMoney(const std::string &money_string, CAmount &nRet)
Parse an amount denoted in full coins.
CAmount GetImmatureCredit(bool fUseCache=true) const
DBErrors LoadWallet(CWallet *pwallet)
void ListSelected(std::vector< COutPoint > &vOutpoints) const
CAmount GetCredit(const isminefilter &filter) const
void chainStateFlushed(const CBlockLocator &loc) override
boost::signals2::signal< void(CWallet *wallet)> NotifyStatusChanged
Wallet status (encrypted, locked) changed.
bool MarkReplaced(const uint256 &originalHash, const uint256 &newHash)
Mark a transaction as replaced by another transaction (e.g., BIP 125).
DBErrors
Error statuses for the wallet database.
std::vector< OutputGroup > GroupOutputs(const std::vector< COutput > &outputs, bool single_coin, const size_t max_ancestors) const
bool EncryptWallet(const SecureString &strWalletPassphrase)
bool WriteWalletFlags(const uint64_t flags)
int GetLastBlockHeight() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get last block processed height.
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
CAmount m_watchonly_trusted
virtual double guessVerificationProgress(const uint256 &block_hash)=0
Estimate fraction of total transactions verified if blocks up to the specified block hash are verifie...
int GetSpendSize(unsigned int out, bool use_max_sig=false) const
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool fFromMe
From me flag is set to 1 for transactions that were created by the wallet on this bitcoin node...
static const bool DEFAULT_WALLET_RBF
-walletrbf default
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Loads an active ScriptPubKeyMan for the specified type and internal.
WalletFeature
(client) version numbers for particular wallet features
CFeeRate GetMinimumFeeRate(const CWallet &wallet, const CCoinControl &coin_control, FeeCalculation *feeCalc)
Estimate the minimum fee rate considering user set parameters and the required fee.
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
virtual bool checkFinalTx(const CTransaction &tx)=0
Check if transaction will be final given chain height current time.
bool LoadWalletFlags(uint64_t flags)
Loads the flags into the wallet.
const std::vector< CTxIn > vin
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 GetBroadcastTransactions() const
Inquire whether this wallet broadcasts transactions.
bool IsEquivalentTo(const CWalletTx &tx) const
const std::array< OutputType, 3 > OUTPUT_TYPES
interfaces::Chain & chain() const
Interface for accessing chain state.
size_t GetSerializeSize(const T &t, int nVersion=0)
Access to the wallet database.
mapValue_t mapValue
Key/value map with information about the transaction.
std::string ToString() const
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::shared_ptr< CWallet > CreateWallet(interfaces::Chain &chain, const std::string &name, Optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
static Mutex g_loading_wallet_mutex
bool GetNewChangeDestination(const OutputType type, CTxDestination &dest, std::string &error)
int64_t CAmount
Amount in satoshis (Can be negative)
bool m_avoid_partial_spends
Avoid partial use of funds sent to a given address.
bool WriteBestBlock(const CBlockLocator &locator)
bool TxnAbort()
Abort current transaction.
boost::signals2::signal< void(CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged
Wallet transaction added, removed or updated.
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
bool HasEncryptionKeys() const override
std::string ToString(const T &t)
Locale-independent version of std::to_string.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
DBErrors ReorderTransactions()
Optional< bool > m_signal_bip125_rbf
Override the wallet's m_signal_rbf if set.
std::set< ScriptPubKeyMan * > GetAllScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans.
bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
static void NotifyCanGetAddressesChanged(WalletModel *walletmodel)
void UnsetWalletFlag(uint64_t flag)
Unsets a single wallet flag.
bool DelAddressBook(const CTxDestination &address)
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
bool error(const char *fmt, const Args &...args)
bool SelectCoins(const std::vector< COutput > &vAvailableCoins, const CAmount &nTargetValue, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet, const CCoinControl &coin_control, CoinSelectionParams &coin_selection_params, bool &bnb_used) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Select a set of coins such that nValueRet >= nTargetValue and at least all coins from coinControl are...
bool push_back(const UniValue &val)
unsigned int nMasterKeyMaxID
const int DEFAULT_MAX_DEPTH
fs::path GetWalletDir()
Get the path of the wallet directory.
void UnsetBlankWalletFlag(WalletBatch &batch) override
Unset the blank wallet flag and saves it to disk.
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
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.
int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
bool AbandonTransaction(const uint256 &hashTx)
DBErrors LoadWallet(bool &fFirstRunRet)
CAmount m_mine_immature
Immature coinbases in the main chain.
ScriptPubKeyMan * AddWalletDescriptor(WalletDescriptor &desc, const FlatSigningProvider &signing_provider, const std::string &label, bool internal)
Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type.
bool IsImmatureCoinBase() const
int GetBlocksToMaturity() const
int64_t GetOldestKeyPoolTime() const
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.
bool AddToWalletIfInvolvingMe(const CTransactionRef &tx, CWalletTx::Confirmation confirm, bool fUpdate) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Add a transaction to the wallet, or update it.
An input of a transaction.
bool FundTransaction(CMutableTransaction &tx, CAmount &nFeeRet, int &nChangePosInOut, bilingual_str &error, bool lockUnspents, const std::set< int > &setSubtractFeeFromOutputs, CCoinControl)
Insert additional inputs into the transaction by calling CreateTransaction();.
void GetKeyBirthTimes(std::map< CKeyID, int64_t > &mapKeyBirth) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
int CalculateMaximumSignedInputSize(const CTxOut &txout, const CWallet *wallet, bool use_max_sig)
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...
bool m_add_inputs
If false, only selected inputs are used.
void SetupDescriptorScriptPubKeyMans() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Create new DescriptorScriptPubKeyMans and add them to the wallet.
static void NotifyAddressBookChanged(WalletModel *walletmodel, const CTxDestination &address, const std::string &label, bool isMine, const std::string &purpose, ChangeType status)
void SetTx(CTransactionRef arg)
bilingual_str _(const char *psz)
Translation function.
Removed for conflict with in-block transaction.
static void UpdateWalletSetting(interfaces::Chain &chain, const std::string &wallet_name, 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...
void Set(isminefilter filter, CAmount value)
std::set< ScriptPubKeyMan * > GetActiveScriptPubKeyMans() const
Returns all unique ScriptPubKeyMans in m_internal_spk_managers and m_external_spk_managers.
AssertLockHeld(mempool.cs)
CTxDestination destChange
Custom change destination, if not set an address is generated.
bilingual_str AmountHighWarn(const std::string &optname)
bool TransactionCanBeAbandoned(const uint256 &hashTx) const
Return whether transaction can be abandoned.
std::set< uint256 > GetConflicts() const NO_THREAD_SAFETY_ANALYSIS
void Select(const COutPoint &output)
An encapsulated public key.
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
bool HaveChain() const
Interface to assert chain access.
DescriptorScriptPubKeyMan * GetDescriptorScriptPubKeyMan(const WalletDescriptor &desc) const
Return the DescriptorScriptPubKeyMan for a WalletDescriptor if it is already in the wallet...
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
void UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
static const bool DEFAULT_WALLETBROADCAST
const std::vector< CTxOut > vout
CAmount GetCachableAmount(AmountType type, const isminefilter &filter, bool recalculate=false) const
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses, and other watch only things, and is therefore "blank.".
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack...
SigningResult SignMessage(const std::string &message, const PKHash &pkhash, std::string &str_sig) const
const int DEFAULT_MIN_DEPTH
virtual void waitForNotificationsIfTipChanged(const uint256 &old_tip)=0
Wait for pending notifications to be processed unless block hash points to the current chain tip...
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
std::unique_ptr< interfaces::Handler > HandleLoadWallet(LoadWalletFn load_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.
virtual void requestMempoolTransactions(Notifications ¬ifications)=0
Synchronously send transactionAddedToMempool notifications about all current mempool transactions to ...
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)
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE
Default for -spendzeroconfchange.
unsigned int ComputeTimeSmart(const CWalletTx &wtx) const
Compute smart timestamp for a transaction being added to the wallet.
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
CAmount GetDebit(const CTxIn &txin, const isminefilter &filter) const
Returns amount of debit if the input matches the filter, otherwise returns 0.
isminetype
IsMine() return codes.
bool WriteOrderPosNext(int64_t nOrderPosNext)
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor &desc)
Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it.
#define WAIT_LOCK(cs, name)
An output of a transaction.
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 RemoveWallet(const std::shared_ptr< CWallet > &wallet, Optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
CWalletTx * AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation &confirm, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true)
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Descriptor with some wallet metadata.
static const unsigned int DEFAULT_TX_CONFIRM_TARGET
-txconfirmtarget default
bool IsFromMe(const isminefilter &filter) const
virtual void getTransactionAncestry(const uint256 &txid, size_t &ancestors, size_t &descendants)=0
Calculate mempool ancestor and descendant counts for the given transaction.
An outpoint - a combination of a transaction hash and an index n into its vout.
static const CAmount MIN_FINAL_CHANGE
final minimum change amount after paying for fees
bool SelectCoinsMinConf(const CAmount &nTargetValue, const CoinEligibilityFilter &eligibility_filter, std::vector< OutputGroup > groups, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet, const CoinSelectionParams &coin_selection_params, bool &bnb_used) const
Shuffle and select coins until nTargetValue is reached while avoiding small change; This method is st...
std::vector< CTxOut > vout
unsigned int fTimeReceivedIsTxTime
CAmount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
static const size_t OUTPUT_GROUP_MAX_ENTRIES
void ConnectScriptPubKeyManNotifiers()
Connect the signals from ScriptPubKeyMans to the signals in CWallet.
void SetSeed(const unsigned char *seed, unsigned int nSeedLen)
std::vector< PSBTInput > inputs
std::map< CTxDestination, CAmount > GetAddressBalances() const
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::unique_ptr< Wallet > MakeWallet(const std::shared_ptr< CWallet > &wallet)
Return implementation of Wallet interface.
void updatedBlockTip() override
void AddToSpends(const COutPoint &outpoint, const uint256 &wtxid) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void SyncMetaData(std::pair< TxSpends::iterator, TxSpends::iterator >) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
static uint32_t GetLocktimeForNewTransaction(interfaces::Chain &chain, const uint256 &block_hash, int block_height)
Return a height-based locktime for new transactions (uses the height of the current chain tip unless ...
RAII object to check and reserve a wallet rescan.
A transaction with a bunch of additional info that only the owner cares about.
size_t KeypoolCountExternalKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void MarkConflicted(const uint256 &hashBlock, int conflicting_height, const uint256 &hashTx)
bool IsSolvable(const SigningProvider &provider, const CScript &script)
static void ReleaseWallet(CWallet *wallet)
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::map< uint256, std::unique_ptr< ScriptPubKeyMan > > m_spk_managers
bool isConflicted() const
std::vector< CKeyID > GetAffectedKeys(const CScript &spk, const SigningProvider &provider)
static std::shared_ptr< CWallet > Create(interfaces::Chain &chain, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bilingual_str &error, std::vector< bilingual_str > &warnings)
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 ...
CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS]
std::string ShellEscape(const std::string &arg)
void SyncTransaction(const CTransactionRef &tx, CWalletTx::Confirmation confirm, bool update_tx=true) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
const std::string & FormatOutputType(OutputType type)
int64_t IncOrderPosNext(WalletBatch *batch=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Increment the next transaction order id.
void LockCoin(const COutPoint &output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
OutputGroup GetPositiveOnlyGroup()
static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS
Default for -walletrejectlongchains.
const unsigned int WALLET_CRYPTO_SALT_SIZE
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
virtual bool checkChainLimits(const CTransactionRef &tx)=0
Check if transaction will pass the mempool's chain limits.
std::vector< CTransactionRef > vtx
int m_max_depth
Maximum chain depth value for coin availability.
bool UpgradeWallet(int version, bilingual_str &error)
Upgrade the wallet.
std::set< CTxDestination > GetLabelAddresses(const std::string &label) const
void transactionAddedToMempool(const CTransactionRef &tx, uint64_t mempool_sequence) override
CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(0), 0)
virtual util::SettingsValue getRwSetting(const std::string &name)=0
Return /settings.json setting value.
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
void BlockUntilSyncedToCurrentChain() const EXCLUSIVE_LOCKS_REQUIRED(!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...
std::atomic< uint64_t > m_wallet_flags
MasterKeyMap mapMasterKeys
bool CreateTransaction(const std::vector< CRecipient > &vecSend, CTransactionRef &tx, CAmount &nFeeRet, int &nChangePosInOut, bilingual_str &error, const CCoinControl &coin_control, FeeCalculation &fee_calc_out, bool sign=true)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
virtual bool TopUp(unsigned int size=0)
Fills internal address pool.
void ResendWalletTransactions()
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
Serialized script, used inside transaction inputs and outputs.
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< unsigned char > &vchCiphertext) const
bool TopUpKeyPool(unsigned int kpSize=0)
bool SetAddressBookWithDB(WalletBatch &batch, const CTxDestination &address, const std::string &strName, const std::string &strPurpose)
static const int PROTOCOL_VERSION
network protocol versioning
static const unsigned int MAX_STANDARD_TX_WEIGHT
The maximum weight for transactions we're willing to relay/mine.
OutputType TransactionChangeType(const Optional< OutputType > &change_type, const std::vector< CRecipient > &vecSend)
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet...
static std::condition_variable g_wallet_release_cv
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
enum CWallet::ScanResult::@15 status
bool IsInMainChain() const
LegacyScriptPubKeyMan * GetLegacyScriptPubKeyMan() const
Get the LegacyScriptPubKeyMan which is used for all types, internal, and external.
static bool IsCurrentForAntiFeeSniping(interfaces::Chain &chain, const uint256 &block_hash)
static void NotifyTransactionChanged(WalletModel *walletmodel, const uint256 &hash, ChangeType status)
virtual void initMessage(const std::string &message)=0
Send init message.
bool RemoveWalletSetting(interfaces::Chain &chain, const std::string &wallet_name)
Remove wallet name from persistent configuration so it will not be loaded on startup.
A reference to a CKey: the Hash160 of its serialized public key.
void UpdateInput(CTxIn &input, const SignatureData &data)
std::string ToString() const
int GetDepthInMainChain() const NO_THREAD_SAFETY_ANALYSIS
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
bool GetReservedDestination(CTxDestination &pubkey, bool internal)
Reserve an address.
std::set< uint256 > GetConflicts(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get wallet transactions that conflict with given transaction (spend same outputs) ...
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Fee rate in satoshis per kilobyte: CAmount / kB.
void MarkInputsDirty(const CTransactionRef &tx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
#define AssertLockNotHeld(cs)
A wrapper to reserve an address from a wallet.
bool KnapsackSolver(const CAmount &nTargetValue, std::vector< OutputGroup > &groups, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet)
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
std::vector< unsigned char > vchSalt
bool LoadToWallet(const uint256 &hash, const UpdateWalletTxFn &fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool DummySignInput(CTxIn &tx_in, const CTxOut &txout, bool use_max_sig=false) const
std::string EncodeDestination(const CTxDestination &dest)
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
Optional< int > last_scanned_height
A mutable version of CTransaction.
SecureString create_passphrase
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
virtual Optional< int > getBlockHeight(const uint256 &hash)=0
Get block height above genesis block.
const uint256 & GetHash() const
bool PSBTInputSigned(const PSBTInput &input)
Checks whether a PSBTInput is already signed.
static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly)
static std::vector< COutput > vCoins
bool IsSpent(const uint256 &hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Outpoint is spent if any non-conflicted transaction spends it:
void Flush()
Flush wallet (bitdb flush)
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...
Optional< CFeeRate > m_feerate
Override the wallet's m_pay_tx_fee if set.
Optional< OutputType > m_change_type
Override the default change type if set, ignored if destChange is set.
unsigned int nTimeReceived
time received by this node
An encapsulated private key.
static const unsigned int LOCKTIME_THRESHOLD
The basic transaction that is broadcasted on the network and contained in blocks. ...
boost::optional< T > Optional
Substitute for C++17 std::optional.
std::shared_ptr< CWallet > LoadWallet(interfaces::Chain &chain, const std::string &name, Optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
std::vector< std::string > GetDestValues(const std::string &prefix) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Get all destination values matching a prefix.
Optional< DatabaseFormat > require_format
unsigned int nDeriveIterations
virtual CBlockLocator getTipLocator()=0
Get locator for the current chain tip.
ScanResult ScanForWalletTransactions(const uint256 &start_block, int start_height, Optional< int > max_height, const WalletRescanReserver &reserver, bool fUpdate)
Scan the block chain (starting in start_block) for transactions from or to us.
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver &reserver, bool update)
Scan active chain for relevant transactions after importing keys.
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
bool BackupWallet(const std::string &strDest) const
Indicate that this wallet supports DescriptorScriptPubKeyMan.
bool IsSelected(const COutPoint &output) const
bool IsSpentKey(const uint256 &hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
int64_t GetTime()
Return system time (or mocked time, if set)
int GetRandInt(int nMax) noexcept
CAmount GetChange(const CTxOut &txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::multimap< int64_t, CWalletTx * > TxItems
const CAddressBookData * FindAddressBookEntry(const CTxDestination &, bool allow_change=false) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Balance GetBalance(int min_depth=0, bool avoid_reuse=true) const
void transactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override
bool ParseOutputType(const std::string &type, OutputType &output_type)
bool Unlock(const CKeyingMaterial &vMasterKeyIn, bool accept_no_keys=false)
std::string StringForFeeReason(FeeReason reason)
bool SignTransaction(CMutableTransaction &tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
std::unique_ptr< WalletDatabase > MakeDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
virtual CFeeRate relayMinFee()=0
Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
virtual bool findNextBlock(const uint256 &block_hash, int block_height, const FoundBlock &next={}, bool *reorg=nullptr)=0
Find next block if block is part of current chain.
bool fInternal
Whether this keypool entry is in the internal keypool (for change outputs)
#define PACKAGE_BUGREPORT
std::set< CKeyID > GetKeys() const override
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig)
bool AddWalletFlags(uint64_t flags)
overwrite all flags by the given uint64_t returns false if unknown, non-tolerable flags are present ...
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.
virtual bool havePruned()=0
Check if any block has been pruned.
void AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
Adds the active ScriptPubKeyMan for the specified type and internal.
void UnsetWalletFlagWithDB(WalletBatch &batch, uint64_t flag)
Unsets a wallet flag and saves it to disk.
bool GetNewDestination(const OutputType type, const std::string label, CTxDestination &dest, std::string &error)
const CWallet *const pwallet
static constexpr uint64_t KNOWN_WALLET_FLAGS
CAmount GetChange() const
void KeepDestination()
Keep the address. Do not return it's key to the keypool when this object goes out of scope...
A key from a CWallet's keypool.
bool CreateTransactionInternal(const std::vector< CRecipient > &vecSend, CTransactionRef &tx, CAmount &nFeeRet, int &nChangePosInOut, bilingual_str &error, const CCoinControl &coin_control, FeeCalculation &fee_calc_out, bool sign)
constexpr CAmount HIGH_TX_FEE_PER_KB
Discourage users to set fees higher than this amount (in satoshis) per kB.
bool SubmitMemoryPoolAndRelay(std::string &err_string, bool relay)
bool IsTrusted(const CWalletTx &wtx, std::set< uint256 > &trusted_parents) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool EraseName(const std::string &strAddress)
std::vector< std::pair< std::string, std::string > > vOrderForm
void ReturnDestination()
Return reserved address.
bool isUnconfirmed() const
std::set< std::set< CTxDestination > > GetAddressGroupings() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE
Pre-calculated constants for input size estimation in virtual size