Skip to content

Commit 436ad43

Browse files
Fix issue with conflicted mempool tx in listsinceblock
listsinceblock now checks that returned transactions are not conflicting with any transactions that are filtered out by the given blockhash Co-Authored-By: Michael Chrostowski <[email protected]>
1 parent 693e400 commit 436ad43

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
@@ -1591,7 +1591,7 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
15911591
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
15921592
CWalletTx tx = pairWtx.second;
15931593

1594-
if (depth == -1 || tx.GetDepthInMainChain(*locked_chain) < depth) {
1594+
if (depth == -1 || abs(tx.GetDepthInMainChain(*locked_chain)) < depth) {
15951595
ListTransactions(*locked_chain, pwallet, tx, 0, true, transactions, filter, nullptr /* filter_label */);
15961596
}
15971597
}

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)