17
17
FILE_CHAR_START = 32 if os .name == 'nt' else 1
18
18
FILE_CHAR_END = 128
19
19
FILE_CHARS_DISALLOWED = '/\\ ?%*:|"<>' if os .name == 'nt' else '/'
20
-
20
+ UNCONFIRMED_HASH_STRING = 'unconfirmed'
21
21
22
22
def notify_outputname (walletname , txid ):
23
23
return txid if os .name == 'nt' else '{}_{}' .format (walletname , txid )
@@ -43,7 +43,7 @@ def setup_network(self):
43
43
"-blocknotify=echo > {}" .format (os .path .join (self .blocknotify_dir , '%s' )),
44
44
], [
45
45
"-rescan" ,
46
- "-walletnotify=echo > {}" .format (os .path .join (self .walletnotify_dir , notify_outputname ('%w' , '%s' ))),
46
+ "-walletnotify=echo %h_%b > {}" .format (os .path .join (self .walletnotify_dir , notify_outputname ('%w' , '%s' ))),
47
47
]]
48
48
self .wallet_names = [self .default_wallet_name , self .wallet ]
49
49
super ().setup_network ()
@@ -90,11 +90,9 @@ def run_test(self):
90
90
self .wait_until (lambda : len (os .listdir (self .walletnotify_dir )) == block_count , timeout = 10 )
91
91
92
92
# directory content should equal the generated transaction hashes
93
- txids_rpc = list (map (lambda t : notify_outputname (self .wallet , t ['txid' ]), self .nodes [1 ].listtransactions ("*" , block_count )))
94
- assert_equal (sorted (txids_rpc ), sorted (os .listdir (self .walletnotify_dir )))
93
+ tx_details = list (map (lambda t : (t ['txid' ], t ['blockheight' ], t ['blockhash' ]), self .nodes [1 ].listtransactions ("*" , block_count )))
95
94
self .stop_node (1 )
96
- for tx_file in os .listdir (self .walletnotify_dir ):
97
- os .remove (os .path .join (self .walletnotify_dir , tx_file ))
95
+ self .expect_wallet_notify (tx_details )
98
96
99
97
self .log .info ("test -walletnotify after rescan" )
100
98
# restart node to rescan to force wallet notifications
@@ -104,10 +102,8 @@ def run_test(self):
104
102
self .wait_until (lambda : len (os .listdir (self .walletnotify_dir )) == block_count , timeout = 10 )
105
103
106
104
# directory content should equal the generated transaction hashes
107
- txids_rpc = list (map (lambda t : notify_outputname (self .wallet , t ['txid' ]), self .nodes [1 ].listtransactions ("*" , block_count )))
108
- assert_equal (sorted (txids_rpc ), sorted (os .listdir (self .walletnotify_dir )))
109
- for tx_file in os .listdir (self .walletnotify_dir ):
110
- os .remove (os .path .join (self .walletnotify_dir , tx_file ))
105
+ tx_details = list (map (lambda t : (t ['txid' ], t ['blockheight' ], t ['blockhash' ]), self .nodes [1 ].listtransactions ("*" , block_count )))
106
+ self .expect_wallet_notify (tx_details )
111
107
112
108
# Conflicting transactions tests.
113
109
# Generate spends from node 0, and check notifications
@@ -122,7 +118,7 @@ def run_test(self):
122
118
tx1 = self .nodes [0 ].sendtoaddress (address = ADDRESS_BCRT1_UNSPENDABLE , amount = 1 , replaceable = True )
123
119
assert_equal (tx1 in self .nodes [0 ].getrawmempool (), True )
124
120
self .sync_mempools ()
125
- self .expect_wallet_notify ([tx1 ])
121
+ self .expect_wallet_notify ([( tx1 , - 1 , UNCONFIRMED_HASH_STRING ) ])
126
122
127
123
# Generate bump transaction, sync mempools, and check for bump1
128
124
# notification. In the future, per
@@ -131,39 +127,57 @@ def run_test(self):
131
127
bump1 = self .nodes [0 ].bumpfee (tx1 )["txid" ]
132
128
assert_equal (bump1 in self .nodes [0 ].getrawmempool (), True )
133
129
self .sync_mempools ()
134
- self .expect_wallet_notify ([bump1 ])
130
+ self .expect_wallet_notify ([( bump1 , - 1 , UNCONFIRMED_HASH_STRING ) ])
135
131
136
132
# Add bump1 transaction to new block, checking for a notification
137
133
# and the correct number of confirmations.
138
- self .nodes [0 ].generatetoaddress (1 , ADDRESS_BCRT1_UNSPENDABLE )
134
+ blockhash1 = self .nodes [0 ].generatetoaddress (1 , ADDRESS_BCRT1_UNSPENDABLE )[0 ]
135
+ blockheight1 = self .nodes [0 ].getblockcount ()
139
136
self .sync_blocks ()
140
- self .expect_wallet_notify ([bump1 ])
137
+ self .expect_wallet_notify ([( bump1 , blockheight1 , blockhash1 ) ])
141
138
assert_equal (self .nodes [1 ].gettransaction (bump1 )["confirmations" ], 1 )
142
139
143
140
# Generate a second transaction to be bumped.
144
141
tx2 = self .nodes [0 ].sendtoaddress (address = ADDRESS_BCRT1_UNSPENDABLE , amount = 1 , replaceable = True )
145
142
assert_equal (tx2 in self .nodes [0 ].getrawmempool (), True )
146
143
self .sync_mempools ()
147
- self .expect_wallet_notify ([tx2 ])
144
+ self .expect_wallet_notify ([( tx2 , - 1 , UNCONFIRMED_HASH_STRING ) ])
148
145
149
146
# Bump tx2 as bump2 and generate a block on node 0 while
150
147
# disconnected, then reconnect and check for notifications on node 1
151
148
# about newly confirmed bump2 and newly conflicted tx2.
152
149
self .disconnect_nodes (0 , 1 )
153
150
bump2 = self .nodes [0 ].bumpfee (tx2 )["txid" ]
154
- self .nodes [0 ].generatetoaddress (1 , ADDRESS_BCRT1_UNSPENDABLE )
151
+ blockhash2 = self .nodes [0 ].generatetoaddress (1 , ADDRESS_BCRT1_UNSPENDABLE )[0 ]
152
+ blockheight2 = self .nodes [0 ].getblockcount ()
155
153
assert_equal (self .nodes [0 ].gettransaction (bump2 )["confirmations" ], 1 )
156
154
assert_equal (tx2 in self .nodes [1 ].getrawmempool (), True )
157
155
self .connect_nodes (0 , 1 )
158
156
self .sync_blocks ()
159
- self .expect_wallet_notify ([bump2 , tx2 ])
157
+ self .expect_wallet_notify ([( bump2 , blockheight2 , blockhash2 ), ( tx2 , - 1 , UNCONFIRMED_HASH_STRING ) ])
160
158
assert_equal (self .nodes [1 ].gettransaction (bump2 )["confirmations" ], 1 )
161
159
162
160
# TODO: add test for `-alertnotify` large fork notifications
163
161
164
- def expect_wallet_notify (self , tx_ids ):
165
- self .wait_until (lambda : len (os .listdir (self .walletnotify_dir )) >= len (tx_ids ), timeout = 10 )
166
- assert_equal (sorted (notify_outputname (self .wallet , tx_id ) for tx_id in tx_ids ), sorted (os .listdir (self .walletnotify_dir )))
162
+ def expect_wallet_notify (self , tx_details ):
163
+ self .wait_until (lambda : len (os .listdir (self .walletnotify_dir )) >= len (tx_details ), timeout = 10 )
164
+ # Should have no more and no less files than expected
165
+ assert_equal (sorted (notify_outputname (self .wallet , tx_id ) for tx_id , _ , _ in tx_details ), sorted (os .listdir (self .walletnotify_dir )))
166
+ # Should now verify contents of each file
167
+ for tx_id , blockheight , blockhash in tx_details :
168
+ fname = os .path .join (self .walletnotify_dir , notify_outputname (self .wallet , tx_id ))
169
+ with open (fname , 'rt' , encoding = 'utf-8' ) as f :
170
+ text = f .read ()
171
+ # Universal newline ensures '\n' on 'nt'
172
+ assert_equal (text [- 1 ], '\n ' )
173
+ text = text [:- 1 ]
174
+ if os .name == 'nt' :
175
+ # On Windows, echo as above will append a whitespace
176
+ assert_equal (text [- 1 ], ' ' )
177
+ text = text [:- 1 ]
178
+ expected = str (blockheight ) + '_' + blockhash
179
+ assert_equal (text , expected )
180
+
167
181
for tx_file in os .listdir (self .walletnotify_dir ):
168
182
os .remove (os .path .join (self .walletnotify_dir , tx_file ))
169
183
0 commit comments