Skip to content

Commit bfc4c89

Browse files
committed
Merge #17258: Fix issue with conflicted mempool tx in listsinceblock
436ad43 Fix issue with conflicted mempool tx in listsinceblock (Adam Jonas) Pull request description: Closes #8752 by bringing back abandoned #10470. This now checks that returned transactions are not conflicting with any transactions that are filtered out by the given blockhash and add a functional test to prevent this in the future. For more context, #8757 was closed in favor of #10470. ACKs for top commit: instagibbs: utACK bitcoin/bitcoin@436ad43 kallewoof: utACK 436ad43 jonatack: I'm not qualifed to give an ACK here but 436ad43 appears reasonable. Built/ran tests/verified that this test fails without the change in rpcwallet.cpp: Tree-SHA512: 63d75cd3d3f19fc84dc38899b200c96179b82b24db263cd0116ee5b715265be647157855c2e35912d2fbc49c7b37db9375d6aab0ac672f0f09bece8431de5ea9
2 parents bc38bb9 + 436ad43 commit bfc4c89

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1598,7 +1598,7 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
15981598
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
15991599
CWalletTx tx = pairWtx.second;
16001600

1601-
if (depth == -1 || tx.GetDepthInMainChain(*locked_chain) < depth) {
1601+
if (depth == -1 || abs(tx.GetDepthInMainChain(*locked_chain)) < depth) {
16021602
ListTransactions(*locked_chain, pwallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
16031603
}
16041604
}

test/functional/wallet_listsinceblock.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
"""Test the listsincelast RPC."""
66

77
from test_framework.test_framework import BitcoinTestFramework
8+
from test_framework.messages import BIP125_SEQUENCE_NUMBER
89
from test_framework.util import (
910
assert_array_result,
1011
assert_equal,
1112
assert_raises_rpc_error,
1213
connect_nodes,
1314
)
1415

16+
from decimal import Decimal
1517

1618
class ListSinceBlockTest(BitcoinTestFramework):
1719
def set_test_params(self):
@@ -33,6 +35,7 @@ def run_test(self):
3335
self.test_reorg()
3436
self.test_double_spend()
3537
self.test_double_send()
38+
self.double_spends_filtered()
3639

3740
def test_no_blockhash(self):
3841
txid = self.nodes[2].sendtoaddress(self.nodes[0].getnewaddress(), 1)
@@ -291,5 +294,51 @@ def test_double_send(self):
291294
if tx['txid'] == txid1:
292295
assert_equal(tx['confirmations'], 2)
293296

297+
def double_spends_filtered(self):
298+
'''
299+
`listsinceblock` was returning conflicted transactions even if they
300+
occurred before the specified cutoff blockhash
301+
'''
302+
spending_node = self.nodes[2]
303+
dest_address = spending_node.getnewaddress()
304+
305+
tx_input = dict(
306+
sequence=BIP125_SEQUENCE_NUMBER, **next(u for u in spending_node.listunspent()))
307+
rawtx = spending_node.createrawtransaction(
308+
[tx_input], {dest_address: tx_input["amount"] - Decimal("0.00051000"),
309+
spending_node.getrawchangeaddress(): Decimal("0.00050000")})
310+
signedtx = spending_node.signrawtransactionwithwallet(rawtx)
311+
orig_tx_id = spending_node.sendrawtransaction(signedtx["hex"])
312+
original_tx = spending_node.gettransaction(orig_tx_id)
313+
314+
double_tx = spending_node.bumpfee(orig_tx_id)
315+
316+
# check that both transactions exist
317+
block_hash = spending_node.listsinceblock(
318+
spending_node.getblockhash(spending_node.getblockcount()))
319+
original_found = False
320+
double_found = False
321+
for tx in block_hash['transactions']:
322+
if tx['txid'] == original_tx['txid']:
323+
original_found = True
324+
if tx['txid'] == double_tx['txid']:
325+
double_found = True
326+
assert_equal(original_found, True)
327+
assert_equal(double_found, True)
328+
329+
lastblockhash = spending_node.generate(1)[0]
330+
331+
# check that neither transaction exists
332+
block_hash = spending_node.listsinceblock(lastblockhash)
333+
original_found = False
334+
double_found = False
335+
for tx in block_hash['transactions']:
336+
if tx['txid'] == original_tx['txid']:
337+
original_found = True
338+
if tx['txid'] == double_tx['txid']:
339+
double_found = True
340+
assert_equal(original_found, False)
341+
assert_equal(double_found, False)
342+
294343
if __name__ == '__main__':
295344
ListSinceBlockTest().main()

0 commit comments

Comments
 (0)