Merge #13652: rpc: Fix that CWallet::AbandonTransaction would leave the grandchildren, etc. active
89e70f9d7f
Fix that CWallet::AbandonTransaction would only traverse one level (Ben Woosley)
Pull request description:
Prior to this change, it would mark only the first layer of
child transactions abandoned, due to always following the input `hashTx`
rather than the current `now` tx.
Tree-SHA512: df068b49637d299ad73237c7244005fe5aa966d6beae57aff12e6948f173d9381e1b5d08533f7e3a1416991ed57f9f1f7b834057141d85c07dc60bb1f0872cea
This commit is contained in:
commit
17943f77bd
2 changed files with 11 additions and 3 deletions
|
@ -1143,7 +1143,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||||
batch.WriteTx(wtx);
|
batch.WriteTx(wtx);
|
||||||
NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED);
|
NotifyTransactionChanged(this, 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
|
||||||
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0));
|
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
|
||||||
while (iter != mapTxSpends.end() && iter->first.hash == now) {
|
while (iter != mapTxSpends.end() && iter->first.hash == now) {
|
||||||
if (!done.count(iter->second)) {
|
if (!done.count(iter->second)) {
|
||||||
todo.insert(iter->second);
|
todo.insert(iter->second);
|
||||||
|
|
|
@ -70,9 +70,17 @@ class AbandonConflictTest(BitcoinTestFramework):
|
||||||
signed2 = self.nodes[0].signrawtransactionwithwallet(self.nodes[0].createrawtransaction(inputs, outputs))
|
signed2 = self.nodes[0].signrawtransactionwithwallet(self.nodes[0].createrawtransaction(inputs, outputs))
|
||||||
txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"])
|
txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"])
|
||||||
|
|
||||||
|
# Create a child tx spending ABC2
|
||||||
|
signed3_change = Decimal("24.999")
|
||||||
|
inputs = [ {"txid":txABC2, "vout":0} ]
|
||||||
|
outputs = { self.nodes[0].getnewaddress(): signed3_change }
|
||||||
|
signed3 = self.nodes[0].signrawtransactionwithwallet(self.nodes[0].createrawtransaction(inputs, outputs))
|
||||||
|
# note tx is never directly referenced, only abandoned as a child of the above
|
||||||
|
self.nodes[0].sendrawtransaction(signed3["hex"])
|
||||||
|
|
||||||
# In mempool txs from self should increase balance from change
|
# In mempool txs from self should increase balance from change
|
||||||
newbalance = self.nodes[0].getbalance()
|
newbalance = self.nodes[0].getbalance()
|
||||||
assert_equal(newbalance, balance - Decimal("30") + Decimal("24.9996"))
|
assert_equal(newbalance, balance - Decimal("30") + signed3_change)
|
||||||
balance = newbalance
|
balance = newbalance
|
||||||
|
|
||||||
# Restart the node with a higher min relay fee so the parent tx is no longer in mempool
|
# Restart the node with a higher min relay fee so the parent tx is no longer in mempool
|
||||||
|
@ -87,7 +95,7 @@ class AbandonConflictTest(BitcoinTestFramework):
|
||||||
# Not in mempool txs from self should only reduce balance
|
# Not in mempool txs from self should only reduce balance
|
||||||
# inputs are still spent, but change not received
|
# inputs are still spent, but change not received
|
||||||
newbalance = self.nodes[0].getbalance()
|
newbalance = self.nodes[0].getbalance()
|
||||||
assert_equal(newbalance, balance - Decimal("24.9996"))
|
assert_equal(newbalance, balance - signed3_change)
|
||||||
# Unconfirmed received funds that are not in mempool, also shouldn't show
|
# Unconfirmed received funds that are not in mempool, also shouldn't show
|
||||||
# up in unconfirmed balance
|
# up in unconfirmed balance
|
||||||
unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance()
|
unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance()
|
||||||
|
|
Loading…
Reference in a new issue