mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 11:32:46 +01:00
Merge bitcoin/bitcoin#22100: refactor: Clean up new wallet spend, receive files added #21207
b11a195ef450bd138aa03204a5e74fdd3ddced26 refactor: Detach wallet transaction methods (followup for move-only) (Russell Yanofsky) Pull request description: This makes `CWallet` and `CWalletTx` methods in `spend.cpp` and `receive.cpp` files into standalone functions. It's a followup to [#21207 MOVEONLY: CWallet transaction code out of wallet.cpp/.h](https://github.com/bitcoin/bitcoin/pull/21207), which moved code from `wallet.cpp` to new `spend.cpp` and `receive.cpp` files. There are no changes in behavior. This is just making methods into functions and removing circular dependencies created by #21207. There are no comment or documentation changes, either. Removed comments from `transaction.h` are just migrated to `spend.h`, `receive.h`, and `wallet.h`. --- This commit was split off from #21206 so there are a few earlier review comments there ACKs for top commit: achow101: ACK b11a195ef450bd138aa03204a5e74fdd3ddced26 Sjors: utACK b11a195ef450bd138aa03204a5e74fdd3ddced26 meshcollider: light ACK b11a195ef450bd138aa03204a5e74fdd3ddced26 Tree-SHA512: 75ce818d3f03b728b14b12e2d21bd20b7be73978601989cb37ff98254393300d1bb7823281449cd3d9e40756d67d42bd9a46bbdafd2e8baa95aaf2cb1c84549f
This commit is contained in:
parent
18ddb83fbc
commit
8a58b5e244
@ -6,6 +6,7 @@
|
||||
#include <interfaces/chain.h>
|
||||
#include <node/context.h>
|
||||
#include <wallet/coinselection.h>
|
||||
#include <wallet/spend.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
#include <set>
|
||||
@ -17,7 +18,7 @@ static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<st
|
||||
tx.nLockTime = nextLockTime++; // so all transactions get different hashes
|
||||
tx.vout.resize(1);
|
||||
tx.vout[0].nValue = nValue;
|
||||
wtxs.push_back(std::make_unique<CWalletTx>(&wallet, MakeTransactionRef(std::move(tx))));
|
||||
wtxs.push_back(std::make_unique<CWalletTx>(MakeTransactionRef(std::move(tx))));
|
||||
}
|
||||
|
||||
// Simple benchmark for wallet coin selection. Note that it maybe be necessary
|
||||
@ -45,7 +46,7 @@ static void CoinSelection(benchmark::Bench& bench)
|
||||
// Create coins
|
||||
std::vector<COutput> coins;
|
||||
for (const auto& wtx : wtxs) {
|
||||
coins.emplace_back(wtx.get(), 0 /* iIn */, 6 * 24 /* nDepthIn */, true /* spendable */, true /* solvable */, true /* safe */);
|
||||
coins.emplace_back(wallet, *wtx, 0 /* iIn */, 6 * 24 /* nDepthIn */, true /* spendable */, true /* solvable */, true /* safe */);
|
||||
}
|
||||
const CoinEligibilityFilter filter_standard(1, 6, 0);
|
||||
const CoinSelectionParams coin_selection_params(/* use_bnb= */ true, /* change_output_size= */ 34,
|
||||
@ -56,7 +57,7 @@ static void CoinSelection(benchmark::Bench& bench)
|
||||
std::set<CInputCoin> setCoinsRet;
|
||||
CAmount nValueRet;
|
||||
bool bnb_used;
|
||||
bool success = wallet.AttemptSelection(1003 * COIN, filter_standard, coins, setCoinsRet, nValueRet, coin_selection_params, bnb_used);
|
||||
bool success = AttemptSelection(wallet, 1003 * COIN, filter_standard, coins, setCoinsRet, nValueRet, coin_selection_params, bnb_used);
|
||||
assert(success);
|
||||
assert(nValueRet == 1003 * COIN);
|
||||
assert(setCoinsRet.size() == 2);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/wallet.h>
|
||||
#include <validationinterface.h>
|
||||
#include <wallet/receive.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
#include <optional>
|
||||
@ -34,11 +35,11 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b
|
||||
}
|
||||
SyncWithValidationInterfaceQueue();
|
||||
|
||||
auto bal = wallet.GetBalance(); // Cache
|
||||
auto bal = GetBalance(wallet); // Cache
|
||||
|
||||
bench.minEpochIterations(epoch_iters).run([&] {
|
||||
if (set_dirty) wallet.MarkDirty();
|
||||
bal = wallet.GetBalance();
|
||||
bal = GetBalance(wallet);
|
||||
if (add_mine) assert(bal.m_mine_trusted > 0);
|
||||
if (add_watchonly) assert(bal.m_watchonly_trusted > 0);
|
||||
});
|
||||
|
@ -25,7 +25,9 @@
|
||||
#include <wallet/fees.h>
|
||||
#include <wallet/ismine.h>
|
||||
#include <wallet/load.h>
|
||||
#include <wallet/receive.h>
|
||||
#include <wallet/rpcwallet.h>
|
||||
#include <wallet/spend.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
#include <memory>
|
||||
@ -76,9 +78,9 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
|
||||
fOutputDenomFound = true;
|
||||
}
|
||||
}
|
||||
result.credit = wtx.GetCredit(ISMINE_ALL);
|
||||
result.debit = wtx.GetDebit(ISMINE_ALL);
|
||||
result.change = wtx.GetChange();
|
||||
result.credit = CachedTxGetCredit(wallet, wtx, ISMINE_ALL);
|
||||
result.debit = CachedTxGetDebit(wallet, wtx, ISMINE_ALL);
|
||||
result.change = CachedTxGetChange(wallet, wtx);
|
||||
result.time = wtx.GetTxTime();
|
||||
result.value_map = wtx.mapValue;
|
||||
result.is_coinbase = wtx.IsCoinBase();
|
||||
@ -96,15 +98,15 @@ WalletTxStatus MakeWalletTxStatus(const CWallet& wallet, const CWalletTx& wtx)
|
||||
{
|
||||
WalletTxStatus result;
|
||||
result.block_height = wtx.m_confirm.block_height > 0 ? wtx.m_confirm.block_height : std::numeric_limits<int>::max();
|
||||
result.blocks_to_maturity = wtx.GetBlocksToMaturity();
|
||||
result.depth_in_main_chain = wtx.GetDepthInMainChain();
|
||||
result.blocks_to_maturity = wallet.GetTxBlocksToMaturity(wtx);
|
||||
result.depth_in_main_chain = wallet.GetTxDepthInMainChain(wtx);
|
||||
result.time_received = wtx.nTimeReceived;
|
||||
result.lock_time = wtx.tx->nLockTime;
|
||||
result.is_final = wallet.chain().checkFinalTx(*wtx.tx);
|
||||
result.is_trusted = wtx.IsTrusted();
|
||||
result.is_trusted = CachedTxIsTrusted(wallet, wtx);
|
||||
result.is_abandoned = wtx.isAbandoned();
|
||||
result.is_coinbase = wtx.IsCoinBase();
|
||||
result.is_in_main_chain = wtx.IsInMainChain();
|
||||
result.is_in_main_chain = wallet.IsTxInMainChain(wtx);
|
||||
result.is_chainlocked = wtx.IsChainLocked();
|
||||
result.is_islocked = wtx.IsLockedByInstantSend();
|
||||
return result;
|
||||
@ -274,7 +276,7 @@ public:
|
||||
ReserveDestination m_dest(m_wallet.get());
|
||||
CTransactionRef tx;
|
||||
FeeCalculation fee_calc_out;
|
||||
if (!m_wallet->CreateTransaction(recipients, tx, fee, change_pos,
|
||||
if (!CreateTransaction(*m_wallet, recipients, tx, fee, change_pos,
|
||||
fail_reason, coin_control, fee_calc_out, sign)) {
|
||||
return {};
|
||||
}
|
||||
@ -378,7 +380,7 @@ public:
|
||||
}
|
||||
WalletBalances getBalances() override
|
||||
{
|
||||
const auto bal = m_wallet->GetBalance();
|
||||
const auto bal = GetBalance(*m_wallet);
|
||||
WalletBalances result;
|
||||
result.balance = bal.m_mine_trusted;
|
||||
result.unconfirmed_balance = bal.m_mine_untrusted_pending;
|
||||
@ -404,7 +406,7 @@ public:
|
||||
}
|
||||
CAmount getBalance() override
|
||||
{
|
||||
return m_wallet->GetBalance().m_mine_trusted;
|
||||
return GetBalance(*m_wallet).m_mine_trusted;
|
||||
}
|
||||
CAmount getAnonymizableBalance(bool fSkipDenominated, bool fSkipUnconfirmed) override
|
||||
{
|
||||
@ -436,13 +438,13 @@ public:
|
||||
if (coin_control.IsUsingCoinJoin()) {
|
||||
return m_wallet->GetBalance(0, coin_control.m_avoid_address_reuse, false, &coin_control).m_anonymized;
|
||||
} else {
|
||||
return m_wallet->GetAvailableBalance(&coin_control);
|
||||
return GetAvailableBalance(*m_wallet, &coin_control);
|
||||
}
|
||||
}
|
||||
isminetype txinIsMine(const CTxIn& txin) override
|
||||
{
|
||||
LOCK(m_wallet->cs_wallet);
|
||||
return m_wallet->IsMine(txin);
|
||||
return InputIsMine(*m_wallet, txin);
|
||||
}
|
||||
isminetype txoutIsMine(const CTxOut& txout) override
|
||||
{
|
||||
@ -457,13 +459,13 @@ public:
|
||||
CAmount getCredit(const CTxOut& txout, isminefilter filter) override
|
||||
{
|
||||
LOCK(m_wallet->cs_wallet);
|
||||
return m_wallet->GetCredit(txout, filter);
|
||||
return OutputGetCredit(*m_wallet, txout, filter);
|
||||
}
|
||||
CoinsList listCoins() override
|
||||
{
|
||||
LOCK(m_wallet->cs_wallet);
|
||||
CoinsList result;
|
||||
for (const auto& entry : m_wallet->ListCoins()) {
|
||||
for (const auto& entry : ListCoins(*m_wallet)) {
|
||||
auto& group = result[entry.first];
|
||||
for (const auto& coin : entry.second) {
|
||||
group.emplace_back(COutPoint(coin.tx->GetHash(), coin.i),
|
||||
@ -481,7 +483,7 @@ public:
|
||||
result.emplace_back();
|
||||
auto it = m_wallet->mapWallet.find(output.hash);
|
||||
if (it != m_wallet->mapWallet.end()) {
|
||||
int depth = it->second.GetDepthInMainChain();
|
||||
int depth = m_wallet->GetTxDepthInMainChain(it->second);
|
||||
if (depth >= 0) {
|
||||
result.back() = MakeWalletTxOut(*m_wallet, it->second, output.n, depth);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <util/string.h>
|
||||
#include <util/system.h>
|
||||
#include <util/translation.h>
|
||||
#include <wallet/spend.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletdb.h>
|
||||
|
||||
|
@ -30,9 +30,11 @@
|
||||
#include <wallet/coincontrol.h>
|
||||
#include <wallet/context.h>
|
||||
#include <wallet/load.h>
|
||||
#include <wallet/receive.h>
|
||||
#include <wallet/rpcwallet.h>
|
||||
#include <wallet/scriptpubkeyman.h>
|
||||
#include <wallet/rpc/util.h>
|
||||
#include <wallet/spend.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletdb.h>
|
||||
#include <wallet/walletutil.h>
|
||||
@ -59,9 +61,11 @@ bool HaveKey(const SigningProvider& wallet, const CKey& key)
|
||||
return wallet.HaveKey(key.GetPubKey().GetID()) || wallet.HaveKey(key2.GetPubKey().GetID());
|
||||
}
|
||||
|
||||
static void WalletTxToJSON(interfaces::Chain& chain, const CWalletTx& wtx, UniValue& entry)
|
||||
static void WalletTxToJSON(const JSONRPCRequest& request, interfaces::Chain& chain, const CWalletTx& wtx, UniValue& entry)
|
||||
{
|
||||
int confirms = wtx.GetDepthInMainChain();
|
||||
interfaces::Chain& chain = wallet.chain();
|
||||
int confirms = wallet.GetTxDepthInMainChain(wtx);
|
||||
bool fLocked = chain.isInstantSendLockedTx(wtx.GetHash());
|
||||
bool chainlock = false;
|
||||
if (confirms > 0) {
|
||||
@ -84,12 +88,12 @@ static void WalletTxToJSON(interfaces::Chain& chain, const CWalletTx& wtx, UniVa
|
||||
CHECK_NONFATAL(chain.findBlock(wtx.m_confirm.hashBlock, FoundBlock().time(block_time)));
|
||||
entry.pushKV("blocktime", block_time);
|
||||
} else {
|
||||
entry.pushKV("trusted", wtx.IsTrusted());
|
||||
entry.pushKV("trusted", CachedTxIsTrusted(wallet, wtx));
|
||||
}
|
||||
uint256 hash = wtx.GetHash();
|
||||
entry.pushKV("txid", hash.GetHex());
|
||||
UniValue conflicts(UniValue::VARR);
|
||||
for (const uint256& conflict : wtx.GetConflicts())
|
||||
for (const uint256& conflict : wallet.GetTxConflicts(wtx))
|
||||
conflicts.push_back(conflict.GetHex());
|
||||
entry.pushKV("walletconflicts", conflicts);
|
||||
entry.pushKV("time", wtx.GetTxTime());
|
||||
@ -300,7 +304,7 @@ UniValue SendMoney(CWallet& wallet, const CCoinControl &coin_control, std::vecto
|
||||
bilingual_str error;
|
||||
CTransactionRef tx;
|
||||
FeeCalculation fee_calc_out;
|
||||
const bool fCreated = wallet.CreateTransaction(recipients, tx, nFeeRequired, nChangePosRet, error, coin_control, fee_calc_out, true);
|
||||
const bool fCreated = CreateTransaction(wallet, recipients, tx, nFeeRequired, nChangePosRet, error, coin_control, fee_calc_out, true);
|
||||
if (!fCreated) {
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, error.original);
|
||||
}
|
||||
@ -472,8 +476,8 @@ static RPCHelpMan listaddressgroupings()
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
UniValue jsonGroupings(UniValue::VARR);
|
||||
std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
|
||||
for (const std::set<CTxDestination>& grouping : pwallet->GetAddressGroupings()) {
|
||||
std::map<CTxDestination, CAmount> balances = GetAddressBalances(*pwallet);
|
||||
for (const std::set<CTxDestination>& grouping : GetAddressGroupings(*pwallet)) {
|
||||
UniValue jsonGrouping(UniValue::VARR);
|
||||
for (const CTxDestination& address : grouping)
|
||||
{
|
||||
@ -630,7 +634,7 @@ static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool b
|
||||
if (wtx.IsCoinBase() || !wallet.chain().checkFinalTx(*wtx.tx)) {
|
||||
continue;
|
||||
}
|
||||
if (wtx.GetDepthInMainChain() < min_depth && !(fAddLocked && wtx.IsLockedByInstantSend())) continue;
|
||||
if (wallet.GetTxDepthInMainChain(wtx) < min_depth && !(fAddLocked && wtx.IsLockedByInstantSend())) continue;
|
||||
|
||||
for (const CTxOut& txout : wtx.tx->vout) {
|
||||
CTxDestination address;
|
||||
@ -776,7 +780,7 @@ static RPCHelpMan getbalance()
|
||||
bool include_watchonly = ParseIncludeWatchonly(request.params[3], *pwallet);
|
||||
|
||||
bool avoid_reuse = GetAvoidReuseFlag(*pwallet, request.params[4]);
|
||||
const auto bal = pwallet->GetBalance(min_depth, avoid_reuse, fAddLocked);
|
||||
const auto bal = GetBalance(*pwallet, min_depth, avoid_reuse, fAddLocked);
|
||||
|
||||
return ValueFromAmount(bal.m_mine_trusted + (include_watchonly ? bal.m_watchonly_trusted : 0));
|
||||
},
|
||||
@ -801,7 +805,7 @@ static RPCHelpMan getunconfirmedbalance()
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
return ValueFromAmount(pwallet->GetBalance().m_mine_untrusted_pending);
|
||||
return ValueFromAmount(GetBalance(*pwallet).m_mine_untrusted_pending);
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -1027,7 +1031,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, bool
|
||||
if (wtx.IsCoinBase() || !wallet.chain().checkFinalTx(*wtx.tx))
|
||||
continue;
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
int nDepth = wallet.GetTxDepthInMainChain(wtx);
|
||||
if ((nDepth < nMinDepth) && !(fAddLocked && wtx.IsLockedByInstantSend()))
|
||||
continue;
|
||||
|
||||
@ -1260,9 +1264,9 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM
|
||||
std::list<COutputEntry> listReceived;
|
||||
std::list<COutputEntry> listSent;
|
||||
|
||||
wtx.GetAmounts(listReceived, listSent, nFee, filter_ismine);
|
||||
CachedTxGetAmounts(wallet, wtx, listReceived, listSent, nFee, filter_ismine);
|
||||
|
||||
bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
|
||||
bool involvesWatchonly = CachedTxIsFromMe(wallet, wtx, ISMINE_WATCH_ONLY);
|
||||
|
||||
// Sent
|
||||
if (!filter_label)
|
||||
@ -1284,14 +1288,14 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM
|
||||
entry.pushKV("vout", s.vout);
|
||||
entry.pushKV("fee", ValueFromAmount(-nFee));
|
||||
if (fLong)
|
||||
WalletTxToJSON(wallet.chain(), wtx, entry);
|
||||
WalletTxToJSON(wallet, wtx, entry);
|
||||
entry.pushKV("abandoned", wtx.isAbandoned());
|
||||
ret.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Received
|
||||
if (listReceived.size() > 0 && ((wtx.GetDepthInMainChain() >= nMinDepth) || wtx.IsLockedByInstantSend()))
|
||||
if (listReceived.size() > 0 && ((wallet.GetTxDepthInMainChain(wtx) >= nMinDepth) || wtx.IsLockedByInstantSend()))
|
||||
{
|
||||
for (const COutputEntry& r : listReceived)
|
||||
{
|
||||
@ -1310,9 +1314,9 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM
|
||||
MaybePushAddress(entry, r.destination);
|
||||
if (wtx.IsCoinBase())
|
||||
{
|
||||
if (wtx.GetDepthInMainChain() < 1)
|
||||
if (wallet.GetTxDepthInMainChain(wtx) < 1)
|
||||
entry.pushKV("category", "orphan");
|
||||
else if (wtx.IsImmatureCoinBase())
|
||||
else if (wallet.IsTxImmatureCoinBase(wtx))
|
||||
entry.pushKV("category", "immature");
|
||||
else
|
||||
entry.pushKV("category", "generate");
|
||||
@ -1331,7 +1335,7 @@ static void ListTransactions(const CWallet& wallet, const CWalletTx& wtx, int nM
|
||||
}
|
||||
entry.pushKV("vout", r.vout);
|
||||
if (fLong)
|
||||
WalletTxToJSON(wallet.chain(), wtx, entry);
|
||||
WalletTxToJSON(wallet, wtx, entry);
|
||||
ret.push_back(entry);
|
||||
}
|
||||
}
|
||||
@ -1574,7 +1578,7 @@ static RPCHelpMan listsinceblock()
|
||||
for (const std::pair<const uint256, CWalletTx>& pairWtx : wallet.mapWallet) {
|
||||
const CWalletTx& tx = pairWtx.second;
|
||||
|
||||
if (depth == -1 || abs(tx.GetDepthInMainChain()) < depth) {
|
||||
if (depth == -1 || abs(wallet.GetTxDepthInMainChain(tx)) < depth) {
|
||||
ListTransactions(wallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
|
||||
}
|
||||
}
|
||||
@ -1694,16 +1698,16 @@ static RPCHelpMan gettransaction()
|
||||
}
|
||||
const CWalletTx& wtx = it->second;
|
||||
|
||||
CAmount nCredit = wtx.GetCredit(filter);
|
||||
CAmount nDebit = wtx.GetDebit(filter);
|
||||
CAmount nCredit = CachedTxGetCredit(*pwallet, wtx, filter);
|
||||
CAmount nDebit = CachedTxGetDebit(*pwallet, wtx, filter);
|
||||
CAmount nNet = nCredit - nDebit;
|
||||
CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
|
||||
CAmount nFee = (CachedTxIsFromMe(*pwallet, wtx, filter) ? wtx.tx->GetValueOut() - nDebit : 0);
|
||||
|
||||
entry.pushKV("amount", ValueFromAmount(nNet - nFee));
|
||||
if (wtx.IsFromMe(filter))
|
||||
if (CachedTxIsFromMe(*pwallet, wtx, filter))
|
||||
entry.pushKV("fee", ValueFromAmount(nFee));
|
||||
|
||||
WalletTxToJSON(pwallet->chain(), wtx, entry);
|
||||
WalletTxToJSON(*pwallet, wtx, entry);
|
||||
|
||||
UniValue details(UniValue::VARR);
|
||||
ListTransactions(*pwallet, wtx, 0, false, details, filter, nullptr /* filter_label */);
|
||||
@ -2418,7 +2422,7 @@ static RPCHelpMan getbalances()
|
||||
|
||||
LOCK(wallet.cs_wallet);
|
||||
|
||||
const auto bal = wallet.GetBalance();
|
||||
const auto bal = GetBalance(wallet);
|
||||
UniValue balances{UniValue::VOBJ};
|
||||
{
|
||||
UniValue balances_mine{UniValue::VOBJ};
|
||||
@ -2428,7 +2432,7 @@ static RPCHelpMan getbalances()
|
||||
if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) {
|
||||
// If the AVOID_REUSE flag is set, bal has been set to just the un-reused address balance. Get
|
||||
// the total balance, and then subtract bal to get the reused address balance.
|
||||
const auto full_bal = wallet.GetBalance(0, false);
|
||||
const auto full_bal = GetBalance(wallet, 0, false);
|
||||
balances_mine.pushKV("used", ValueFromAmount(full_bal.m_mine_trusted + full_bal.m_mine_untrusted_pending - bal.m_mine_trusted - bal.m_mine_untrusted_pending));
|
||||
}
|
||||
balances_mine.pushKV("coinjoin", ValueFromAmount(bal.m_anonymized));
|
||||
@ -2511,7 +2515,7 @@ static RPCHelpMan getwalletinfo()
|
||||
bool fHDEnabled = spk_man && spk_man->GetHDChain(hdChainCurrent);
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
|
||||
const auto bal = pwallet->GetBalance();
|
||||
const auto bal = GetBalance(*pwallet);
|
||||
int64_t kp_oldest = pwallet->GetOldestKeyPoolTime();
|
||||
obj.pushKV("walletname", pwallet->GetName());
|
||||
obj.pushKV("walletversion", pwallet->GetVersion());
|
||||
@ -3227,7 +3231,7 @@ static RPCHelpMan listunspent()
|
||||
coinControl.m_include_unsafe_inputs = include_unsafe;
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
pwallet->AvailableCoins(vecOutputs, &coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount);
|
||||
AvailableCoins(*pwallet, vecOutputs, &coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount);
|
||||
}
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
@ -3406,7 +3410,7 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
|
||||
|
||||
bilingual_str error;
|
||||
|
||||
if (!wallet.FundTransaction(tx, fee_out, change_position, error, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
|
||||
if (!FundTransaction(wallet, tx, fee_out, change_position, error, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
|
||||
}
|
||||
}
|
||||
@ -3920,7 +3924,7 @@ RPCHelpMan getaddressinfo()
|
||||
UniValue detail = DescribeWalletAddress(*pwallet, dest);
|
||||
ret.pushKVs(detail);
|
||||
|
||||
ret.pushKV("ischange", pwallet->IsChange(scriptPubKey));
|
||||
ret.pushKV("ischange", ScriptIsChange(*pwallet, scriptPubKey));
|
||||
|
||||
ScriptPubKeyMan* spk_man = pwallet->GetScriptPubKeyMan(scriptPubKey);
|
||||
if (spk_man) {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <validation.h>
|
||||
#include <wallet/coincontrol.h>
|
||||
#include <wallet/coinselection.h>
|
||||
#include <wallet/spend.h>
|
||||
#include <wallet/test/wallet_test_fixture.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
@ -80,7 +81,7 @@ static void add_coin(std::vector<COutput>& coins, CWallet& wallet, const CAmount
|
||||
wtx->m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1);
|
||||
wtx->m_is_cache_empty = false;
|
||||
}
|
||||
COutput output(wtx, nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
|
||||
COutput output(wallet, *wtx, nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
|
||||
coins.push_back(output);
|
||||
}
|
||||
|
||||
@ -302,7 +303,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
|
||||
coin_control.fAllowOtherInputs = true;
|
||||
coin_control.Select(COutPoint(coins.at(0).tx->GetHash(), coins.at(0).i));
|
||||
coin_selection_params_bnb.m_effective_feerate = CFeeRate(0);
|
||||
BOOST_CHECK(wallet->SelectCoins(coins, 10 * CENT, setCoinsRet, nValueRet, coin_control, coin_selection_params_bnb, bnb_used));
|
||||
BOOST_CHECK(SelectCoins(*wallet, coins, 10 * CENT, setCoinsRet, nValueRet, coin_control, coin_selection_params_bnb, bnb_used));
|
||||
BOOST_CHECK(bnb_used);
|
||||
BOOST_CHECK(coin_selection_params_bnb.use_bnb);
|
||||
}
|
||||
@ -656,8 +657,8 @@ BOOST_AUTO_TEST_CASE(SelectCoins_test)
|
||||
CoinSet out_set;
|
||||
CAmount out_value = 0;
|
||||
bool bnb_used = false;
|
||||
BOOST_CHECK(wallet->AttemptSelection(target, filter_standard, coins, out_set, out_value, coin_selection_params_bnb, bnb_used) ||
|
||||
wallet->AttemptSelection(target, filter_standard, coins, out_set, out_value, coin_selection_params_knapsack, bnb_used));
|
||||
BOOST_CHECK(AttemptSelection(wallet, target, filter_standard, coins, out_set, out_value, coin_selection_params_bnb, bnb_used) ||
|
||||
AttemptSelection(wallet, target, filter_standard, coins, out_set, out_value, coin_selection_params_knapsack, bnb_used));
|
||||
BOOST_CHECK_GE(out_value, target);
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,12 @@ BOOST_AUTO_TEST_CASE(psbt_updater_test)
|
||||
CDataStream s_prev_tx1(ParseHex("0200000000010158e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7501000000171600145f275f436b09a8cc9a2eb2a2f528485c68a56323feffffff02d8231f1b0100000017a914aed962d6654f9a2b36608eb9d64d2b260db4f1118700c2eb0b0000000017a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e88702483045022100a22edcc6e5bc511af4cc4ae0de0fcd75c7e04d8c1c3a8aa9d820ed4b967384ec02200642963597b9b1bc22c75e9f3e117284a962188bf5e8a74c895089046a20ad770121035509a48eb623e10aace8bfd0212fdb8a8e5af3c94b0b133b95e114cab89e4f7965000000"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
CTransactionRef prev_tx1;
|
||||
s_prev_tx1 >> prev_tx1;
|
||||
m_wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(prev_tx1->GetHash()), std::forward_as_tuple(&m_wallet, prev_tx1));
|
||||
m_wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(prev_tx1->GetHash()), std::forward_as_tuple(prev_tx1));
|
||||
|
||||
CDataStream s_prev_tx2(ParseHex("0200000001aad73931018bd25f84ae400b68848be09db706eac2ac18298babee71ab656f8b0000000048473044022058f6fc7c6a33e1b31548d481c826c015bd30135aad42cd67790dab66d2ad243b02204a1ced2604c6735b6393e5b41691dd78b00f0c5942fb9f751856faa938157dba01feffffff0280f0fa020000000017a9140fb9463421696b82c833af241c78c17ddbde493487d0f20a270100000017a91429ca74f8a08f81999428185c97b5d852e4063f618765000000"), SER_NETWORK, PROTOCOL_VERSION);
|
||||
CTransactionRef prev_tx2;
|
||||
s_prev_tx2 >> prev_tx2;
|
||||
m_wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(prev_tx2->GetHash()), std::forward_as_tuple(&m_wallet, prev_tx2));
|
||||
m_wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(prev_tx2->GetHash()), std::forward_as_tuple(prev_tx2));
|
||||
|
||||
// Add scripts
|
||||
CScript rs1;
|
||||
|
@ -25,8 +25,9 @@
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <wallet/coincontrol.h>
|
||||
#include <wallet/receive.h>
|
||||
#include <wallet/spend.h>
|
||||
#include <wallet/test/wallet_test_fixture.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <univalue.h>
|
||||
|
||||
@ -119,7 +120,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
|
||||
BOOST_CHECK(result.last_failed_block.IsNull());
|
||||
BOOST_CHECK(result.last_scanned_block.IsNull());
|
||||
BOOST_CHECK(!result.last_scanned_height);
|
||||
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 0);
|
||||
BOOST_CHECK_EQUAL(GetBalance(wallet).m_mine_immature, 0);
|
||||
}
|
||||
|
||||
// Verify ScanForWalletTransactions picks up transactions in both the old
|
||||
@ -138,7 +139,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
|
||||
BOOST_CHECK(result.last_failed_block.IsNull());
|
||||
BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash());
|
||||
BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight);
|
||||
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 1000 * COIN);
|
||||
BOOST_CHECK_EQUAL(GetBalance(wallet).m_mine_immature, 1000 * COIN);
|
||||
}
|
||||
|
||||
// Prune the older block file.
|
||||
@ -166,7 +167,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
|
||||
BOOST_CHECK_EQUAL(result.last_failed_block, oldTip->GetBlockHash());
|
||||
BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash());
|
||||
BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight);
|
||||
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 500 * COIN);
|
||||
BOOST_CHECK_EQUAL(GetBalance(wallet).m_mine_immature, 500 * COIN);
|
||||
}
|
||||
|
||||
// Prune the remaining block file.
|
||||
@ -192,7 +193,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
|
||||
BOOST_CHECK_EQUAL(result.last_failed_block, newTip->GetBlockHash());
|
||||
BOOST_CHECK(result.last_scanned_block.IsNull());
|
||||
BOOST_CHECK(!result.last_scanned_height);
|
||||
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 0);
|
||||
BOOST_CHECK_EQUAL(GetBalance(wallet).m_mine_immature, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,7 +409,7 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
|
||||
{
|
||||
CWallet wallet(m_node.chain.get(), m_node.coinjoin_loader.get(), "", CreateDummyWalletDatabase());
|
||||
auto spk_man = wallet.GetOrCreateLegacyScriptPubKeyMan();
|
||||
CWalletTx wtx(&wallet, m_coinbase_txns.back());
|
||||
CWalletTx wtx(m_coinbase_txns.back());
|
||||
|
||||
LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
|
||||
wallet.SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
|
||||
@ -418,13 +419,13 @@ BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
|
||||
|
||||
// Call GetImmatureCredit() once before adding the key to the wallet to
|
||||
// cache the current immature credit amount, which is 0.
|
||||
BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(), 0);
|
||||
BOOST_CHECK_EQUAL(CachedTxGetImmatureCredit(wallet, wtx), 0);
|
||||
|
||||
// Invalidate the cached value, add the key, and make sure a new immature
|
||||
// credit amount is calculated.
|
||||
wtx.MarkDirty();
|
||||
BOOST_CHECK(spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()));
|
||||
BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(), 500*COIN);
|
||||
BOOST_CHECK_EQUAL(CachedTxGetImmatureCredit(wallet, wtx), 500*COIN);
|
||||
}
|
||||
|
||||
static int64_t AddTx(ChainstateManager& chainman, CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime)
|
||||
@ -609,7 +610,7 @@ public:
|
||||
bilingual_str error;
|
||||
CCoinControl dummy;
|
||||
FeeCalculation fee_calc_out;
|
||||
BOOST_CHECK(wallet->CreateTransaction({recipient}, tx, fee, changePos, error, dummy, fee_calc_out));
|
||||
BOOST_CHECK(CreateTransaction(*wallet, {recipient}, tx, fee, changePos, error, dummy, fee_calc_out));
|
||||
wallet->CommitTransaction(tx, {}, {});
|
||||
CMutableTransaction blocktx;
|
||||
{
|
||||
@ -630,7 +631,7 @@ public:
|
||||
std::unique_ptr<CWallet> wallet;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
BOOST_FIXTURE_TEST_CASE(ListCoinsTest, ListCoinsTestingSetup)
|
||||
{
|
||||
std::string coinbaseAddress = coinbaseKey.GetPubKey().GetID().ToString();
|
||||
|
||||
@ -639,14 +640,14 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
std::map<CTxDestination, std::vector<COutput>> list;
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
list = wallet->ListCoins();
|
||||
list = ListCoins(*wallet);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(list.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(std::get<PKHash>(list.begin()->first).ToString(), coinbaseAddress);
|
||||
BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U);
|
||||
|
||||
// Check initial balance from one mature coinbase transaction.
|
||||
BOOST_CHECK_EQUAL(500 * COIN, wallet->GetAvailableBalance());
|
||||
BOOST_CHECK_EQUAL(500 * COIN, GetAvailableBalance(*wallet));
|
||||
|
||||
// Add a transaction creating a change address, and confirm ListCoins still
|
||||
// returns the coin associated with the change address underneath the
|
||||
@ -655,7 +656,7 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, false /* subtract fee */});
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
list = wallet->ListCoins();
|
||||
list = ListCoins(*wallet);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(list.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(std::get<PKHash>(list.begin()->first).ToString(), coinbaseAddress);
|
||||
@ -665,7 +666,7 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
std::vector<COutput> available;
|
||||
wallet->AvailableCoins(available);
|
||||
AvailableCoins(*wallet, available);
|
||||
BOOST_CHECK_EQUAL(available.size(), 2U);
|
||||
}
|
||||
for (const auto& group : list) {
|
||||
@ -677,14 +678,14 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
std::vector<COutput> available;
|
||||
wallet->AvailableCoins(available);
|
||||
AvailableCoins(*wallet, available);
|
||||
BOOST_CHECK_EQUAL(available.size(), 0U);
|
||||
}
|
||||
// Confirm ListCoins still returns same result as before, despite coins
|
||||
// being locked.
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
list = wallet->ListCoins();
|
||||
list = ListCoins(*wallet);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(list.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(std::get<PKHash>(list.begin()->first).ToString(), coinbaseAddress);
|
||||
|
@ -617,7 +617,7 @@ bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
|
||||
const uint256& wtxid = it->second;
|
||||
std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
|
||||
if (mit != mapWallet.end()) {
|
||||
int depth = mit->second.GetDepthInMainChain();
|
||||
int depth = GetTxDepthInMainChain(mit->second);
|
||||
if (depth > 0 || (depth == 0 && !mit->second.isAbandoned()))
|
||||
return true; // Spent
|
||||
}
|
||||
@ -905,7 +905,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
|
||||
}
|
||||
|
||||
// Inserts only if not already there, returns tx inserted or tx found
|
||||
auto ret = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(this, tx));
|
||||
auto ret = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(tx));
|
||||
CWalletTx& wtx = (*ret.first).second;
|
||||
bool fInsertedNew = ret.second;
|
||||
bool fUpdated = update_wtx && update_wtx(wtx, fInsertedNew);
|
||||
@ -1014,7 +1014,7 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const CWalletTx::Confirmatio
|
||||
|
||||
bool CWallet::LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx)
|
||||
{
|
||||
const auto& ins = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(this, nullptr));
|
||||
const auto& ins = mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(hash), std::forward_as_tuple(nullptr));
|
||||
CWalletTx& wtx = ins.first->second;
|
||||
if (!fill_wtx(wtx, ins.second)) {
|
||||
return false;
|
||||
@ -1111,7 +1111,7 @@ bool CWallet::TransactionCanBeAbandoned(const uint256& hashTx) const
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
const CWalletTx* wtx = GetWalletTx(hashTx);
|
||||
return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain() == 0 && !wtx->InMempool();
|
||||
return wtx && !wtx->isAbandoned() && GetTxDepthInMainChain(*wtx) == 0 && !wtx->InMempool();
|
||||
}
|
||||
|
||||
bool CWallet::TransactionCanBeResent(const uint256& hashTx) const
|
||||
@ -1144,7 +1144,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||
auto it = mapWallet.find(hashTx);
|
||||
assert(it != mapWallet.end());
|
||||
const CWalletTx& origtx = it->second;
|
||||
if (origtx.GetDepthInMainChain() != 0 || origtx.InMempool() || origtx.IsLockedByInstantSend()) {
|
||||
if (GetTxDepthInMainChain(origtx) != 0 || origtx.InMempool() || origtx.IsLockedByInstantSend()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1157,7 +1157,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||
auto it = mapWallet.find(now);
|
||||
assert(it != mapWallet.end());
|
||||
CWalletTx& wtx = it->second;
|
||||
int currentconfirm = wtx.GetDepthInMainChain();
|
||||
int currentconfirm = GetTxDepthInMainChain(wtx);
|
||||
// If the orig tx was not in block, none of its spends can be
|
||||
assert(currentconfirm <= 0);
|
||||
// if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon}
|
||||
@ -1227,7 +1227,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, c
|
||||
auto it = mapWallet.find(now);
|
||||
assert(it != mapWallet.end());
|
||||
CWalletTx& wtx = it->second;
|
||||
int currentconfirm = wtx.GetDepthInMainChain();
|
||||
int currentconfirm = GetTxDepthInMainChain(wtx);
|
||||
if (conflictconfirms < currentconfirm) {
|
||||
// Block is 'more conflicted' than current confirm; update.
|
||||
// Mark transaction as conflicted with this block.
|
||||
@ -2140,7 +2140,7 @@ void CWallet::ReacceptWalletTransactions()
|
||||
CWalletTx& wtx = item.second;
|
||||
assert(wtx.GetHash() == wtxid);
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
int nDepth = GetTxDepthInMainChain(wtx);
|
||||
|
||||
if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.IsLockedByInstantSend() && !wtx.isAbandoned())) {
|
||||
mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
|
||||
@ -2151,7 +2151,7 @@ void CWallet::ReacceptWalletTransactions()
|
||||
for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
|
||||
CWalletTx& wtx = *(item.second);
|
||||
bilingual_str unused_err_string;
|
||||
wtx.SubmitMemoryPoolAndRelay(unused_err_string, false);
|
||||
SubmitTxMemoryPoolAndRelay(wtx, unused_err_string, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2176,7 +2176,7 @@ bool CWalletTx::SubmitMemoryPoolAndRelay(bilingual_str& err_string, bool relay)
|
||||
if (!CanBeResent()) return false;
|
||||
|
||||
// Submit transaction to mempool for relay
|
||||
pwallet->WalletLogPrintf("Submitting wtx %s to mempool for relay\n", GetHash().ToString());
|
||||
WalletLogPrintf("Submitting wtx %s to mempool for relay\n", wtx.GetHash().ToString());
|
||||
// We must set fInMempool here - while it will be re-set to true by the
|
||||
// entered-mempool callback, if we did not there would be a race where a
|
||||
// user could call sendmoney in a loop and hit spurious out of funds errors
|
||||
@ -2186,19 +2186,18 @@ bool CWalletTx::SubmitMemoryPoolAndRelay(bilingual_str& err_string, bool relay)
|
||||
// Irrespective of the failure reason, un-marking fInMempool
|
||||
// out-of-order is incorrect - it should be unmarked when
|
||||
// TransactionRemovedFromMempool fires.
|
||||
bool ret = pwallet->chain().broadcastTransaction(tx, pwallet->m_default_max_tx_fee, relay, err_string);
|
||||
fInMempool |= ret;
|
||||
bool ret = chain().broadcastTransaction(wtx.tx, m_default_max_tx_fee, relay, err_string);
|
||||
wtx.fInMempool |= ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::set<uint256> CWalletTx::GetConflicts() const
|
||||
std::set<uint256> CWallet::GetTxConflicts(const CWalletTx& wtx) const
|
||||
{
|
||||
std::set<uint256> result;
|
||||
if (pwallet != nullptr)
|
||||
{
|
||||
AssertLockHeld(pwallet->cs_wallet);
|
||||
uint256 myHash = GetHash();
|
||||
result = pwallet->GetConflicts(myHash);
|
||||
uint256 myHash = wtx.GetHash();
|
||||
result = GetConflicts(myHash);
|
||||
result.erase(myHash);
|
||||
}
|
||||
return result;
|
||||
@ -2484,11 +2483,11 @@ void CWallet::ResendWalletTransactions()
|
||||
for (std::pair<const uint256, CWalletTx>& item : mapWallet) {
|
||||
CWalletTx& wtx = item.second;
|
||||
// Attempt to rebroadcast all txes more than 5 minutes older than
|
||||
// the last block. SubmitMemoryPoolAndRelay() will not rebroadcast
|
||||
// the last block. SubmitTxMemoryPoolAndRelay() will not rebroadcast
|
||||
// any confirmed or conflicting txs.
|
||||
if (wtx.nTimeReceived > m_best_block_time - 5 * 60) continue;
|
||||
bilingual_str unused_err_string;
|
||||
if (wtx.SubmitMemoryPoolAndRelay(unused_err_string, true)) ++submitted_tx_count;
|
||||
if (SubmitTxMemoryPoolAndRelay(wtx, unused_err_string, true)) ++submitted_tx_count;
|
||||
}
|
||||
} // cs_wallet
|
||||
|
||||
@ -3994,7 +3993,7 @@ void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
||||
}
|
||||
|
||||
bilingual_str err_string;
|
||||
if (!wtx.SubmitMemoryPoolAndRelay(err_string, true)) {
|
||||
if (!SubmitTxMemoryPoolAndRelay(wtx, err_string, true)) {
|
||||
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string.original);
|
||||
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
|
||||
}
|
||||
@ -5450,13 +5449,12 @@ CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool fInternalIn)
|
||||
fInternal = fInternalIn;
|
||||
}
|
||||
|
||||
int CWalletTx::GetDepthInMainChain() const
|
||||
int CWallet::GetTxDepthInMainChain(const CWalletTx& wtx) const
|
||||
{
|
||||
assert(pwallet != nullptr);
|
||||
AssertLockHeld(pwallet->cs_wallet);
|
||||
if (isUnconfirmed() || isAbandoned()) return 0;
|
||||
AssertLockHeld(cs_wallet);
|
||||
if (wtx.isUnconfirmed() || wtx.isAbandoned()) return 0;
|
||||
|
||||
return (pwallet->GetLastBlockHeight() - m_confirm.block_height + 1) * (isConflicted() ? -1 : 1);
|
||||
return (GetLastBlockHeight() - wtx.m_confirm.block_height + 1) * (wtx.isConflicted() ? -1 : 1);
|
||||
}
|
||||
|
||||
bool CWalletTx::IsLockedByInstantSend() const
|
||||
@ -5483,19 +5481,19 @@ bool CWalletTx::IsChainLocked() const
|
||||
return fIsChainlocked;
|
||||
}
|
||||
|
||||
int CWalletTx::GetBlocksToMaturity() const
|
||||
int CWallet::GetTxBlocksToMaturity(const CWalletTx& wtx) const
|
||||
{
|
||||
if (!IsCoinBase())
|
||||
if (!wtx.IsCoinBase())
|
||||
return 0;
|
||||
int chain_depth = GetDepthInMainChain();
|
||||
int chain_depth = GetTxDepthInMainChain(wtx);
|
||||
assert(chain_depth >= 0); // coinbase tx should not be conflicted
|
||||
return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
|
||||
}
|
||||
|
||||
bool CWalletTx::IsImmatureCoinBase() const
|
||||
bool CWallet::IsTxImmatureCoinBase(const CWalletTx& wtx) const
|
||||
{
|
||||
// note GetBlocksToMaturity is 0 for non-coinbase tx
|
||||
return GetBlocksToMaturity() > 0;
|
||||
return GetTxBlocksToMaturity(wtx) > 0;
|
||||
}
|
||||
|
||||
std::vector<OutputGroup> CWallet::GroupOutputs(const std::vector<COutput>& outputs, bool separate_coins, const CFeeRate& effective_feerate, const CFeeRate& long_term_feerate, const CoinEligibilityFilter& filter, bool positive_only) const
|
||||
|
@ -541,7 +541,6 @@ public:
|
||||
bool IsEquivalentTo(const CWalletTx& tx) const;
|
||||
|
||||
bool InMempool() const;
|
||||
bool IsTrusted() const;
|
||||
|
||||
int64_t GetTxTime() const;
|
||||
|
||||
@ -858,8 +857,6 @@ private:
|
||||
// ScriptPubKeyMan::GetID. In many cases it will be the hash of an internal structure
|
||||
std::map<uint256, std::unique_ptr<ScriptPubKeyMan>> m_spk_managers;
|
||||
|
||||
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, int nExtraPayloadSize) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);;
|
||||
|
||||
/**
|
||||
* Catch wallet up to current chain, scanning new blocks, updating the best
|
||||
* block locator and m_last_block_processed, and registering for
|
||||
@ -880,17 +877,6 @@ public:
|
||||
return *m_database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a set of coins such that nValueRet >= nTargetValue and at least
|
||||
* all coins from coin_control are selected; never select unconfirmed coins if they are not ours
|
||||
* param@[out] setCoinsRet Populated with inputs including pre-selected inputs from
|
||||
* coin_control and Coin Selection if successful.
|
||||
* param@[out] nValueRet Total value of selected coins including pre-selected ones
|
||||
* from coin_control and Coin Selection if successful.
|
||||
*/
|
||||
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);
|
||||
|
||||
/** Get a name for this wallet for logging/debugging purposes.
|
||||
*/
|
||||
const std::string& GetName() const { return m_name; }
|
||||
@ -972,25 +958,37 @@ public:
|
||||
bool coinjoin_available() { return m_coinjoin_loader != nullptr; }
|
||||
|
||||
const CWalletTx* GetWalletTx(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool IsTrusted(const CWalletTx& wtx, std::set<uint256>& trusted_parents) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
//! check whether we support the named feature
|
||||
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return IsFeatureSupported(nWalletVersion, wf); }
|
||||
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
||||
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
|
||||
// "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
|
||||
// resolve the issue of member access into incomplete type CWallet. Note
|
||||
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
|
||||
// in place.
|
||||
std::set<uint256> GetTxConflicts(const CWalletTx& wtx) const NO_THREAD_SAFETY_ANALYSIS;
|
||||
|
||||
/**
|
||||
* populate vCoins with vector of available COutputs.
|
||||
* Return depth of transaction in blockchain:
|
||||
* <0 : conflicts with a transaction this deep in the blockchain
|
||||
* 0 : in memory pool, waiting to be included in a block
|
||||
* >=1 : this many blocks deep in the main chain
|
||||
*/
|
||||
void AvailableCoins(std::vector<COutput>& vCoins, 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);
|
||||
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
||||
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
|
||||
// "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
|
||||
// resolve the issue of member access into incomplete type CWallet. Note
|
||||
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
|
||||
// in place.
|
||||
int GetTxDepthInMainChain(const CWalletTx& wtx) const NO_THREAD_SAFETY_ANALYSIS;
|
||||
bool IsTxInMainChain(const CWalletTx& wtx) const { return GetTxDepthInMainChain(wtx) > 0; }
|
||||
|
||||
/**
|
||||
* Return list of available coins and locked coins grouped by non-change output address.
|
||||
* @return number of blocks to maturity for this transaction:
|
||||
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
|
||||
* >0 : is a coinbase transaction which matures in this many blocks
|
||||
*/
|
||||
std::map<CTxDestination, std::vector<COutput>> ListCoins() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
/**
|
||||
* Find non-change parent output.
|
||||
*/
|
||||
const CTxOut& FindNonChangeParentOutput(const CTransaction& tx, int output) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
int GetTxBlocksToMaturity(const CWalletTx& wtx) const;
|
||||
bool IsTxImmatureCoinBase(const CWalletTx& wtx) const;
|
||||
|
||||
/**
|
||||
* Shuffle and select coins until nTargetValue is reached while avoiding
|
||||
@ -1030,8 +1028,6 @@ public:
|
||||
bool IsSpentKey(const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used, std::set<CTxDestination>& tx_destinations) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
std::vector<OutputGroup> GroupOutputs(const std::vector<COutput>& outputs, bool separate_coins, const CFeeRate& effective_feerate, const CFeeRate& long_term_feerate, const CoinEligibilityFilter& filter, bool positive_only) const;
|
||||
|
||||
bool IsLockedCoin(uint256 hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void LockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void UnlockCoin(const COutPoint& output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
@ -1115,31 +1111,12 @@ public:
|
||||
void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override;
|
||||
void ReacceptWalletTransactions() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void ResendWalletTransactions();
|
||||
struct Balance {
|
||||
CAmount m_mine_trusted{0}; //!< Trusted, at depth=GetBalance.min_depth or more
|
||||
CAmount m_mine_untrusted_pending{0}; //!< Untrusted, but in mempool (pending)
|
||||
CAmount m_mine_immature{0}; //!< Immature coinbases in the main chain
|
||||
CAmount m_watchonly_trusted{0};
|
||||
CAmount m_watchonly_untrusted_pending{0};
|
||||
CAmount m_watchonly_immature{0};
|
||||
CAmount m_anonymized{0};
|
||||
CAmount m_denominated_trusted{0};
|
||||
CAmount m_denominated_untrusted_pending{0};
|
||||
};
|
||||
Balance GetBalance(const int min_depth = 0, const bool avoid_reuse = true, const bool fAddLocked = false, const CCoinControl* coinControl = nullptr) const;
|
||||
|
||||
CAmount GetAnonymizableBalance(bool fSkipDenominated = false, bool fSkipUnconfirmed = true) const;
|
||||
float GetAverageAnonymizedRounds() const;
|
||||
CAmount GetNormalizedAnonymizedBalance() const;
|
||||
|
||||
bool GetBudgetSystemCollateralTX(CTransactionRef& tx, uint256 hash, CAmount amount, const COutPoint& outpoint=COutPoint()/*defaults null*/);
|
||||
CAmount GetAvailableBalance(const CCoinControl* coinControl = nullptr) const;
|
||||
|
||||
/**
|
||||
* Insert additional inputs into the transaction by
|
||||
* calling CreateTransaction();
|
||||
*/
|
||||
bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, bilingual_str& error, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl);
|
||||
/** Fetch the inputs and sign with SIGHASH_ALL. */
|
||||
bool SignTransaction(CMutableTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
/** Sign the tx given the input coins and sighash. */
|
||||
@ -1171,12 +1148,6 @@ public:
|
||||
bool bip32derivs = true,
|
||||
size_t* n_signed = nullptr) const;
|
||||
|
||||
/**
|
||||
* Create a new transaction paying the recipients with a set of coins
|
||||
* selected by SelectCoins(); Also create the change output, when needed
|
||||
* @note passing nChangePosInOut as -1 will result in setting a random position
|
||||
*/
|
||||
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, int nExtraPayloadSize = 0);
|
||||
/**
|
||||
* Submit the transaction to the node's mempool and then relay to peers.
|
||||
* Should be called after CreateTransaction unless you want to abort
|
||||
@ -1188,6 +1159,9 @@ public:
|
||||
*/
|
||||
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm);
|
||||
|
||||
/** Pass this transaction to node for mempool insertion and relay to peers if flag set to true */
|
||||
bool SubmitTxMemoryPoolAndRelay(const CWalletTx& wtx, std::string& err_string, bool relay) const;
|
||||
|
||||
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
|
||||
{
|
||||
std::vector<CTxOut> v_txouts(txouts.size());
|
||||
@ -1230,9 +1204,6 @@ public:
|
||||
|
||||
int64_t GetOldestKeyPoolTime() const;
|
||||
|
||||
std::set<std::set<CTxDestination>> GetAddressGroupings() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
std::map<CTxDestination, CAmount> GetAddressBalances() const;
|
||||
|
||||
std::set<CTxDestination> GetLabelAddresses(const std::string& label) const;
|
||||
|
||||
/**
|
||||
@ -1246,25 +1217,16 @@ public:
|
||||
|
||||
isminetype IsMine(const CTxDestination& dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
isminetype IsMine(const CScript& script) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
isminetype IsMine(const CTxIn& txin) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
/**
|
||||
* Returns amount of debit if the input matches the
|
||||
* filter, otherwise returns 0
|
||||
*/
|
||||
CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const;
|
||||
isminetype IsMine(const CTxOut& txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const;
|
||||
bool IsChange(const CTxOut& txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool IsChange(const CScript& script) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
CAmount GetChange(const CTxOut& txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool IsMine(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
/** should probably be renamed to IsRelevantToMe */
|
||||
bool IsFromMe(const CTransaction& tx) const;
|
||||
CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
|
||||
/** Returns whether all of the inputs match the filter */
|
||||
bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const;
|
||||
CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const;
|
||||
CAmount GetChange(const CTransaction& tx) const;
|
||||
void chainStateFlushed(const CBlockLocator& loc) override;
|
||||
|
||||
DBErrors LoadWallet();
|
||||
@ -1564,15 +1526,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Calculate the size of the transaction assuming all signatures are max size
|
||||
* Use DummySignatureCreator, which inserts 71 byte signatures everywhere.
|
||||
* NOTE: this requires that all inputs must be in mapWallet (eg the tx should
|
||||
* be IsAllFromMe). */
|
||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, bool use_max_sig = false) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet);
|
||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts, bool use_max_sig = false);
|
||||
|
||||
//! Add wallet name to persistent configuration so it will be loaded on startup.
|
||||
bool AddWalletSetting(interfaces::Chain& chain, const std::string& wallet_name);
|
||||
|
||||
|
@ -953,7 +953,7 @@ DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWal
|
||||
uint256 hash;
|
||||
ssKey >> hash;
|
||||
vTxHash.push_back(hash);
|
||||
vWtx.emplace_back(nullptr /* wallet */, nullptr /* tx */);
|
||||
vWtx.emplace_back(nullptr /* tx */);
|
||||
ssValue >> vWtx.back();
|
||||
}
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ class WalletTest(BitcoinTestFramework):
|
||||
total_txs = len(self.nodes[0].listtransactions("*", 99999))
|
||||
|
||||
# Try with walletrejectlongchains
|
||||
# Double chain limit but require combining inputs, so we pass SelectCoinsMinConf
|
||||
# Double chain limit but require combining inputs, so we pass AttemptSelection
|
||||
self.stop_node(0)
|
||||
extra_args = ["-walletrejectlongchains", "-limitancestorcount=" + str(2 * chainlimit)]
|
||||
self.start_node(0, extra_args=extra_args)
|
||||
|
Loading…
Reference in New Issue
Block a user