Skip to content

Commit 99c0372

Browse files
committed
Merge #18878: test: Add test for conflicted wallet tx notifications
f963a68 test: Add test for conflicted wallet tx notifications (Russell Yanofsky) Pull request description: Add test coverage for conflicted wallet transaction notifications so we can improve current behavior and avoid future regressions bitcoin/bitcoin#9240 - accidental break bitcoin/bitcoin#9479 - bug report bitcoin/bitcoin#9371 - fix bitcoin/bitcoin#16624 - accidental break bitcoin/bitcoin#18325 - bug report bitcoin/bitcoin#18600 - potential fix ACKs for top commit: laanwj: ACK f963a68 jonatack: re-ACK f963a68 MarcoFalke: ACK f963a68 Tree-SHA512: d3a7952a2d3dc2ff0800ef857575ea4ef9759c0917d58a7fc91e2db0ca3cc3baf0dd0cf9af61683f691e5fefb11afe8120bb5810c7037ed9ecedee385dd4aa07
2 parents 6c647c8 + f963a68 commit 99c0372

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

test/functional/feature_notifications.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
"""Test the -alertnotify, -blocknotify and -walletnotify options."""
66
import os
77

8-
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE
8+
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE, keyhash_to_p2pkh
99
from test_framework.test_framework import BitcoinTestFramework
1010
from test_framework.util import (
1111
assert_equal,
1212
wait_until,
1313
connect_nodes,
14+
disconnect_nodes,
15+
hex_str_to_bytes,
1416
)
1517

1618
# Linux allow all characters other than \x00
@@ -81,8 +83,72 @@ def run_test(self):
8183
# directory content should equal the generated transaction hashes
8284
txids_rpc = list(map(lambda t: notify_outputname(self.wallet, t['txid']), self.nodes[1].listtransactions("*", block_count)))
8385
assert_equal(sorted(txids_rpc), sorted(os.listdir(self.walletnotify_dir)))
86+
for tx_file in os.listdir(self.walletnotify_dir):
87+
os.remove(os.path.join(self.walletnotify_dir, tx_file))
88+
89+
# Conflicting transactions tests. Give node 0 same wallet seed as
90+
# node 1, generate spends from node 0, and check notifications
91+
# triggered by node 1
92+
self.log.info("test -walletnotify with conflicting transactions")
93+
self.nodes[0].sethdseed(seed=self.nodes[1].dumpprivkey(keyhash_to_p2pkh(hex_str_to_bytes(self.nodes[1].getwalletinfo()['hdseedid'])[::-1])))
94+
self.nodes[0].rescanblockchain()
95+
self.nodes[0].generatetoaddress(100, ADDRESS_BCRT1_UNSPENDABLE)
96+
97+
# Generate transaction on node 0, sync mempools, and check for
98+
# notification on node 1.
99+
tx1 = self.nodes[0].sendtoaddress(address=ADDRESS_BCRT1_UNSPENDABLE, amount=1, replaceable=True)
100+
assert_equal(tx1 in self.nodes[0].getrawmempool(), True)
101+
self.sync_mempools()
102+
self.expect_wallet_notify([tx1])
103+
104+
# Generate bump transaction, sync mempools, and check for bump1
105+
# notification. In the future, per
106+
# https://github.com/bitcoin/bitcoin/pull/9371, it might be better
107+
# to have notifications for both tx1 and bump1.
108+
bump1 = self.nodes[0].bumpfee(tx1)["txid"]
109+
assert_equal(bump1 in self.nodes[0].getrawmempool(), True)
110+
self.sync_mempools()
111+
self.expect_wallet_notify([bump1])
112+
113+
# Add bump1 transaction to new block, checking for a notification
114+
# and the correct number of confirmations.
115+
self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)
116+
self.sync_blocks()
117+
self.expect_wallet_notify([bump1])
118+
assert_equal(self.nodes[1].gettransaction(bump1)["confirmations"], 1)
119+
120+
# Generate a second transaction to be bumped.
121+
tx2 = self.nodes[0].sendtoaddress(address=ADDRESS_BCRT1_UNSPENDABLE, amount=1, replaceable=True)
122+
assert_equal(tx2 in self.nodes[0].getrawmempool(), True)
123+
self.sync_mempools()
124+
self.expect_wallet_notify([tx2])
125+
126+
# Bump tx2 as bump2 and generate a block on node 0 while
127+
# disconnected, then reconnect and check for notifications on node 1
128+
# about newly confirmed bump2 and newly conflicted tx2. Currently
129+
# only the bump2 notification is sent. Ideally, notifications would
130+
# be sent both for bump2 and tx2, which was the previous behavior
131+
# before being broken by an accidental change in PR
132+
# https://github.com/bitcoin/bitcoin/pull/16624. The bug is reported
133+
# in issue https://github.com/bitcoin/bitcoin/issues/18325.
134+
disconnect_nodes(self.nodes[0], 1)
135+
bump2 = self.nodes[0].bumpfee(tx2)["txid"]
136+
self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)
137+
assert_equal(self.nodes[0].gettransaction(bump2)["confirmations"], 1)
138+
assert_equal(tx2 in self.nodes[1].getrawmempool(), True)
139+
connect_nodes(self.nodes[0], 1)
140+
self.sync_blocks()
141+
self.expect_wallet_notify([bump2])
142+
assert_equal(self.nodes[1].gettransaction(bump2)["confirmations"], 1)
84143

85144
# TODO: add test for `-alertnotify` large fork notifications
86145

146+
def expect_wallet_notify(self, tx_ids):
147+
wait_until(lambda: len(os.listdir(self.walletnotify_dir)) >= len(tx_ids), timeout=10)
148+
assert_equal(sorted(notify_outputname(self.wallet, tx_id) for tx_id in tx_ids), sorted(os.listdir(self.walletnotify_dir)))
149+
for tx_file in os.listdir(self.walletnotify_dir):
150+
os.remove(os.path.join(self.walletnotify_dir, tx_file))
151+
152+
87153
if __name__ == '__main__':
88154
NotificationsTest().main()

0 commit comments

Comments
 (0)