mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-19 06:43:45 +01:00
wallet: don't include unconfirmed v3 txs with children in available coins
This commit is contained in:
@@ -390,8 +390,11 @@ CoinsResult AvailableCoins(const CWallet& wallet,
|
||||
if (nDepth == 0 && params.check_version_trucness) {
|
||||
if (coinControl->m_version == TRUC_VERSION) {
|
||||
if (wtx.tx->version != TRUC_VERSION) continue;
|
||||
// this unconfirmed v3 transaction already has a child
|
||||
if (wtx.truc_child_in_mempool.has_value()) continue;
|
||||
} else {
|
||||
if (wtx.tx->version == TRUC_VERSION) continue;
|
||||
Assume(!wtx.truc_child_in_mempool.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -258,6 +258,10 @@ public:
|
||||
// BlockConflicted.
|
||||
std::set<Txid> mempool_conflicts;
|
||||
|
||||
// Track v3 mempool tx that spends from this tx
|
||||
// so that we don't try to create another unconfirmed child
|
||||
std::optional<Txid> truc_child_in_mempool;
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <node/types.h>
|
||||
#include <outputtype.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/truc_policy.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <psbt.h>
|
||||
@@ -1388,6 +1389,22 @@ void CWallet::transactionAddedToMempool(const CTransactionRef& tx) {
|
||||
return wtx.mempool_conflicts.insert(txid).second ? TxUpdate::CHANGED : TxUpdate::UNCHANGED;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (tx->version == TRUC_VERSION) {
|
||||
// Unconfirmed TRUC transactions are only allowed a 1-parent-1-child topology.
|
||||
// For any unconfirmed v3 parents (there should be a maximum of 1 except in reorgs),
|
||||
// record this child so the wallet doesn't try to spend any other outputs
|
||||
for (const CTxIn& tx_in : tx->vin) {
|
||||
auto parent_it = mapWallet.find(tx_in.prevout.hash);
|
||||
if (parent_it != mapWallet.end()) {
|
||||
CWalletTx& parent_wtx = parent_it->second;
|
||||
if (parent_wtx.isUnconfirmed()) {
|
||||
parent_wtx.truc_child_in_mempool = tx->GetHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1441,6 +1458,22 @@ void CWallet::transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRe
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (tx->version == TRUC_VERSION) {
|
||||
// If this tx has a parent, unset its truc_child_in_mempool to make it possible
|
||||
// to spend from the parent again. If this tx was replaced by another
|
||||
// child of the same parent, transactionAddedToMempool
|
||||
// will update truc_child_in_mempool
|
||||
for (const CTxIn& tx_in : tx->vin) {
|
||||
auto parent_it = mapWallet.find(tx_in.prevout.hash);
|
||||
if (parent_it != mapWallet.end()) {
|
||||
CWalletTx& parent_wtx = parent_it->second;
|
||||
if (parent_wtx.truc_child_in_mempool == tx->GetHash()) {
|
||||
parent_wtx.truc_child_in_mempool = std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWallet::blockConnected(ChainstateRole role, const interfaces::BlockInfo& block)
|
||||
|
||||
Reference in New Issue
Block a user