mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
wallet: Automatically abandon orphaned coinbases and their children
This commit is contained in:
parent
48174c0f28
commit
9addbd7890
3 changed files with 34 additions and 12 deletions
|
@ -293,6 +293,7 @@ public:
|
|||
|
||||
bool isAbandoned() const { return state<TxStateInactive>() && state<TxStateInactive>()->abandoned; }
|
||||
bool isConflicted() const { return state<TxStateConflicted>(); }
|
||||
bool isInactive() const { return state<TxStateInactive>(); }
|
||||
bool isUnconfirmed() const { return !isAbandoned() && !isConflicted() && !isConfirmed(); }
|
||||
bool isConfirmed() const { return state<TxStateConfirmed>(); }
|
||||
const uint256& GetHash() const { return tx->GetHash(); }
|
||||
|
|
|
@ -1067,6 +1067,33 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const
|
|||
}
|
||||
}
|
||||
|
||||
// Mark inactive coinbase transactions and their descendants as abandoned
|
||||
if (wtx.IsCoinBase() && wtx.isInactive()) {
|
||||
std::vector<CWalletTx*> txs{&wtx};
|
||||
|
||||
TxStateInactive inactive_state = TxStateInactive{/*abandoned=*/true};
|
||||
|
||||
while (!txs.empty()) {
|
||||
CWalletTx* desc_tx = txs.back();
|
||||
txs.pop_back();
|
||||
desc_tx->m_state = inactive_state;
|
||||
// Break caches since we have changed the state
|
||||
desc_tx->MarkDirty();
|
||||
batch.WriteTx(*desc_tx);
|
||||
MarkInputsDirty(desc_tx->tx);
|
||||
for (unsigned int i = 0; i < desc_tx->tx->vout.size(); ++i) {
|
||||
COutPoint outpoint(desc_tx->GetHash(), i);
|
||||
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(outpoint);
|
||||
for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
|
||||
const auto wit = mapWallet.find(it->second);
|
||||
if (wit != mapWallet.end()) {
|
||||
txs.push_back(&wit->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// debug print
|
||||
WalletLogPrintf("AddToWallet %s %s%s\n", hash.ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
|
||||
|
||||
|
@ -1276,7 +1303,11 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
|||
wtx.MarkDirty();
|
||||
batch.WriteTx(wtx);
|
||||
NotifyTransactionChanged(wtx.GetHash(), CT_UPDATED);
|
||||
// Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
|
||||
// Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too.
|
||||
// States are not permanent, so these transactions can become unabandoned if they are re-added to the
|
||||
// mempool, or confirmed in a block, or conflicted.
|
||||
// Note: If the reorged coinbase is re-added to the main chain, the descendants that have not had their
|
||||
// states change will remain abandoned and will require manual broadcast if the user wants them.
|
||||
for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
|
||||
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(COutPoint(now, i));
|
||||
for (TxSpends::const_iterator iter = range.first; iter != range.second; ++iter) {
|
||||
|
|
|
@ -37,17 +37,7 @@ class OrphanedBlockRewardTest(BitcoinTestFramework):
|
|||
# from the wallet can still be spent.
|
||||
self.nodes[0].invalidateblock(blk)
|
||||
self.generate(self.nodes[0], 152)
|
||||
# Without the following abandontransaction call, the coins are
|
||||
# not considered available yet.
|
||||
assert_equal(self.nodes[1].getbalances()["mine"], {
|
||||
"trusted": 0,
|
||||
"untrusted_pending": 0,
|
||||
"immature": 0,
|
||||
})
|
||||
# The following abandontransaction is necessary to make the later
|
||||
# lines succeed, and probably should not be needed; see
|
||||
# https://github.com/bitcoin/bitcoin/issues/14148.
|
||||
self.nodes[1].abandontransaction(txid)
|
||||
# We expect the descendants of orphaned rewards to no longer be considered
|
||||
assert_equal(self.nodes[1].getbalances()["mine"], {
|
||||
"trusted": 10,
|
||||
"untrusted_pending": 0,
|
||||
|
|
Loading…
Add table
Reference in a new issue