mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-28 23:08:52 +01:00
Add new format string placeholders for walletnotify to include relevant block information for transactions
This commit is contained in:
@@ -17,7 +17,7 @@ from test_framework.util import (
|
||||
FILE_CHAR_START = 32 if os.name == 'nt' else 1
|
||||
FILE_CHAR_END = 128
|
||||
FILE_CHARS_DISALLOWED = '/\\?%*:|"<>' if os.name == 'nt' else '/'
|
||||
|
||||
UNCONFIRMED_HASH_STRING = 'unconfirmed'
|
||||
|
||||
def notify_outputname(walletname, txid):
|
||||
return txid if os.name == 'nt' else '{}_{}'.format(walletname, txid)
|
||||
@@ -43,7 +43,7 @@ class NotificationsTest(BitcoinTestFramework):
|
||||
"-blocknotify=echo > {}".format(os.path.join(self.blocknotify_dir, '%s')),
|
||||
], [
|
||||
"-rescan",
|
||||
"-walletnotify=echo > {}".format(os.path.join(self.walletnotify_dir, notify_outputname('%w', '%s'))),
|
||||
"-walletnotify=echo %h_%b > {}".format(os.path.join(self.walletnotify_dir, notify_outputname('%w', '%s'))),
|
||||
]]
|
||||
self.wallet_names = [self.default_wallet_name, self.wallet]
|
||||
super().setup_network()
|
||||
@@ -90,11 +90,9 @@ class NotificationsTest(BitcoinTestFramework):
|
||||
self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
|
||||
|
||||
# directory content should equal the generated transaction hashes
|
||||
txids_rpc = list(map(lambda t: notify_outputname(self.wallet, t['txid']), self.nodes[1].listtransactions("*", block_count)))
|
||||
assert_equal(sorted(txids_rpc), sorted(os.listdir(self.walletnotify_dir)))
|
||||
tx_details = list(map(lambda t: (t['txid'], t['blockheight'], t['blockhash']), self.nodes[1].listtransactions("*", block_count)))
|
||||
self.stop_node(1)
|
||||
for tx_file in os.listdir(self.walletnotify_dir):
|
||||
os.remove(os.path.join(self.walletnotify_dir, tx_file))
|
||||
self.expect_wallet_notify(tx_details)
|
||||
|
||||
self.log.info("test -walletnotify after rescan")
|
||||
# restart node to rescan to force wallet notifications
|
||||
@@ -104,10 +102,8 @@ class NotificationsTest(BitcoinTestFramework):
|
||||
self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
|
||||
|
||||
# directory content should equal the generated transaction hashes
|
||||
txids_rpc = list(map(lambda t: notify_outputname(self.wallet, t['txid']), self.nodes[1].listtransactions("*", block_count)))
|
||||
assert_equal(sorted(txids_rpc), sorted(os.listdir(self.walletnotify_dir)))
|
||||
for tx_file in os.listdir(self.walletnotify_dir):
|
||||
os.remove(os.path.join(self.walletnotify_dir, tx_file))
|
||||
tx_details = list(map(lambda t: (t['txid'], t['blockheight'], t['blockhash']), self.nodes[1].listtransactions("*", block_count)))
|
||||
self.expect_wallet_notify(tx_details)
|
||||
|
||||
# Conflicting transactions tests.
|
||||
# Generate spends from node 0, and check notifications
|
||||
@@ -122,7 +118,7 @@ class NotificationsTest(BitcoinTestFramework):
|
||||
tx1 = self.nodes[0].sendtoaddress(address=ADDRESS_BCRT1_UNSPENDABLE, amount=1, replaceable=True)
|
||||
assert_equal(tx1 in self.nodes[0].getrawmempool(), True)
|
||||
self.sync_mempools()
|
||||
self.expect_wallet_notify([tx1])
|
||||
self.expect_wallet_notify([(tx1, -1, UNCONFIRMED_HASH_STRING)])
|
||||
|
||||
# Generate bump transaction, sync mempools, and check for bump1
|
||||
# notification. In the future, per
|
||||
@@ -131,39 +127,57 @@ class NotificationsTest(BitcoinTestFramework):
|
||||
bump1 = self.nodes[0].bumpfee(tx1)["txid"]
|
||||
assert_equal(bump1 in self.nodes[0].getrawmempool(), True)
|
||||
self.sync_mempools()
|
||||
self.expect_wallet_notify([bump1])
|
||||
self.expect_wallet_notify([(bump1, -1, UNCONFIRMED_HASH_STRING)])
|
||||
|
||||
# Add bump1 transaction to new block, checking for a notification
|
||||
# and the correct number of confirmations.
|
||||
self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)
|
||||
blockhash1 = self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)[0]
|
||||
blockheight1 = self.nodes[0].getblockcount()
|
||||
self.sync_blocks()
|
||||
self.expect_wallet_notify([bump1])
|
||||
self.expect_wallet_notify([(bump1, blockheight1, blockhash1)])
|
||||
assert_equal(self.nodes[1].gettransaction(bump1)["confirmations"], 1)
|
||||
|
||||
# Generate a second transaction to be bumped.
|
||||
tx2 = self.nodes[0].sendtoaddress(address=ADDRESS_BCRT1_UNSPENDABLE, amount=1, replaceable=True)
|
||||
assert_equal(tx2 in self.nodes[0].getrawmempool(), True)
|
||||
self.sync_mempools()
|
||||
self.expect_wallet_notify([tx2])
|
||||
self.expect_wallet_notify([(tx2, -1, UNCONFIRMED_HASH_STRING)])
|
||||
|
||||
# Bump tx2 as bump2 and generate a block on node 0 while
|
||||
# disconnected, then reconnect and check for notifications on node 1
|
||||
# about newly confirmed bump2 and newly conflicted tx2.
|
||||
self.disconnect_nodes(0, 1)
|
||||
bump2 = self.nodes[0].bumpfee(tx2)["txid"]
|
||||
self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)
|
||||
blockhash2 = self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)[0]
|
||||
blockheight2 = self.nodes[0].getblockcount()
|
||||
assert_equal(self.nodes[0].gettransaction(bump2)["confirmations"], 1)
|
||||
assert_equal(tx2 in self.nodes[1].getrawmempool(), True)
|
||||
self.connect_nodes(0, 1)
|
||||
self.sync_blocks()
|
||||
self.expect_wallet_notify([bump2, tx2])
|
||||
self.expect_wallet_notify([(bump2, blockheight2, blockhash2), (tx2, -1, UNCONFIRMED_HASH_STRING)])
|
||||
assert_equal(self.nodes[1].gettransaction(bump2)["confirmations"], 1)
|
||||
|
||||
# TODO: add test for `-alertnotify` large fork notifications
|
||||
|
||||
def expect_wallet_notify(self, tx_ids):
|
||||
self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) >= len(tx_ids), timeout=10)
|
||||
assert_equal(sorted(notify_outputname(self.wallet, tx_id) for tx_id in tx_ids), sorted(os.listdir(self.walletnotify_dir)))
|
||||
def expect_wallet_notify(self, tx_details):
|
||||
self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) >= len(tx_details), timeout=10)
|
||||
# Should have no more and no less files than expected
|
||||
assert_equal(sorted(notify_outputname(self.wallet, tx_id) for tx_id, _, _ in tx_details), sorted(os.listdir(self.walletnotify_dir)))
|
||||
# Should now verify contents of each file
|
||||
for tx_id, blockheight, blockhash in tx_details:
|
||||
fname = os.path.join(self.walletnotify_dir, notify_outputname(self.wallet, tx_id))
|
||||
with open(fname, 'rt', encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
# Universal newline ensures '\n' on 'nt'
|
||||
assert_equal(text[-1], '\n')
|
||||
text = text[:-1]
|
||||
if os.name == 'nt':
|
||||
# On Windows, echo as above will append a whitespace
|
||||
assert_equal(text[-1], ' ')
|
||||
text = text[:-1]
|
||||
expected = str(blockheight) + '_' + blockhash
|
||||
assert_equal(text, expected)
|
||||
|
||||
for tx_file in os.listdir(self.walletnotify_dir):
|
||||
os.remove(os.path.join(self.walletnotify_dir, tx_file))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user