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) {
2370 if (!group.EligibleForSpending(eligibility_filter))
continue;
2385 return SelectCoinsBnB(utxo_pool, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
2389 if (!group.EligibleForSpending(eligibility_filter))
continue;
2390 utxo_pool.push_back(group);
2393 return KnapsackSolver(nTargetValue, utxo_pool, setCoinsRet, nValueRet);
2399 std::vector<COutput>
vCoins(vAvailableCoins);
2400 CAmount value_to_select = nTargetValue;
2408 for (
const COutput& out : vCoins)
2410 if (!out.fSpendable)
2412 nValueRet += out.tx->tx->vout[out.i].nValue;
2413 setCoinsRet.insert(out.GetInputCoin());
2415 return (nValueRet >= nTargetValue);
2419 std::set<CInputCoin> setPresetCoins;
2420 CAmount nValueFromPresetInputs = 0;
2422 std::vector<COutPoint> vPresetInputs;
2424 for (
const COutPoint& outpoint : vPresetInputs)
2426 std::map<uint256, CWalletTx>::const_iterator
it = mapWallet.find(outpoint.hash);
2427 if (it != mapWallet.end())
2431 if (wtx.
tx->vout.size() <= outpoint.n) {
2437 if (coin.m_input_bytes <= 0) {
2441 if (coin_selection_params.
use_bnb) {
2442 value_to_select -= coin.effective_value;
2444 value_to_select -= coin.txout.nValue;
2446 setPresetCoins.insert(coin);
2453 for (std::vector<COutput>::iterator
it = vCoins.begin();
it != vCoins.end() && coin_control.
HasSelected();)
2455 if (setPresetCoins.count(
it->GetInputCoin()))
2456 it = vCoins.erase(
it);
2461 unsigned int limit_ancestor_count = 0;
2462 unsigned int limit_descendant_count = 0;
2464 size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
2465 size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
2476 std::vector<OutputGroup> groups = GroupOutputs(vCoins, !coin_control.
m_avoid_partial_spends, max_ancestors);
2478 bool res = value_to_select <= 0 ||
2479 SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(1, 6, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2480 SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(1, 1, 0), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used) ||
2481 (m_spend_zero_conf_change && SelectCoinsMinConf(value_to_select,
CoinEligibilityFilter(0, 1, 2), groups, setCoinsRet, nValueRet, coin_selection_params, bnb_used)) ||
2482 (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)) ||
2483 (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)) ||
2484 (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)) ||
2485 (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));
2491 nValueRet += nValueFromPresetInputs;
2501 std::map<COutPoint, Coin> coins;
2502 for (
auto& input : tx.
vin) {
2503 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
2504 if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
2510 std::map<int, std::string> input_errors;
2520 if (spk_man->SignTransaction(tx, coins, sighash, input_errors)) {
2536 for (
unsigned int i = 0; i < psbtx.
tx->vin.size(); ++i) {
2537 const CTxIn& txin = psbtx.
tx->vin[i];
2547 const auto it = mapWallet.find(txhash);
2548 if (
it != mapWallet.end()) {
2559 int n_signed_this_spkm = 0;
2560 TransactionError res = spk_man->FillPSBT(psbtx, sighash_type, sign, bip32derivs, &n_signed_this_spkm);
2566 (*n_signed) += n_signed_this_spkm;
2572 for (
const auto& input : psbtx.
inputs) {
2583 for (
const auto& spk_man_pair : m_spk_managers) {
2584 if (spk_man_pair.second->CanProvide(script_pub_key, sigdata)) {
2585 return spk_man_pair.second->SignMessage(message, pkhash, str_sig);
2593 std::vector<CRecipient> vecSend;
2596 for (
size_t idx = 0; idx < tx.
vout.size(); idx++) {
2599 vecSend.push_back(recipient);
2614 if (!CreateTransaction(vecSend, tx_new, nFeeRet, nChangePosInOut, error, coinControl, fee_calc_out,
false)) {
2618 if (nChangePosInOut != -1) {
2619 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]);
2624 for (
unsigned int idx = 0; idx < tx.
vout.size(); idx++) {
2625 tx.
vout[idx].nValue = tx_new->vout[idx].nValue;
2629 for (
const CTxIn& txin : tx_new->vin) {
2631 tx.
vin.push_back(txin);
2648 constexpr int64_t MAX_ANTI_FEE_SNIPING_TIP_AGE = 8 * 60 * 60;
2651 if (block_time < (
GetTime() - MAX_ANTI_FEE_SNIPING_TIP_AGE)) {
2685 locktime = block_height;
2692 locktime = std::max(0, (
int)locktime -
GetRandInt(100));
2707 return *change_type;
2718 for (
const auto& recipient : vecSend) {
2720 int witnessversion = 0;
2721 std::vector<unsigned char> witnessprogram;
2722 if (recipient.scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
2728 return m_default_address_type;
2732 const std::vector<CRecipient>& vecSend,
2735 int& nChangePosInOut,
2744 int nChangePosRequest = nChangePosInOut;
2745 unsigned int nSubtractFeeFromAmount = 0;
2746 for (
const auto& recipient : vecSend)
2748 if (nValue < 0 || recipient.nAmount < 0)
2750 error =
_(
"Transaction amounts must not be negative");
2753 nValue += recipient.nAmount;
2755 if (recipient.fSubtractFeeFromAmount)
2756 nSubtractFeeFromAmount++;
2758 if (vecSend.empty())
2760 error =
_(
"Transaction must have at least one recipient");
2769 std::set<CInputCoin> setCoins;
2773 std::vector<COutput> vAvailableCoins;
2783 if (!boost::get<CNoDestination>(&coin_control.
destChange)) {
2797 error =
_(
"Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.");
2805 CTxOut change_prototype_txout(0, scriptChange);
2821 error =
_(
"Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
2831 bool pick_new_inputs =
true;
2836 coin_selection_params.
use_bnb =
true;
2841 nChangePosInOut = nChangePosRequest;
2846 CAmount nValueToSelect = nValue;
2847 if (nSubtractFeeFromAmount == 0)
2848 nValueToSelect += nFeeRet;
2854 for (
const auto& recipient : vecSend)
2856 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
2858 if (recipient.fSubtractFeeFromAmount)
2860 assert(nSubtractFeeFromAmount != 0);
2861 txout.
nValue -= nFeeRet / nSubtractFeeFromAmount;
2866 txout.
nValue -= nFeeRet % nSubtractFeeFromAmount;
2874 if (
IsDust(txout, chain().relayDustFee()))
2876 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
2879 error =
_(
"The transaction amount is too small to pay the fee");
2881 error =
_(
"The transaction amount is too small to send after the fee has been deducted");
2884 error =
_(
"Transaction amount too small");
2887 txNew.
vout.push_back(txout);
2891 bool bnb_used =
false;
2892 if (pick_new_inputs) {
2898 if (change_spend_size == -1) {
2903 if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coin_control, coin_selection_params, bnb_used))
2907 coin_selection_params.
use_bnb =
false;
2911 error =
_(
"Insufficient funds");
2919 const CAmount nChange = nValueIn - nValueToSelect;
2923 CTxOut newTxOut(nChange, scriptChange);
2930 nChangePosInOut = -1;
2935 if (nChangePosInOut == -1)
2940 else if ((
unsigned int)nChangePosInOut > txNew.
vout.size())
2942 error =
_(
"Change index out of range");
2946 std::vector<CTxOut>::iterator position = txNew.
vout.begin()+nChangePosInOut;
2947 txNew.
vout.insert(position, newTxOut);
2950 nChangePosInOut = -1;
2955 for (
const auto& coin : setCoins) {
2961 error =
_(
"Signing transaction failed");
2966 if (nFeeRet >= nFeeNeeded) {
2977 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
2978 unsigned int tx_size_with_change = nBytes + coin_selection_params.
change_output_size + 2;
2981 if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
2982 pick_new_inputs =
false;
2983 nFeeRet = fee_needed_with_change;
2989 if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
2990 CAmount extraFeePaid = nFeeRet - nFeeNeeded;
2991 std::vector<CTxOut>::iterator change_position = txNew.
vout.begin()+nChangePosInOut;
2992 change_position->nValue += extraFeePaid;
2993 nFeeRet -= extraFeePaid;
2997 else if (!pick_new_inputs) {
3002 error =
_(
"Transaction fee and change calculation failed");
3007 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3008 CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet;
3009 std::vector<CTxOut>::iterator change_position = txNew.
vout.begin()+nChangePosInOut;
3012 change_position->nValue -= additionalFeeNeeded;
3013 nFeeRet += additionalFeeNeeded;
3020 if (nSubtractFeeFromAmount > 0) {
3021 pick_new_inputs =
false;
3025 nFeeRet = nFeeNeeded;
3026 coin_selection_params.
use_bnb =
false;
3031 if (scriptChange.empty() && nChangePosInOut != -1) {
3038 std::vector<CInputCoin> selected_coins(setCoins.begin(), setCoins.end());
3050 for (
const auto& coin : selected_coins) {
3055 error =
_(
"Signing transaction failed");
3065 error =
_(
"Transaction too large");
3070 if (nFeeRet > m_default_max_tx_fee) {
3078 error =
_(
"Transaction has too long of a mempool chain");
3086 fee_calc_out = feeCalc;
3088 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",
3100 const std::vector<CRecipient>& vecSend,
3103 int& nChangePosInOut,
3109 int nChangePosIn = nChangePosInOut;
3111 bool res = CreateTransactionInternal(vecSend, tx, nFeeRet, nChangePosInOut, error, coin_control, fee_calc_out, sign);
3117 int nChangePosInOut2 = nChangePosIn;
3119 if (CreateTransactionInternal(vecSend, tx2, nFeeRet2, nChangePosInOut2, error2, tmp_cc, fee_calc_out, sign)) {
3121 const bool use_aps = nFeeRet2 <= nFeeRet + m_max_aps_fee;
3122 WalletLogPrintf(
"Fee non-grouped = %lld, grouped = %lld, using %s\n", nFeeRet, nFeeRet2, use_aps ?
"grouped" :
"non-grouped");
3126 nChangePosInOut = nChangePosInOut2;
3136 WalletLogPrintf(
"CommitTransaction:\n%s", tx->ToString());
3140 AddToWallet(tx, {}, [&](
CWalletTx& wtx,
bool new_tx) {
3143 wtx.
mapValue = std::move(mapValue);
3151 for (
const CTxIn& txin : tx->vin) {
3159 CWalletTx& wtx = mapWallet.at(tx->GetHash());
3161 if (!fBroadcastTransactions) {
3166 std::string err_string;
3168 WalletLogPrintf(
"CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
3177 fFirstRunRet =
false;
3181 if (database->Rewrite(
"\x04pool"))
3183 for (
const auto& spk_man_pair : m_spk_managers) {
3184 spk_man_pair.second->RewriteDB();
3192 assert(m_external_spk_managers.empty());
3193 assert(m_internal_spk_managers.empty());
3197 return nLoadWalletRet;
3206 for (
const uint256& hash : vHashOut) {
3207 const auto&
it = mapWallet.find(hash);
3208 wtxOrdered.erase(
it->second.m_it_wtxOrdered);
3209 for (
const auto& txin :
it->second.tx->vin)
3210 mapTxSpends.erase(txin.prevout);
3211 mapWallet.erase(
it);
3217 if (database->Rewrite(
"\x04pool"))
3219 for (
const auto& spk_man_pair : m_spk_managers) {
3220 spk_man_pair.second->RewriteDB();
3226 return nZapSelectTxRet;
3235 bool fUpdated =
false;
3239 std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find(address);
3240 fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
3241 m_address_book[address].SetLabel(strName);
3242 if (!strPurpose.empty())
3243 m_address_book[address].purpose = strPurpose;
3256 return SetAddressBookWithDB(batch, address, strName, strPurpose);
3268 if (IsMine(address)) {
3269 WalletLogPrintf(
"%s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n", __func__,
PACKAGE_BUGREPORT);
3274 for (
const std::pair<const std::string, std::string> &item : m_address_book[address].destdata)
3278 m_address_book.erase(address);
3292 unsigned int count = 0;
3293 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
3294 count += spk_man->KeypoolCountExternalKeys();
3304 unsigned int count = 0;
3305 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
3306 count += spk_man->GetKeyPoolSize();
3315 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
3316 res &= spk_man->TopUp(kpSize);
3325 bool result =
false;
3326 auto spk_man = GetScriptPubKeyMan(type,
false );
3329 result = spk_man->GetNewDestination(type, dest, error);
3334 SetAddressBook(dest, label,
"receive");
3347 error =
_(
"Error: Keypool ran out, please call keypoolrefill first").
translated;
3358 int64_t oldestKey = std::numeric_limits<int64_t>::max();
3359 for (
const auto& spk_man_pair : m_spk_managers) {
3360 oldestKey = std::min(oldestKey, spk_man_pair.second->GetOldestKeyPoolTime());
3366 for (
auto& entry : mapWallet) {
3369 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++) {
3381 std::map<CTxDestination, CAmount> balances;
3385 std::set<uint256> trusted_parents;
3386 for (
const auto& walletEntry : mapWallet)
3388 const CWalletTx& wtx = walletEntry.second;
3400 for (
unsigned int i = 0; i < wtx.
tx->vout.size(); i++)
3403 if (!IsMine(wtx.
tx->vout[i]))
3408 CAmount n = IsSpent(walletEntry.first, i) ? 0 : wtx.
tx->vout[i].nValue;
3409 balances[addr] += n;
3420 std::set< std::set<CTxDestination> > groupings;
3421 std::set<CTxDestination> grouping;
3423 for (
const auto& walletEntry : mapWallet)
3425 const CWalletTx& wtx = walletEntry.second;
3427 if (wtx.
tx->vin.size() > 0)
3429 bool any_mine =
false;
3431 for (
const CTxIn& txin : wtx.
tx->vin)
3438 grouping.insert(address);
3445 for (
const CTxOut& txout : wtx.
tx->vout)
3446 if (IsChange(txout))
3451 grouping.insert(txoutAddr);
3454 if (grouping.size() > 0)
3456 groupings.insert(grouping);
3462 for (
const auto& txout : wtx.
tx->vout)
3468 grouping.insert(address);
3469 groupings.insert(grouping);
3474 std::set< std::set<CTxDestination>* > uniqueGroupings;
3475 std::map< CTxDestination, std::set<CTxDestination>* > setmap;
3476 for (std::set<CTxDestination> _grouping : groupings)
3479 std::set< std::set<CTxDestination>* > hits;
3480 std::map< CTxDestination, std::set<CTxDestination>* >::iterator
it;
3482 if ((it = setmap.find(address)) != setmap.end())
3483 hits.insert((*it).second);
3486 std::set<CTxDestination>* merged =
new std::set<CTxDestination>(_grouping);
3487 for (std::set<CTxDestination>* hit : hits)
3489 merged->insert(hit->begin(), hit->end());
3490 uniqueGroupings.erase(hit);
3493 uniqueGroupings.insert(merged);
3497 setmap[element] = merged;
3500 std::set< std::set<CTxDestination> > ret;
3501 for (
const std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
3503 ret.insert(*uniqueGrouping);
3504 delete uniqueGrouping;
3513 std::set<CTxDestination> result;
3514 for (
const std::pair<const CTxDestination, CAddressBookData>& item : m_address_book)
3516 if (item.second.IsChange())
continue;
3518 const std::string& strName = item.second.GetLabel();
3519 if (strName == label)
3520 result.insert(address);
3538 if (!m_spk_man->GetReservedDestination(type,
internal, address, nIndex, keypool)) {
3550 m_spk_man->KeepDestination(nIndex, type);
3559 m_spk_man->ReturnDestination(nIndex, fInternal, address);
3568 setLockedCoins.insert(output);
3574 setLockedCoins.erase(output);
3580 setLockedCoins.clear();
3588 return (setLockedCoins.count(outpt) > 0);
3594 for (std::set<COutPoint>::iterator
it = setLockedCoins.begin();
3595 it != setLockedCoins.end();
it++) {
3597 vOutpts.push_back(outpt);
3605 mapKeyBirth.clear();
3608 assert(spk_man !=
nullptr);
3612 for (
const auto& entry : spk_man->mapKeyMetadata) {
3613 if (entry.second.nCreateTime) {
3614 mapKeyBirth[entry.first] = entry.second.nCreateTime;
3619 std::map<CKeyID, const CWalletTx::Confirmation*> mapKeyFirstBlock;
3621 max_confirm.
block_height = GetLastBlockHeight() > 144 ? GetLastBlockHeight() - 144 : 0;
3624 if (mapKeyBirth.count(keyid) == 0)
3625 mapKeyFirstBlock[keyid] = &max_confirm;
3629 if (mapKeyFirstBlock.empty())
3633 for (
const auto& entry : mapWallet) {
3638 for (
const CTxOut &txout : wtx.
tx->vout) {
3642 auto rit = mapKeyFirstBlock.find(keyid);
3652 for (
const auto& entry : mapKeyFirstBlock) {
3687 int64_t latestEntry = 0;
3690 int64_t latestTolerated = latestNow + 300;
3691 const TxItems& txOrdered = wtxOrdered;
3692 for (
auto it = txOrdered.rbegin();
it != txOrdered.rend(); ++
it) {
3702 if (nSmartTime <= latestTolerated) {
3703 latestEntry = nSmartTime;
3704 if (nSmartTime > latestNow) {
3705 latestNow = nSmartTime;
3711 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
3721 if (boost::get<CNoDestination>(&dest))
3724 m_address_book[dest].destdata.insert(std::make_pair(key, value));
3730 if (!m_address_book[dest].destdata.erase(key))
3737 m_address_book[dest].destdata.insert(std::make_pair(key, value));
3742 std::map<CTxDestination, CAddressBookData>::const_iterator i = m_address_book.find(dest);
3743 if(i != m_address_book.end())
3745 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
3746 if(j != i->second.destdata.end())
3758 std::vector<std::string> values;
3759 for (
const auto& address : m_address_book) {
3760 for (
const auto& data : address.second.destdata) {
3761 if (!data.first.compare(0, prefix.size(),
prefix)) {
3762 values.emplace_back(data.second);
3777 const fs::path& wallet_path = fs::absolute(name,
GetWalletDir());
3778 fs::file_type path_type = fs::symlink_status(wallet_path).type();
3779 if (!(path_type == fs::file_not_found || path_type == fs::directory_file ||
3780 (path_type == fs::symlink_file && fs::is_directory(wallet_path)) ||
3781 (path_type == fs::regular_file && fs::path(name).filename() == name))) {
3783 "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
3784 "database/log.?????????? files can be stored, a location where such a directory could be created, "
3785 "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
3790 return MakeDatabase(wallet_path, options, status, error_string);
3795 const std::string& walletFile = database->Filename();
3800 bool fFirstRun =
true;
3803 std::shared_ptr<CWallet> walletInstance(
new CWallet(&chain, name, std::move(database)),
ReleaseWallet);
3804 DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
3807 error =
strprintf(
_(
"Error loading %s: Wallet corrupted"), walletFile);
3812 warnings.push_back(
strprintf(
_(
"Error reading %s! All keys read correctly, but transaction data"
3813 " or address book entries might be missing or incorrect."),
3826 error =
strprintf(
_(
"Error loading %s"), walletFile);
3836 walletInstance->AddWalletFlags(wallet_creation_flags);
3840 walletInstance->SetupLegacyScriptPubKeyMan();
3844 LOCK(walletInstance->cs_wallet);
3846 walletInstance->SetupDescriptorScriptPubKeyMans();
3850 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
3851 if (!spk_man->SetupGeneration()) {
3852 error =
_(
"Unable to generate initial keys");
3862 error =
strprintf(
_(
"Error loading %s: Private keys can only be disabled during creation"), walletFile);
3864 }
else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
3865 for (
auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
3866 if (spk_man->HavePrivateKeys()) {
3867 warnings.push_back(
strprintf(
_(
"Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
3886 walletInstance->m_default_change_type = out_type;
3897 _(
"This is the minimum transaction fee you pay on every transaction."));
3899 walletInstance->m_min_fee =
CFeeRate(n);
3903 const std::string max_aps_fee{
gArgs.
GetArg(
"-maxapsfee",
"")};
3905 if (max_aps_fee ==
"-1") {
3913 _(
"This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection."));
3915 walletInstance->m_max_aps_fee = n;
3921 error =
strprintf(
_(
"Invalid amount for -fallbackfee=<amount>: '%s'"),
gArgs.
GetArg(
"-fallbackfee",
""));
3926 _(
"This is the transaction fee you may pay when fee estimates are not available."));
3928 walletInstance->m_fallback_fee =
CFeeRate(nFeePerK);
3931 walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
3936 error =
strprintf(
_(
"Invalid amount for -discardfee=<amount>: '%s'"),
gArgs.
GetArg(
"-discardfee",
""));
3941 _(
"This is the transaction fee you may discard if change is smaller than dust at this level"));
3943 walletInstance->m_discard_rate =
CFeeRate(nFeePerK);
3953 _(
"This is the transaction fee you will pay if you send a transaction."));
3955 walletInstance->m_pay_tx_fee =
CFeeRate(nFeePerK, 1000);
3956 if (walletInstance->m_pay_tx_fee < chain.
relayMinFee()) {
3957 error =
strprintf(
_(
"Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
3970 warnings.push_back(
_(
"-maxtxfee is set very high! Fees this large could be paid on a single transaction."));
3973 error =
strprintf(
_(
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
3977 walletInstance->m_default_max_tx_fee = nMaxFee;
3982 _(
"The wallet will avoid paying less than the minimum relay fee."));
3989 walletInstance->WalletLogPrintf(
"Wallet completed loading in %15dms\n",
GetTimeMillis() - nStart);
3992 walletInstance->TopUpKeyPool();
3994 LOCK(walletInstance->cs_wallet);
4004 walletInstance->m_chain_notifications_handler = walletInstance->chain().handleNotifications(walletInstance);
4006 int rescan_height = 0;
4013 rescan_height = *fork_height;
4020 walletInstance->m_last_block_processed = chain.
getBlockHash(*tip_height);
4021 walletInstance->m_last_block_processed_height = *tip_height;
4023 walletInstance->m_last_block_processed.
SetNull();
4024 walletInstance->m_last_block_processed_height = -1;
4027 if (tip_height && *tip_height != rescan_height)
4036 int block_height = *tip_height;
4037 while (block_height > 0 && chain.
haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
4041 if (rescan_height != block_height) {
4042 error =
_(
"Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)");
4048 walletInstance->WalletLogPrintf(
"Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
4054 for (
auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
4055 int64_t time = spk_man->GetTimeFirstKey();
4056 if (!time_first_key || time < *time_first_key) time_first_key = time;
4058 if (time_first_key) {
4060 rescan_height = *first_block;
4066 if (!reserver.
reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.
getBlockHash(rescan_height), rescan_height, {} , reserver,
true ).status)) {
4067 error =
_(
"Failed to rescan the wallet during initialization");
4072 walletInstance->database->IncrementUpdateCounter();
4077 for (
auto& load_wallet : g_load_wallet_fns) {
4085 walletInstance->WalletLogPrintf(
"setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
4086 walletInstance->WalletLogPrintf(
"mapWallet.size() = %u\n", walletInstance->mapWallet.size());
4087 walletInstance->WalletLogPrintf(
"m_address_book.size() = %u\n", walletInstance->m_address_book.size());
4090 return walletInstance;
4095 const auto& address_book_it = m_address_book.find(dest);
4096 if (address_book_it == m_address_book.end())
return nullptr;
4097 if ((!allow_change) && address_book_it->second.IsChange()) {
4100 return &address_book_it->second;
4105 int prev_version = GetVersion();
4107 WalletLogPrintf(
"Performing wallet upgrade to %i\n",
FEATURE_LATEST);
4110 WalletLogPrintf(
"Allowing wallet upgrade up to %i\n", version);
4112 if (version < prev_version)
4114 error =
_(
"Cannot downgrade wallet");
4122 error =
_(
"Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use version 169900 or no version specified.");
4129 for (
auto spk_man : GetActiveScriptPubKeyMans()) {
4130 if (!spk_man->Upgrade(prev_version, version, error)) {
4143 ReacceptWalletTransactions();
4151 return database->Backup(strDest);
4158 m_pre_split =
false;
4164 vchPubKey = vchPubKeyIn;
4165 fInternal = internalIn;
4166 m_pre_split =
false;
4183 assert(chain_depth >= 0);
4193 std::vector<OutputGroup>
CWallet::GroupOutputs(
const std::vector<COutput>& outputs,
bool single_coin,
const size_t max_ancestors)
const {
4194 std::vector<OutputGroup> groups;
4195 std::map<CTxDestination, OutputGroup> gmap;
4196 std::set<CTxDestination> full_groups;
4198 for (
const auto& output : outputs) {
4199 if (output.fSpendable) {
4201 CInputCoin input_coin = output.GetInputCoin();
4203 size_t ancestors, descendants;
4205 if (!single_coin &&
ExtractDestination(output.tx->tx->vout[output.i].scriptPubKey, dst)) {
4206 auto it = gmap.find(dst);
4207 if (
it != gmap.end()) {
4214 groups.push_back(
it->second);
4216 full_groups.insert(dst);
4218 it->second.Insert(input_coin, output.nDepth, output.tx->IsFromMe(
ISMINE_ALL), ancestors, descendants);
4220 gmap[dst].Insert(input_coin, output.nDepth, output.tx->IsFromMe(
ISMINE_ALL), ancestors, descendants);
4223 groups.emplace_back(input_coin, output.nDepth, output.tx->IsFromMe(
ISMINE_ALL), ancestors, descendants);
4228 for (
auto&
it : gmap) {
4229 auto& group =
it.second;
4230 if (full_groups.count(
it.first) > 0) {
4232 group.m_ancestors = max_ancestors - 1;
4234 groups.push_back(group);
4242 return HasEncryptionKeys();
4251 return vMasterKey.empty();
4264 NotifyStatusChanged(
this);
4272 for (
const auto& spk_man_pair : m_spk_managers) {
4273 if (!spk_man_pair.second->CheckDecryptionKey(vMasterKeyIn, accept_no_keys)) {
4277 vMasterKey = vMasterKeyIn;
4279 NotifyStatusChanged(
this);
4285 std::set<ScriptPubKeyMan*> spk_mans;
4286 for (
bool internal : {
false,
true}) {
4288 auto spk_man = GetScriptPubKeyMan(t,
internal);
4290 spk_mans.insert(spk_man);
4299 std::set<ScriptPubKeyMan*> spk_mans;
4300 for (
const auto& spk_man_pair : m_spk_managers) {
4301 spk_mans.insert(spk_man_pair.second.get());
4308 const std::map<OutputType, ScriptPubKeyMan*>& spk_managers =
internal ? m_internal_spk_managers : m_external_spk_managers;
4309 std::map<OutputType, ScriptPubKeyMan*>::const_iterator
it = spk_managers.find(type);
4310 if (it == spk_managers.end()) {
4311 WalletLogPrintf(
"%s scriptPubKey Manager for output type %d does not exist\n",
internal ?
"Internal" :
"External", static_cast<int>(type));
4319 std::set<ScriptPubKeyMan*> spk_mans;
4320 for (
const auto& spk_man_pair : m_spk_managers) {
4321 if (spk_man_pair.second->CanProvide(script, sigdata)) {
4322 spk_mans.insert(spk_man_pair.second.get());
4331 for (
const auto& spk_man_pair : m_spk_managers) {
4332 if (spk_man_pair.second->CanProvide(script, sigdata)) {
4333 return spk_man_pair.second.get();
4341 if (m_spk_managers.count(
id) > 0) {
4342 return m_spk_managers.at(
id).get();
4350 return GetSolvingProvider(script, sigdata);
4355 for (
const auto& spk_man_pair : m_spk_managers) {
4356 if (spk_man_pair.second->CanProvide(script, sigdata)) {
4357 return spk_man_pair.second->GetSolvingProvider(script);
4371 if (
it == m_internal_spk_managers.end())
return nullptr;
4377 SetupLegacyScriptPubKeyMan();
4378 return GetLegacyScriptPubKeyMan();
4383 if (!m_internal_spk_managers.empty() || !m_external_spk_managers.empty() || !m_spk_managers.empty() || IsWalletFlagSet(
WALLET_FLAG_DESCRIPTORS)) {
4389 m_internal_spk_managers[type] = spk_manager.get();
4390 m_external_spk_managers[type] = spk_manager.get();
4392 m_spk_managers[spk_manager->GetID()] = std::move(spk_manager);
4402 return !mapMasterKeys.empty();
4407 for (
const auto& spk_man : GetActiveScriptPubKeyMans()) {
4416 m_spk_managers[id] = std::move(spk_manager);
4425 seed_key.MakeNewKey(
true);
4426 CPubKey seed = seed_key.GetPubKey();
4427 assert(seed_key.VerifyPubKey(seed));
4431 master_key.
SetSeed(seed_key.begin(), seed_key.size());
4433 for (
bool internal : {
false,
true}) {
4438 throw std::runtime_error(std::string(__func__) +
": Wallet is locked, cannot setup new descriptors");
4440 if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey,
nullptr)) {
4441 throw std::runtime_error(std::string(__func__) +
": Could not encrypt new descriptors");
4444 spk_manager->SetupDescriptorGeneration(master_key, t);
4445 uint256 id = spk_manager->GetID();
4446 m_spk_managers[id] = std::move(spk_manager);
4447 AddActiveScriptPubKeyMan(
id, t,
internal);
4456 throw std::runtime_error(std::string(__func__) +
": writing active ScriptPubKeyMan id failed");
4458 LoadActiveScriptPubKeyMan(
id, type,
internal);
4463 WalletLogPrintf(
"Setting spkMan to active: id = %s, type = %d, internal = %d\n",
id.
ToString(), static_cast<int>(type), static_cast<int>(
internal));
4464 auto& spk_mans =
internal ? m_internal_spk_managers : m_external_spk_managers;
4465 auto spk_man = m_spk_managers.at(
id).get();
4466 spk_man->SetInternal(
internal);
4467 spk_mans[type] = spk_man;
4478 return spk_man !=
nullptr;
4483 for (
auto& spk_man_pair : m_spk_managers) {
4497 WalletLogPrintf(
"Cannot add WalletDescriptor to a non-descriptor wallet\n");
4505 auto old_spk_man = GetDescriptorScriptPubKeyMan(desc);
4507 WalletLogPrintf(
"Update existing descriptor: %s\n", desc.
descriptor->ToString());
4510 LOCK(old_spk_man->cs_desc_man);
4511 new_spk_man->SetCache(old_spk_man->GetWalletDescriptor().cache);
4515 auto old_spk_man_id = old_spk_man->GetID();
4516 for (
bool internal : {
false,
true}) {
4518 auto active_spk_man = GetScriptPubKeyMan(t,
internal);
4519 if (active_spk_man && active_spk_man->GetID() == old_spk_man_id) {
4521 m_internal_spk_managers.erase(t);
4523 m_external_spk_managers.erase(t);
4529 m_spk_managers.erase(old_spk_man_id);
4533 for (
const auto& entry : signing_provider.
keys) {
4534 const CKey& key = entry.second;
4535 new_spk_man->AddDescriptorKey(key, key.GetPubKey());
4539 if (!new_spk_man->TopUp()) {
4540 WalletLogPrintf(
"Could not top up scriptPubKeys\n");
4547 auto script_pub_keys = new_spk_man->GetScriptPubKeys();
4548 if (script_pub_keys.empty()) {
4549 WalletLogPrintf(
"Could not generate scriptPubKeys (cache is empty)\n");
4555 SetAddressBook(dest, label,
"receive");
4560 auto ret = new_spk_man.get();
4561 m_spk_managers[new_spk_man->GetID()] = std::move(new_spk_man);
4564 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
CFeeRate m_effective_feerate
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)
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)
CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(0), CFeeRate(0), CFeeRate(0), 0)
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
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...
CFeeRate m_discard_feerate
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)
virtual unsigned int estimateMaxBlocks()=0
Fee estimator max target.
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)
CFeeRate m_long_term_feerate
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