@@ -114,20 +114,14 @@ def __init__(self):
114
114
self .block_announced = False
115
115
self .last_blockhash_announced = None
116
116
117
- def clear_last_announcement (self ):
118
- with mininode_lock :
119
- self .block_announced = False
120
- self .last_message .pop ("inv" , None )
121
- self .last_message .pop ("headers" , None )
122
-
123
- # Request data for a list of block hashes
124
- def get_data (self , block_hashes ):
117
+ def send_get_data (self , block_hashes ):
118
+ """Request data for a list of block hashes."""
125
119
msg = msg_getdata ()
126
120
for x in block_hashes :
127
121
msg .inv .append (CInv (2 , x ))
128
122
self .connection .send_message (msg )
129
123
130
- def get_headers (self , locator , hashstop ):
124
+ def send_get_headers (self , locator , hashstop ):
131
125
msg = msg_getheaders ()
132
126
msg .locator .vHave = locator
133
127
msg .hashstop = hashstop
@@ -138,6 +132,25 @@ def send_block_inv(self, blockhash):
138
132
msg .inv = [CInv (2 , blockhash )]
139
133
self .connection .send_message (msg )
140
134
135
+ def send_header_for_blocks (self , new_blocks ):
136
+ headers_message = msg_headers ()
137
+ headers_message .headers = [CBlockHeader (b ) for b in new_blocks ]
138
+ self .send_message (headers_message )
139
+
140
+ def send_getblocks (self , locator ):
141
+ getblocks_message = msg_getblocks ()
142
+ getblocks_message .locator .vHave = locator
143
+ self .send_message (getblocks_message )
144
+
145
+ def wait_for_getdata (self , hash_list , timeout = 60 ):
146
+ if hash_list != []:
147
+ test_function = lambda : "getdata" in self .last_message and [x .hash for x in self .last_message ["getdata" ].inv ] == hash_list
148
+ wait_until (test_function , timeout = timeout , lock = mininode_lock )
149
+
150
+ def wait_for_block_announcement (self , block_hash , timeout = 60 ):
151
+ test_function = lambda : self .last_blockhash_announced == block_hash
152
+ wait_until (test_function , timeout = timeout , lock = mininode_lock )
153
+
141
154
def on_inv (self , conn , message ):
142
155
self .block_announced = True
143
156
self .last_blockhash_announced = message .inv [- 1 ].hash
@@ -148,10 +161,16 @@ def on_headers(self, conn, message):
148
161
message .headers [- 1 ].calc_sha256 ()
149
162
self .last_blockhash_announced = message .headers [- 1 ].sha256
150
163
151
- # Test whether the last announcement we received had the
152
- # right header or the right inv
153
- # inv and headers should be lists of block hashes
164
+ def clear_last_announcement (self ):
165
+ with mininode_lock :
166
+ self .block_announced = False
167
+ self .last_message .pop ("inv" , None )
168
+ self .last_message .pop ("headers" , None )
169
+
154
170
def check_last_announcement (self , headers = None , inv = None ):
171
+ """Test whether the last announcement received had the right header or the right inv.
172
+
173
+ inv and headers should be lists of block hashes."""
155
174
expect_headers = headers if headers is not None else []
156
175
expect_inv = inv if inv is not None else []
157
176
test_function = lambda : self .block_announced
@@ -177,47 +196,26 @@ def check_last_announcement(self, headers=None, inv=None):
177
196
self .last_message .pop ("headers" , None )
178
197
return success
179
198
180
- def wait_for_getdata (self , hash_list , timeout = 60 ):
181
- if hash_list == []:
182
- return
183
-
184
- test_function = lambda : "getdata" in self .last_message and [x .hash for x in self .last_message ["getdata" ].inv ] == hash_list
185
- wait_until (test_function , timeout = timeout , lock = mininode_lock )
186
- return
187
-
188
- def wait_for_block_announcement (self , block_hash , timeout = 60 ):
189
- test_function = lambda : self .last_blockhash_announced == block_hash
190
- wait_until (test_function , timeout = timeout , lock = mininode_lock )
191
- return
192
-
193
- def send_header_for_blocks (self , new_blocks ):
194
- headers_message = msg_headers ()
195
- headers_message .headers = [CBlockHeader (b ) for b in new_blocks ]
196
- self .send_message (headers_message )
197
-
198
- def send_getblocks (self , locator ):
199
- getblocks_message = msg_getblocks ()
200
- getblocks_message .locator .vHave = locator
201
- self .send_message (getblocks_message )
202
-
203
199
class SendHeadersTest (BitcoinTestFramework ):
204
200
def set_test_params (self ):
205
201
self .setup_clean_chain = True
206
202
self .num_nodes = 2
207
203
208
- # mine count blocks and return the new tip
209
204
def mine_blocks (self , count ):
205
+ """Mine count blocks and return the new tip."""
206
+
210
207
# Clear out last block announcement from each p2p listener
211
208
[x .clear_last_announcement () for x in self .nodes [0 ].p2ps ]
212
209
self .nodes [0 ].generate (count )
213
210
return int (self .nodes [0 ].getbestblockhash (), 16 )
214
211
215
- # mine a reorg that invalidates length blocks (replacing them with
216
- # length+1 blocks).
217
- # Note: we clear the state of our p2p connections after the
218
- # to-be-reorged-out blocks are mined, so that we don't break later tests.
219
- # return the list of block hashes newly mined
220
212
def mine_reorg (self , length ):
213
+ """Mine a reorg that invalidates length blocks (replacing them with # length+1 blocks).
214
+
215
+ Note: we clear the state of our p2p connections after the
216
+ to-be-reorged-out blocks are mined, so that we don't break later tests.
217
+ return the list of block hashes newly mined."""
218
+
221
219
self .nodes [0 ].generate (length ) # make sure all invalidated blocks are node0's
222
220
sync_blocks (self .nodes , wait = 0.1 )
223
221
for x in self .nodes [0 ].p2ps :
@@ -257,15 +255,15 @@ def test_null_locators(self, test_node):
257
255
258
256
self .log .info ("Verify getheaders with null locator and valid hashstop returns headers." )
259
257
test_node .clear_last_announcement ()
260
- test_node .get_headers (locator = [], hashstop = tip_hash )
258
+ test_node .send_get_headers (locator = [], hashstop = tip_hash )
261
259
assert_equal (test_node .check_last_announcement (headers = [tip_hash ]), True )
262
260
263
261
self .log .info ("Verify getheaders with null locator and invalid hashstop does not return headers." )
264
262
block = create_block (int (tip ["hash" ], 16 ), create_coinbase (tip ["height" ] + 1 ), tip ["mediantime" ] + 1 )
265
263
block .solve ()
266
264
test_node .send_header_for_blocks ([block ])
267
265
test_node .clear_last_announcement ()
268
- test_node .get_headers (locator = [], hashstop = int (block .hash , 16 ))
266
+ test_node .send_get_headers (locator = [], hashstop = int (block .hash , 16 ))
269
267
test_node .sync_with_ping ()
270
268
assert_equal (test_node .block_announced , False )
271
269
test_node .send_message (msg_block (block ))
@@ -284,12 +282,12 @@ def test_nonnull_locators(self, test_node, inv_node):
284
282
# Try a few different responses; none should affect next announcement
285
283
if i == 0 :
286
284
# first request the block
287
- test_node .get_data ([tip ])
285
+ test_node .send_get_data ([tip ])
288
286
test_node .wait_for_block (tip )
289
287
elif i == 1 :
290
288
# next try requesting header and block
291
- test_node .get_headers (locator = [old_tip ], hashstop = tip )
292
- test_node .get_data ([tip ])
289
+ test_node .send_get_headers (locator = [old_tip ], hashstop = tip )
290
+ test_node .send_get_data ([tip ])
293
291
test_node .wait_for_block (tip )
294
292
test_node .clear_last_announcement () # since we requested headers...
295
293
elif i == 2 :
@@ -313,7 +311,7 @@ def test_nonnull_locators(self, test_node, inv_node):
313
311
# commence and keep working.
314
312
test_node .send_message (msg_sendheaders ())
315
313
prev_tip = int (self .nodes [0 ].getbestblockhash (), 16 )
316
- test_node .get_headers (locator = [prev_tip ], hashstop = 0 )
314
+ test_node .send_get_headers (locator = [prev_tip ], hashstop = 0 )
317
315
test_node .sync_with_ping ()
318
316
319
317
# Now that we've synced headers, headers announcements should work
@@ -397,7 +395,7 @@ def test_nonnull_locators(self, test_node, inv_node):
397
395
# Use getblocks/getdata
398
396
test_node .send_getblocks (locator = [fork_point ])
399
397
assert_equal (test_node .check_last_announcement (inv = new_block_hashes ), True )
400
- test_node .get_data (new_block_hashes )
398
+ test_node .send_get_data (new_block_hashes )
401
399
test_node .wait_for_block (new_block_hashes [- 1 ])
402
400
403
401
for i in range (3 ):
@@ -407,22 +405,22 @@ def test_nonnull_locators(self, test_node, inv_node):
407
405
assert_equal (test_node .check_last_announcement (inv = [tip ]), True )
408
406
if i == 0 :
409
407
# Just get the data -- shouldn't cause headers announcements to resume
410
- test_node .get_data ([tip ])
408
+ test_node .send_get_data ([tip ])
411
409
test_node .wait_for_block (tip )
412
410
elif i == 1 :
413
411
# Send a getheaders message that shouldn't trigger headers announcements
414
412
# to resume (best header sent will be too old)
415
- test_node .get_headers (locator = [fork_point ], hashstop = new_block_hashes [1 ])
416
- test_node .get_data ([tip ])
413
+ test_node .send_get_headers (locator = [fork_point ], hashstop = new_block_hashes [1 ])
414
+ test_node .send_get_data ([tip ])
417
415
test_node .wait_for_block (tip )
418
416
elif i == 2 :
419
- test_node .get_data ([tip ])
417
+ test_node .send_get_data ([tip ])
420
418
test_node .wait_for_block (tip )
421
419
# This time, try sending either a getheaders to trigger resumption
422
420
# of headers announcements, or mine a new block and inv it, also
423
421
# triggering resumption of headers announcements.
424
422
if j == 0 :
425
- test_node .get_headers (locator = [tip ], hashstop = 0 )
423
+ test_node .send_get_headers (locator = [tip ], hashstop = 0 )
426
424
test_node .sync_with_ping ()
427
425
else :
428
426
test_node .send_block_inv (tip )
0 commit comments