mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Remove locked_chain from GetDepthInMainChain and its callers
We don't remove yet Chain locks as we need to preserve lock order with CWallet one until swapping at once to avoid deadlock failures (spotted by --enable-debug)
This commit is contained in:
parent
0ff03871ad
commit
b66c429c56
@ -31,7 +31,7 @@ namespace interfaces {
|
||||
namespace {
|
||||
|
||||
//! Construct wallet tx struct.
|
||||
WalletTx MakeWalletTx(interfaces::Chain::Lock& locked_chain, CWallet& wallet, const CWalletTx& wtx)
|
||||
WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
|
||||
{
|
||||
WalletTx result;
|
||||
result.tx = wtx.tx;
|
||||
@ -49,7 +49,7 @@ WalletTx MakeWalletTx(interfaces::Chain::Lock& locked_chain, CWallet& wallet, co
|
||||
wallet.IsMine(result.txout_address.back()) :
|
||||
ISMINE_NO);
|
||||
}
|
||||
result.credit = wtx.GetCredit(locked_chain, ISMINE_ALL);
|
||||
result.credit = wtx.GetCredit(ISMINE_ALL);
|
||||
result.debit = wtx.GetDebit(ISMINE_ALL);
|
||||
result.change = wtx.GetChange();
|
||||
result.time = wtx.GetTxTime();
|
||||
@ -63,21 +63,20 @@ WalletTxStatus MakeWalletTxStatus(interfaces::Chain::Lock& locked_chain, const C
|
||||
{
|
||||
WalletTxStatus result;
|
||||
result.block_height = locked_chain.getBlockHeight(wtx.m_confirm.hashBlock).get_value_or(std::numeric_limits<int>::max());
|
||||
result.blocks_to_maturity = wtx.GetBlocksToMaturity(locked_chain);
|
||||
result.depth_in_main_chain = wtx.GetDepthInMainChain(locked_chain);
|
||||
result.blocks_to_maturity = wtx.GetBlocksToMaturity();
|
||||
result.depth_in_main_chain = wtx.GetDepthInMainChain();
|
||||
result.time_received = wtx.nTimeReceived;
|
||||
result.lock_time = wtx.tx->nLockTime;
|
||||
result.is_final = locked_chain.checkFinalTx(*wtx.tx);
|
||||
result.is_trusted = wtx.IsTrusted(locked_chain);
|
||||
result.is_abandoned = wtx.isAbandoned();
|
||||
result.is_coinbase = wtx.IsCoinBase();
|
||||
result.is_in_main_chain = wtx.IsInMainChain(locked_chain);
|
||||
result.is_in_main_chain = wtx.IsInMainChain();
|
||||
return result;
|
||||
}
|
||||
|
||||
//! Construct wallet TxOut struct.
|
||||
WalletTxOut MakeWalletTxOut(interfaces::Chain::Lock& locked_chain,
|
||||
CWallet& wallet,
|
||||
WalletTxOut MakeWalletTxOut(CWallet& wallet,
|
||||
const CWalletTx& wtx,
|
||||
int n,
|
||||
int depth) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||
@ -86,7 +85,7 @@ WalletTxOut MakeWalletTxOut(interfaces::Chain::Lock& locked_chain,
|
||||
result.txout = wtx.tx->vout[n];
|
||||
result.time = wtx.GetTxTime();
|
||||
result.depth_in_main_chain = depth;
|
||||
result.is_spent = wallet.IsSpent(locked_chain, wtx.GetHash(), n);
|
||||
result.is_spent = wallet.IsSpent(wtx.GetHash(), n);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -235,7 +234,7 @@ public:
|
||||
{
|
||||
auto locked_chain = m_wallet->chain().lock();
|
||||
LOCK(m_wallet->cs_wallet);
|
||||
return m_wallet->AbandonTransaction(*locked_chain, txid);
|
||||
return m_wallet->AbandonTransaction(txid);
|
||||
}
|
||||
bool transactionCanBeBumped(const uint256& txid) override
|
||||
{
|
||||
@ -282,7 +281,7 @@ public:
|
||||
LOCK(m_wallet->cs_wallet);
|
||||
auto mi = m_wallet->mapWallet.find(txid);
|
||||
if (mi != m_wallet->mapWallet.end()) {
|
||||
return MakeWalletTx(*locked_chain, *m_wallet, mi->second);
|
||||
return MakeWalletTx(*m_wallet, mi->second);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@ -293,7 +292,7 @@ public:
|
||||
std::vector<WalletTx> result;
|
||||
result.reserve(m_wallet->mapWallet.size());
|
||||
for (const auto& entry : m_wallet->mapWallet) {
|
||||
result.emplace_back(MakeWalletTx(*locked_chain, *m_wallet, entry.second));
|
||||
result.emplace_back(MakeWalletTx(*m_wallet, entry.second));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -338,7 +337,7 @@ public:
|
||||
in_mempool = mi->second.InMempool();
|
||||
order_form = mi->second.vOrderForm;
|
||||
tx_status = MakeWalletTxStatus(*locked_chain, mi->second);
|
||||
return MakeWalletTx(*locked_chain, *m_wallet, mi->second);
|
||||
return MakeWalletTx(*m_wallet, mi->second);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@ -407,7 +406,7 @@ public:
|
||||
auto& group = result[entry.first];
|
||||
for (const auto& coin : entry.second) {
|
||||
group.emplace_back(COutPoint(coin.tx->GetHash(), coin.i),
|
||||
MakeWalletTxOut(*locked_chain, *m_wallet, *coin.tx, coin.i, coin.nDepth));
|
||||
MakeWalletTxOut(*m_wallet, *coin.tx, coin.i, coin.nDepth));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -422,9 +421,9 @@ public:
|
||||
result.emplace_back();
|
||||
auto it = m_wallet->mapWallet.find(output.hash);
|
||||
if (it != m_wallet->mapWallet.end()) {
|
||||
int depth = it->second.GetDepthInMainChain(*locked_chain);
|
||||
int depth = it->second.GetDepthInMainChain();
|
||||
if (depth >= 0) {
|
||||
result.back() = MakeWalletTxOut(*locked_chain, *m_wallet, it->second, output.n, depth);
|
||||
result.back() = MakeWalletTxOut(*m_wallet, it->second, output.n, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
//! Check whether transaction has descendant in wallet or mempool, or has been
|
||||
//! mined, or conflicts with a mined transaction. Return a feebumper::Result.
|
||||
static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chain, const CWallet& wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||
static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||
{
|
||||
if (wallet.HasWalletSpend(wtx.GetHash())) {
|
||||
errors.push_back("Transaction has descendants in the wallet");
|
||||
@ -30,7 +30,7 @@ static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chai
|
||||
}
|
||||
}
|
||||
|
||||
if (wtx.GetDepthInMainChain(locked_chain) != 0) {
|
||||
if (wtx.GetDepthInMainChain() != 0) {
|
||||
errors.push_back("Transaction has been mined, or is conflicted with a mined transaction");
|
||||
return feebumper::Result::WALLET_ERROR;
|
||||
}
|
||||
@ -146,7 +146,7 @@ bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid)
|
||||
if (wtx == nullptr) return false;
|
||||
|
||||
std::vector<std::string> errors_dummy;
|
||||
feebumper::Result res = PreconditionChecks(*locked_chain, wallet, *wtx, errors_dummy);
|
||||
feebumper::Result res = PreconditionChecks(wallet, *wtx, errors_dummy);
|
||||
return res == feebumper::Result::OK;
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, co
|
||||
}
|
||||
const CWalletTx& wtx = it->second;
|
||||
|
||||
Result result = PreconditionChecks(*locked_chain, *wallet, wtx, errors);
|
||||
Result result = PreconditionChecks(*wallet, wtx, errors);
|
||||
if (result != Result::OK) {
|
||||
return result;
|
||||
}
|
||||
@ -291,7 +291,7 @@ Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCo
|
||||
}
|
||||
const CWalletTx& wtx = it->second;
|
||||
|
||||
Result result = PreconditionChecks(*locked_chain, wallet, wtx, errors);
|
||||
Result result = PreconditionChecks(wallet, wtx, errors);
|
||||
if (result != Result::OK) {
|
||||
return result;
|
||||
}
|
||||
@ -382,7 +382,7 @@ Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransacti
|
||||
CWalletTx& oldWtx = it->second;
|
||||
|
||||
// make sure the transaction still has no descendants and hasn't been mined in the meantime
|
||||
Result result = PreconditionChecks(*locked_chain, wallet, oldWtx, errors);
|
||||
Result result = PreconditionChecks(wallet, oldWtx, errors);
|
||||
if (result != Result::OK) {
|
||||
return result;
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ UniValue importaddress(const JSONRPCRequest& request)
|
||||
{
|
||||
auto locked_chain = pwallet->chain().lock();
|
||||
LOCK(pwallet->cs_wallet);
|
||||
pwallet->ReacceptWalletTransactions(*locked_chain);
|
||||
pwallet->ReacceptWalletTransactions();
|
||||
}
|
||||
}
|
||||
|
||||
@ -514,7 +514,7 @@ UniValue importpubkey(const JSONRPCRequest& request)
|
||||
{
|
||||
auto locked_chain = pwallet->chain().lock();
|
||||
LOCK(pwallet->cs_wallet);
|
||||
pwallet->ReacceptWalletTransactions(*locked_chain);
|
||||
pwallet->ReacceptWalletTransactions();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1413,7 +1413,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
|
||||
{
|
||||
auto locked_chain = pwallet->chain().lock();
|
||||
LOCK(pwallet->cs_wallet);
|
||||
pwallet->ReacceptWalletTransactions(*locked_chain);
|
||||
pwallet->ReacceptWalletTransactions();
|
||||
}
|
||||
|
||||
if (pwallet->IsAbortingRescan()) {
|
||||
|
@ -126,7 +126,7 @@ void EnsureWalletIsUnlocked(const CWallet* pwallet)
|
||||
|
||||
static void WalletTxToJSON(interfaces::Chain& chain, interfaces::Chain::Lock& locked_chain, const CWalletTx& wtx, UniValue& entry)
|
||||
{
|
||||
int confirms = wtx.GetDepthInMainChain(locked_chain);
|
||||
int confirms = wtx.GetDepthInMainChain();
|
||||
entry.pushKV("confirmations", confirms);
|
||||
if (wtx.IsCoinBase())
|
||||
entry.pushKV("generated", true);
|
||||
@ -631,7 +631,7 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request)
|
||||
|
||||
for (const CTxOut& txout : wtx.tx->vout)
|
||||
if (txout.scriptPubKey == scriptPubKey)
|
||||
if (wtx.GetDepthInMainChain(*locked_chain) >= nMinDepth)
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
nAmount += txout.nValue;
|
||||
}
|
||||
|
||||
@ -697,7 +697,7 @@ static UniValue getreceivedbylabel(const JSONRPCRequest& request)
|
||||
{
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(txout.scriptPubKey, address) && pwallet->IsMine(address) && setAddress.count(address)) {
|
||||
if (wtx.GetDepthInMainChain(*locked_chain) >= nMinDepth)
|
||||
if (wtx.GetDepthInMainChain() >= nMinDepth)
|
||||
nAmount += txout.nValue;
|
||||
}
|
||||
}
|
||||
@ -1057,7 +1057,7 @@ static UniValue ListReceived(interfaces::Chain::Lock& locked_chain, CWallet * co
|
||||
continue;
|
||||
}
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
if (nDepth < nMinDepth)
|
||||
continue;
|
||||
|
||||
@ -1314,8 +1314,7 @@ static void ListTransactions(interfaces::Chain::Lock& locked_chain, CWallet* con
|
||||
}
|
||||
|
||||
// Received
|
||||
if (listReceived.size() > 0 && wtx.GetDepthInMainChain(locked_chain) >= nMinDepth)
|
||||
{
|
||||
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) {
|
||||
for (const COutputEntry& r : listReceived)
|
||||
{
|
||||
std::string label;
|
||||
@ -1332,9 +1331,9 @@ static void ListTransactions(interfaces::Chain::Lock& locked_chain, CWallet* con
|
||||
MaybePushAddress(entry, r.destination);
|
||||
if (wtx.IsCoinBase())
|
||||
{
|
||||
if (wtx.GetDepthInMainChain(locked_chain) < 1)
|
||||
if (wtx.GetDepthInMainChain() < 1)
|
||||
entry.pushKV("category", "orphan");
|
||||
else if (wtx.IsImmatureCoinBase(locked_chain))
|
||||
else if (wtx.IsImmatureCoinBase())
|
||||
entry.pushKV("category", "immature");
|
||||
else
|
||||
entry.pushKV("category", "generate");
|
||||
@ -1598,7 +1597,7 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
|
||||
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
|
||||
CWalletTx tx = pairWtx.second;
|
||||
|
||||
if (depth == -1 || abs(tx.GetDepthInMainChain(*locked_chain)) < depth) {
|
||||
if (depth == -1 || abs(tx.GetDepthInMainChain()) < depth) {
|
||||
ListTransactions(*locked_chain, pwallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
|
||||
}
|
||||
}
|
||||
@ -1715,7 +1714,7 @@ static UniValue gettransaction(const JSONRPCRequest& request)
|
||||
}
|
||||
const CWalletTx& wtx = it->second;
|
||||
|
||||
CAmount nCredit = wtx.GetCredit(*locked_chain, filter);
|
||||
CAmount nCredit = wtx.GetCredit(filter);
|
||||
CAmount nDebit = wtx.GetDebit(filter);
|
||||
CAmount nNet = nCredit - nDebit;
|
||||
CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
|
||||
@ -1779,7 +1778,7 @@ static UniValue abandontransaction(const JSONRPCRequest& request)
|
||||
if (!pwallet->mapWallet.count(hash)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
||||
}
|
||||
if (!pwallet->AbandonTransaction(*locked_chain, hash)) {
|
||||
if (!pwallet->AbandonTransaction(hash)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment");
|
||||
}
|
||||
|
||||
@ -2210,7 +2209,7 @@ static UniValue lockunspent(const JSONRPCRequest& request)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds");
|
||||
}
|
||||
|
||||
if (pwallet->IsSpent(*locked_chain, outpt.hash, outpt.n)) {
|
||||
if (pwallet->IsSpent(outpt.hash, outpt.n)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output");
|
||||
}
|
||||
|
||||
|
@ -281,13 +281,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(*locked_chain), 0);
|
||||
BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(), 0);
|
||||
|
||||
// Invalidate the cached vanue, 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(*locked_chain), 50*COIN);
|
||||
BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(), 50*COIN);
|
||||
}
|
||||
|
||||
static int64_t AddTx(CWallet& wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime)
|
||||
|
@ -452,7 +452,7 @@ void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> ran
|
||||
* Outpoint is spent if any non-conflicted transaction
|
||||
* spends it:
|
||||
*/
|
||||
bool CWallet::IsSpent(interfaces::Chain::Lock& locked_chain, const uint256& hash, unsigned int n) const
|
||||
bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
|
||||
{
|
||||
const COutPoint outpoint(hash, n);
|
||||
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
|
||||
@ -463,7 +463,7 @@ bool CWallet::IsSpent(interfaces::Chain::Lock& locked_chain, const uint256& hash
|
||||
const uint256& wtxid = it->second;
|
||||
std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
|
||||
if (mit != mapWallet.end()) {
|
||||
int depth = mit->second.GetDepthInMainChain(locked_chain);
|
||||
int depth = mit->second.GetDepthInMainChain();
|
||||
if (depth > 0 || (depth == 0 && !mit->second.isAbandoned()))
|
||||
return true; // Spent
|
||||
}
|
||||
@ -913,7 +913,7 @@ bool CWallet::TransactionCanBeAbandoned(const uint256& hashTx) const
|
||||
auto locked_chain = chain().lock();
|
||||
LOCK(cs_wallet);
|
||||
const CWalletTx* wtx = GetWalletTx(hashTx);
|
||||
return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain(*locked_chain) == 0 && !wtx->InMempool();
|
||||
return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain() == 0 && !wtx->InMempool();
|
||||
}
|
||||
|
||||
void CWallet::MarkInputsDirty(const CTransactionRef& tx)
|
||||
@ -926,9 +926,9 @@ void CWallet::MarkInputsDirty(const CTransactionRef& tx)
|
||||
}
|
||||
}
|
||||
|
||||
bool CWallet::AbandonTransaction(interfaces::Chain::Lock& locked_chain, const uint256& hashTx)
|
||||
bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||
{
|
||||
auto locked_chain_recursive = chain().lock(); // Temporary. Removed in upcoming lock cleanup
|
||||
auto locked_chain = chain().lock(); // Temporary. Removed in upcoming lock cleanup
|
||||
LOCK(cs_wallet);
|
||||
|
||||
WalletBatch batch(*database, "r+");
|
||||
@ -940,7 +940,7 @@ bool CWallet::AbandonTransaction(interfaces::Chain::Lock& locked_chain, const ui
|
||||
auto it = mapWallet.find(hashTx);
|
||||
assert(it != mapWallet.end());
|
||||
CWalletTx& origtx = it->second;
|
||||
if (origtx.GetDepthInMainChain(locked_chain) != 0 || origtx.InMempool()) {
|
||||
if (origtx.GetDepthInMainChain() != 0 || origtx.InMempool()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -953,7 +953,7 @@ bool CWallet::AbandonTransaction(interfaces::Chain::Lock& locked_chain, const ui
|
||||
auto it = mapWallet.find(now);
|
||||
assert(it != mapWallet.end());
|
||||
CWalletTx& wtx = it->second;
|
||||
int currentconfirm = wtx.GetDepthInMainChain(locked_chain);
|
||||
int currentconfirm = wtx.GetDepthInMainChain();
|
||||
// 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}
|
||||
@ -1009,7 +1009,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(*locked_chain);
|
||||
int currentconfirm = wtx.GetDepthInMainChain();
|
||||
if (conflictconfirms < currentconfirm) {
|
||||
// Block is 'more conflicted' than current confirm; update.
|
||||
// Mark transaction as conflicted with this block.
|
||||
@ -1691,7 +1691,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
|
||||
return result;
|
||||
}
|
||||
|
||||
void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
|
||||
void CWallet::ReacceptWalletTransactions()
|
||||
{
|
||||
// If transactions aren't being broadcasted, don't let them into local mempool either
|
||||
if (!fBroadcastTransactions)
|
||||
@ -1704,7 +1704,7 @@ void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
|
||||
CWalletTx& wtx = item.second;
|
||||
assert(wtx.GetHash() == wtxid);
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
|
||||
if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) {
|
||||
mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
|
||||
@ -1715,11 +1715,11 @@ void CWallet::ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain)
|
||||
for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
|
||||
CWalletTx& wtx = *(item.second);
|
||||
std::string unused_err_string;
|
||||
wtx.SubmitMemoryPoolAndRelay(unused_err_string, false, locked_chain);
|
||||
wtx.SubmitMemoryPoolAndRelay(unused_err_string, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool CWalletTx::SubmitMemoryPoolAndRelay(std::string& err_string, bool relay, interfaces::Chain::Lock& locked_chain)
|
||||
bool CWalletTx::SubmitMemoryPoolAndRelay(std::string& err_string, bool relay)
|
||||
{
|
||||
// Can't relay if wallet is not broadcasting
|
||||
if (!pwallet->GetBroadcastTransactions()) return false;
|
||||
@ -1729,7 +1729,7 @@ bool CWalletTx::SubmitMemoryPoolAndRelay(std::string& err_string, bool relay, in
|
||||
// cause log spam.
|
||||
if (IsCoinBase()) return false;
|
||||
// Don't try to submit conflicted or confirmed transactions.
|
||||
if (GetDepthInMainChain(locked_chain) != 0) return false;
|
||||
if (GetDepthInMainChain() != 0) return false;
|
||||
|
||||
// Submit transaction to mempool for relay
|
||||
pwallet->WalletLogPrintf("Submitting wtx %s to mempool for relay\n", GetHash().ToString());
|
||||
@ -1783,10 +1783,10 @@ CAmount CWalletTx::GetDebit(const isminefilter& filter) const
|
||||
return debit;
|
||||
}
|
||||
|
||||
CAmount CWalletTx::GetCredit(interfaces::Chain::Lock& locked_chain, const isminefilter& filter) const
|
||||
CAmount CWalletTx::GetCredit(const isminefilter& filter) const
|
||||
{
|
||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||
if (IsImmatureCoinBase(locked_chain))
|
||||
if (IsImmatureCoinBase())
|
||||
return 0;
|
||||
|
||||
CAmount credit = 0;
|
||||
@ -1800,16 +1800,16 @@ CAmount CWalletTx::GetCredit(interfaces::Chain::Lock& locked_chain, const ismine
|
||||
return credit;
|
||||
}
|
||||
|
||||
CAmount CWalletTx::GetImmatureCredit(interfaces::Chain::Lock& locked_chain, bool fUseCache) const
|
||||
CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
|
||||
{
|
||||
if (IsImmatureCoinBase(locked_chain) && IsInMainChain(locked_chain)) {
|
||||
if (IsImmatureCoinBase() && IsInMainChain()) {
|
||||
return GetCachableAmount(IMMATURE_CREDIT, ISMINE_SPENDABLE, !fUseCache);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAmount CWalletTx::GetAvailableCredit(interfaces::Chain::Lock& locked_chain, bool fUseCache, const isminefilter& filter) const
|
||||
CAmount CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& filter) const
|
||||
{
|
||||
if (pwallet == nullptr)
|
||||
return 0;
|
||||
@ -1818,7 +1818,7 @@ CAmount CWalletTx::GetAvailableCredit(interfaces::Chain::Lock& locked_chain, boo
|
||||
bool allow_cache = (filter & ISMINE_ALL) && (filter & ISMINE_ALL) != ISMINE_ALL;
|
||||
|
||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||
if (IsImmatureCoinBase(locked_chain))
|
||||
if (IsImmatureCoinBase())
|
||||
return 0;
|
||||
|
||||
if (fUseCache && allow_cache && m_amounts[AVAILABLE_CREDIT].m_cached[filter]) {
|
||||
@ -1830,7 +1830,7 @@ CAmount CWalletTx::GetAvailableCredit(interfaces::Chain::Lock& locked_chain, boo
|
||||
uint256 hashTx = GetHash();
|
||||
for (unsigned int i = 0; i < tx->vout.size(); i++)
|
||||
{
|
||||
if (!pwallet->IsSpent(locked_chain, hashTx, i) && (allow_used_addresses || !pwallet->IsUsedDestination(hashTx, i))) {
|
||||
if (!pwallet->IsSpent(hashTx, i) && (allow_used_addresses || !pwallet->IsUsedDestination(hashTx, i))) {
|
||||
const CTxOut &txout = tx->vout[i];
|
||||
nCredit += pwallet->GetCredit(txout, filter);
|
||||
if (!MoneyRange(nCredit))
|
||||
@ -1845,9 +1845,9 @@ CAmount CWalletTx::GetAvailableCredit(interfaces::Chain::Lock& locked_chain, boo
|
||||
return nCredit;
|
||||
}
|
||||
|
||||
CAmount CWalletTx::GetImmatureWatchOnlyCredit(interfaces::Chain::Lock& locked_chain, const bool fUseCache) const
|
||||
CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool fUseCache) const
|
||||
{
|
||||
if (IsImmatureCoinBase(locked_chain) && IsInMainChain(locked_chain)) {
|
||||
if (IsImmatureCoinBase() && IsInMainChain()) {
|
||||
return GetCachableAmount(IMMATURE_CREDIT, ISMINE_WATCH_ONLY, !fUseCache);
|
||||
}
|
||||
|
||||
@ -1878,7 +1878,7 @@ bool CWalletTx::IsTrusted(interfaces::Chain::Lock& locked_chain, std::set<uint25
|
||||
{
|
||||
// Quick answer in most cases
|
||||
if (!locked_chain.checkFinalTx(*tx)) return false;
|
||||
int nDepth = GetDepthInMainChain(locked_chain);
|
||||
int nDepth = GetDepthInMainChain();
|
||||
if (nDepth >= 1) return true;
|
||||
if (nDepth < 0) return false;
|
||||
// using wtx's cached debit
|
||||
@ -1954,7 +1954,7 @@ void CWallet::ResendWalletTransactions()
|
||||
// any confirmed or conflicting txs.
|
||||
if (wtx.nTimeReceived > m_best_block_time - 5 * 60) continue;
|
||||
std::string unused_err_string;
|
||||
if (wtx.SubmitMemoryPoolAndRelay(unused_err_string, true, *locked_chain)) ++submitted_tx_count;
|
||||
if (wtx.SubmitMemoryPoolAndRelay(unused_err_string, true)) ++submitted_tx_count;
|
||||
}
|
||||
} // locked_chain and cs_wallet
|
||||
|
||||
@ -1991,9 +1991,9 @@ CWallet::Balance CWallet::GetBalance(const int min_depth, bool avoid_reuse) cons
|
||||
{
|
||||
const CWalletTx& wtx = entry.second;
|
||||
const bool is_trusted{wtx.IsTrusted(*locked_chain, trusted_parents)};
|
||||
const int tx_depth{wtx.GetDepthInMainChain(*locked_chain)};
|
||||
const CAmount tx_credit_mine{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_SPENDABLE | reuse_filter)};
|
||||
const CAmount tx_credit_watchonly{wtx.GetAvailableCredit(*locked_chain, /* fUseCache */ true, ISMINE_WATCH_ONLY | reuse_filter)};
|
||||
const int tx_depth{wtx.GetDepthInMainChain()};
|
||||
const CAmount tx_credit_mine{wtx.GetAvailableCredit(/* fUseCache */ true, ISMINE_SPENDABLE | reuse_filter)};
|
||||
const CAmount tx_credit_watchonly{wtx.GetAvailableCredit(/* fUseCache */ true, ISMINE_WATCH_ONLY | reuse_filter)};
|
||||
if (is_trusted && tx_depth >= min_depth) {
|
||||
ret.m_mine_trusted += tx_credit_mine;
|
||||
ret.m_watchonly_trusted += tx_credit_watchonly;
|
||||
@ -2002,8 +2002,8 @@ CWallet::Balance CWallet::GetBalance(const int min_depth, bool avoid_reuse) cons
|
||||
ret.m_mine_untrusted_pending += tx_credit_mine;
|
||||
ret.m_watchonly_untrusted_pending += tx_credit_watchonly;
|
||||
}
|
||||
ret.m_mine_immature += wtx.GetImmatureCredit(*locked_chain);
|
||||
ret.m_watchonly_immature += wtx.GetImmatureWatchOnlyCredit(*locked_chain);
|
||||
ret.m_mine_immature += wtx.GetImmatureCredit();
|
||||
ret.m_watchonly_immature += wtx.GetImmatureWatchOnlyCredit();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -2047,10 +2047,10 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wtx.IsImmatureCoinBase(locked_chain))
|
||||
if (wtx.IsImmatureCoinBase())
|
||||
continue;
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
if (nDepth < 0)
|
||||
continue;
|
||||
|
||||
@ -2110,7 +2110,7 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
if (IsLockedCoin(entry.first, i))
|
||||
continue;
|
||||
|
||||
if (IsSpent(locked_chain, wtxid, i))
|
||||
if (IsSpent(wtxid, i))
|
||||
continue;
|
||||
|
||||
isminetype mine = IsMine(wtx.tx->vout[i]);
|
||||
@ -2169,7 +2169,7 @@ std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins(interfaces::Ch
|
||||
for (const COutPoint& output : lockedCoins) {
|
||||
auto it = mapWallet.find(output.hash);
|
||||
if (it != mapWallet.end()) {
|
||||
int depth = it->second.GetDepthInMainChain(locked_chain);
|
||||
int depth = it->second.GetDepthInMainChain();
|
||||
if (depth >= 0 && output.n < it->second.tx->vout.size() &&
|
||||
IsMine(it->second.tx->vout[output.n]) == ISMINE_SPENDABLE) {
|
||||
CTxDestination address;
|
||||
@ -2909,7 +2909,7 @@ void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
||||
}
|
||||
|
||||
std::string err_string;
|
||||
if (!wtx.SubmitMemoryPoolAndRelay(err_string, true, *locked_chain)) {
|
||||
if (!wtx.SubmitMemoryPoolAndRelay(err_string, true)) {
|
||||
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
|
||||
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
|
||||
}
|
||||
@ -3129,10 +3129,10 @@ std::map<CTxDestination, CAmount> CWallet::GetAddressBalances(interfaces::Chain:
|
||||
if (!wtx.IsTrusted(locked_chain, trusted_parents))
|
||||
continue;
|
||||
|
||||
if (wtx.IsImmatureCoinBase(locked_chain))
|
||||
if (wtx.IsImmatureCoinBase())
|
||||
continue;
|
||||
|
||||
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
||||
int nDepth = wtx.GetDepthInMainChain();
|
||||
if (nDepth < (wtx.IsFromMe(ISMINE_ALL) ? 0 : 1))
|
||||
continue;
|
||||
|
||||
@ -3144,7 +3144,7 @@ std::map<CTxDestination, CAmount> CWallet::GetAddressBalances(interfaces::Chain:
|
||||
if(!ExtractDestination(wtx.tx->vout[i].scriptPubKey, addr))
|
||||
continue;
|
||||
|
||||
CAmount n = IsSpent(locked_chain, walletEntry.first, i) ? 0 : wtx.tx->vout[i].nValue;
|
||||
CAmount n = IsSpent(walletEntry.first, i) ? 0 : wtx.tx->vout[i].nValue;
|
||||
|
||||
if (!balances.count(addr))
|
||||
balances[addr] = 0;
|
||||
@ -3908,7 +3908,7 @@ void CWallet::postInitProcess()
|
||||
|
||||
// Add wallet transactions that aren't already in a block to mempool
|
||||
// Do this here as mempool requires genesis block to be loaded
|
||||
ReacceptWalletTransactions(*locked_chain);
|
||||
ReacceptWalletTransactions();
|
||||
|
||||
// Update wallet transactions with current mempool transactions.
|
||||
chain().requestMempoolTransactions(*this);
|
||||
@ -3934,7 +3934,7 @@ CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn)
|
||||
m_pre_split = false;
|
||||
}
|
||||
|
||||
int CWalletTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
||||
int CWalletTx::GetDepthInMainChain() const
|
||||
{
|
||||
assert(pwallet != nullptr);
|
||||
AssertLockHeld(pwallet->cs_wallet);
|
||||
@ -3943,19 +3943,19 @@ int CWalletTx::GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const
|
||||
return (pwallet->GetLastBlockHeight() - m_confirm.block_height + 1) * (isConflicted() ? -1 : 1);
|
||||
}
|
||||
|
||||
int CWalletTx::GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const
|
||||
int CWalletTx::GetBlocksToMaturity() const
|
||||
{
|
||||
if (!IsCoinBase())
|
||||
return 0;
|
||||
int chain_depth = GetDepthInMainChain(locked_chain);
|
||||
int chain_depth = GetDepthInMainChain();
|
||||
assert(chain_depth >= 0); // coinbase tx should not be conflicted
|
||||
return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
|
||||
}
|
||||
|
||||
bool CWalletTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
|
||||
bool CWalletTx::IsImmatureCoinBase() const
|
||||
{
|
||||
// note GetBlocksToMaturity is 0 for non-coinbase tx
|
||||
return GetBlocksToMaturity(locked_chain) > 0;
|
||||
return GetBlocksToMaturity() > 0;
|
||||
}
|
||||
|
||||
std::vector<OutputGroup> CWallet::GroupOutputs(const std::vector<COutput>& outputs, bool single_coin) const {
|
||||
|
@ -449,14 +449,14 @@ public:
|
||||
|
||||
//! filter decides which addresses will count towards the debit
|
||||
CAmount GetDebit(const isminefilter& filter) const;
|
||||
CAmount GetCredit(interfaces::Chain::Lock& locked_chain, const isminefilter& filter) const;
|
||||
CAmount GetImmatureCredit(interfaces::Chain::Lock& locked_chain, bool fUseCache=true) const;
|
||||
CAmount GetCredit(const isminefilter& filter) const;
|
||||
CAmount GetImmatureCredit(bool fUseCache = true) const;
|
||||
// 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.
|
||||
CAmount GetAvailableCredit(interfaces::Chain::Lock& locked_chain, bool fUseCache=true, const isminefilter& filter=ISMINE_SPENDABLE) const NO_THREAD_SAFETY_ANALYSIS;
|
||||
CAmount GetImmatureWatchOnlyCredit(interfaces::Chain::Lock& locked_chain, const bool fUseCache=true) const;
|
||||
CAmount GetAvailableCredit(bool fUseCache = true, const isminefilter& filter = ISMINE_SPENDABLE) const NO_THREAD_SAFETY_ANALYSIS;
|
||||
CAmount GetImmatureWatchOnlyCredit(const bool fUseCache = true) const;
|
||||
CAmount GetChange() const;
|
||||
|
||||
// Get the marginal bytes if spending the specified output from this transaction
|
||||
@ -483,7 +483,7 @@ public:
|
||||
int64_t GetTxTime() const;
|
||||
|
||||
// Pass this transaction to node for mempool insertion and relay to peers if flag set to true
|
||||
bool SubmitMemoryPoolAndRelay(std::string& err_string, bool relay, interfaces::Chain::Lock& locked_chain);
|
||||
bool SubmitMemoryPoolAndRelay(std::string& err_string, bool relay);
|
||||
|
||||
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
||||
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
|
||||
@ -505,15 +505,15 @@ public:
|
||||
// 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 GetDepthInMainChain(interfaces::Chain::Lock& locked_chain) const NO_THREAD_SAFETY_ANALYSIS;
|
||||
bool IsInMainChain(interfaces::Chain::Lock& locked_chain) const { return GetDepthInMainChain(locked_chain) > 0; }
|
||||
int GetDepthInMainChain() const NO_THREAD_SAFETY_ANALYSIS;
|
||||
bool IsInMainChain() const { return GetDepthInMainChain() > 0; }
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
int GetBlocksToMaturity(interfaces::Chain::Lock& locked_chain) const;
|
||||
int GetBlocksToMaturity() const;
|
||||
bool isAbandoned() const { return m_confirm.status == CWalletTx::ABANDONED; }
|
||||
void setAbandoned()
|
||||
{
|
||||
@ -530,7 +530,7 @@ public:
|
||||
void setConfirmed() { m_confirm.status = CWalletTx::CONFIRMED; }
|
||||
const uint256& GetHash() const { return tx->GetHash(); }
|
||||
bool IsCoinBase() const { return tx->IsCoinBase(); }
|
||||
bool IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const;
|
||||
bool IsImmatureCoinBase() const;
|
||||
};
|
||||
|
||||
class COutput
|
||||
@ -808,7 +808,7 @@ public:
|
||||
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;
|
||||
|
||||
bool IsSpent(interfaces::Chain::Lock& locked_chain, const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool IsSpent(const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
// Whether this or any UTXO with the same CTxDestination has been spent.
|
||||
bool IsUsedDestination(const CTxDestination& dst) const;
|
||||
@ -891,7 +891,7 @@ public:
|
||||
};
|
||||
ScanResult ScanForWalletTransactions(const uint256& first_block, const uint256& last_block, const WalletRescanReserver& reserver, bool fUpdate);
|
||||
void TransactionRemovedFromMempool(const CTransactionRef &ptx) override;
|
||||
void ReacceptWalletTransactions(interfaces::Chain::Lock& locked_chain) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void ReacceptWalletTransactions() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void ResendWalletTransactions();
|
||||
struct Balance {
|
||||
CAmount m_mine_trusted{0}; //!< Trusted, at depth=GetBalance.min_depth or more
|
||||
@ -1070,7 +1070,7 @@ public:
|
||||
bool TransactionCanBeAbandoned(const uint256& hashTx) const;
|
||||
|
||||
/* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */
|
||||
bool AbandonTransaction(interfaces::Chain::Lock& locked_chain, const uint256& hashTx);
|
||||
bool AbandonTransaction(const uint256& hashTx);
|
||||
|
||||
/** Mark a transaction as replaced by another transaction (e.g., BIP 125). */
|
||||
bool MarkReplaced(const uint256& originalHash, const uint256& newHash);
|
||||
|
Loading…
Reference in New Issue
Block a user