80
80
Expect: disconnect.
81
81
'''
82
82
83
- class BaseNode (NodeConnCB ):
83
+ direct_fetch_response_time = 0.05
84
+
85
+ class BaseNode (SingleNodeConnCB ):
84
86
def __init__ (self ):
85
- NodeConnCB .__init__ (self )
86
- self .connection = None
87
+ SingleNodeConnCB .__init__ (self )
87
88
self .last_inv = None
88
89
self .last_headers = None
89
90
self .last_block = None
90
- self .ping_counter = 1
91
- self .last_pong = msg_pong (0 )
92
91
self .last_getdata = None
93
- self .sleep_time = 0.05
94
92
self .block_announced = False
95
93
self .last_getheaders = None
96
94
self .disconnected = False
95
+ self .last_blockhash_announced = None
97
96
98
97
def clear_last_announcement (self ):
99
98
with mininode_lock :
100
99
self .block_announced = False
101
100
self .last_inv = None
102
101
self .last_headers = None
103
102
104
- def add_connection (self , conn ):
105
- self .connection = conn
106
-
107
103
# Request data for a list of block hashes
108
104
def get_data (self , block_hashes ):
109
105
msg = msg_getdata ()
@@ -122,17 +118,17 @@ def send_block_inv(self, blockhash):
122
118
msg .inv = [CInv (2 , blockhash )]
123
119
self .connection .send_message (msg )
124
120
125
- # Wrapper for the NodeConn's send_message function
126
- def send_message (self , message ):
127
- self .connection .send_message (message )
128
-
129
121
def on_inv (self , conn , message ):
130
122
self .last_inv = message
131
123
self .block_announced = True
124
+ self .last_blockhash_announced = message .inv [- 1 ].hash
132
125
133
126
def on_headers (self , conn , message ):
134
127
self .last_headers = message
135
- self .block_announced = True
128
+ if len (message .headers ):
129
+ self .block_announced = True
130
+ message .headers [- 1 ].calc_sha256 ()
131
+ self .last_blockhash_announced = message .headers [- 1 ].sha256
136
132
137
133
def on_block (self , conn , message ):
138
134
self .last_block = message .block
@@ -141,9 +137,6 @@ def on_block(self, conn, message):
141
137
def on_getdata (self , conn , message ):
142
138
self .last_getdata = message
143
139
144
- def on_pong (self , conn , message ):
145
- self .last_pong = message
146
-
147
140
def on_getheaders (self , conn , message ):
148
141
self .last_getheaders = message
149
142
@@ -157,7 +150,7 @@ def check_last_announcement(self, headers=None, inv=None):
157
150
expect_headers = headers if headers != None else []
158
151
expect_inv = inv if inv != None else []
159
152
test_function = lambda : self .block_announced
160
- self . sync ( test_function )
153
+ assert ( wait_until ( test_function , timeout = 60 ) )
161
154
with mininode_lock :
162
155
self .block_announced = False
163
156
@@ -180,43 +173,32 @@ def check_last_announcement(self, headers=None, inv=None):
180
173
return success
181
174
182
175
# Syncing helpers
183
- def sync (self , test_function , timeout = 60 ):
184
- while timeout > 0 :
185
- with mininode_lock :
186
- if test_function ():
187
- return
188
- time .sleep (self .sleep_time )
189
- timeout -= self .sleep_time
190
- raise AssertionError ("Sync failed to complete" )
191
-
192
- def sync_with_ping (self , timeout = 60 ):
193
- self .send_message (msg_ping (nonce = self .ping_counter ))
194
- test_function = lambda : self .last_pong .nonce == self .ping_counter
195
- self .sync (test_function , timeout )
196
- self .ping_counter += 1
197
- return
198
-
199
176
def wait_for_block (self , blockhash , timeout = 60 ):
200
177
test_function = lambda : self .last_block != None and self .last_block .sha256 == blockhash
201
- self . sync ( test_function , timeout )
178
+ assert ( wait_until ( test_function , timeout = timeout ) )
202
179
return
203
180
204
181
def wait_for_getheaders (self , timeout = 60 ):
205
182
test_function = lambda : self .last_getheaders != None
206
- self . sync ( test_function , timeout )
183
+ assert ( wait_until ( test_function , timeout = timeout ) )
207
184
return
208
185
209
186
def wait_for_getdata (self , hash_list , timeout = 60 ):
210
187
if hash_list == []:
211
188
return
212
189
213
190
test_function = lambda : self .last_getdata != None and [x .hash for x in self .last_getdata .inv ] == hash_list
214
- self . sync ( test_function , timeout )
191
+ assert ( wait_until ( test_function , timeout = timeout ) )
215
192
return
216
193
217
194
def wait_for_disconnect (self , timeout = 60 ):
218
195
test_function = lambda : self .disconnected
219
- self .sync (test_function , timeout )
196
+ assert (wait_until (test_function , timeout = timeout ))
197
+ return
198
+
199
+ def wait_for_block_announcement (self , block_hash , timeout = 60 ):
200
+ test_function = lambda : self .last_blockhash_announced == block_hash
201
+ assert (wait_until (test_function , timeout = timeout ))
220
202
return
221
203
222
204
def send_header_for_blocks (self , new_blocks ):
@@ -266,7 +248,9 @@ def mine_blocks(self, count):
266
248
def mine_reorg (self , length ):
267
249
self .nodes [0 ].generate (length ) # make sure all invalidated blocks are node0's
268
250
sync_blocks (self .nodes , wait = 0.1 )
269
- [x .clear_last_announcement () for x in self .p2p_connections ]
251
+ for x in self .p2p_connections :
252
+ x .wait_for_block_announcement (int (self .nodes [0 ].getbestblockhash (), 16 ))
253
+ x .clear_last_announcement ()
270
254
271
255
tip_height = self .nodes [1 ].getblockcount ()
272
256
hash_to_invalidate = self .nodes [1 ].getblockhash (tip_height - (length - 1 ))
@@ -495,7 +479,7 @@ def run_test(self):
495
479
496
480
test_node .send_header_for_blocks (blocks )
497
481
test_node .sync_with_ping ()
498
- test_node .wait_for_getdata ([x .sha256 for x in blocks ], timeout = test_node . sleep_time )
482
+ test_node .wait_for_getdata ([x .sha256 for x in blocks ], timeout = direct_fetch_response_time )
499
483
500
484
[ test_node .send_message (msg_block (x )) for x in blocks ]
501
485
@@ -526,13 +510,13 @@ def run_test(self):
526
510
# both blocks (same work as tip)
527
511
test_node .send_header_for_blocks (blocks [1 :2 ])
528
512
test_node .sync_with_ping ()
529
- test_node .wait_for_getdata ([x .sha256 for x in blocks [0 :2 ]], timeout = test_node . sleep_time )
513
+ test_node .wait_for_getdata ([x .sha256 for x in blocks [0 :2 ]], timeout = direct_fetch_response_time )
530
514
531
515
# Announcing 16 more headers should trigger direct fetch for 14 more
532
516
# blocks
533
517
test_node .send_header_for_blocks (blocks [2 :18 ])
534
518
test_node .sync_with_ping ()
535
- test_node .wait_for_getdata ([x .sha256 for x in blocks [2 :16 ]], timeout = test_node . sleep_time )
519
+ test_node .wait_for_getdata ([x .sha256 for x in blocks [2 :16 ]], timeout = direct_fetch_response_time )
536
520
537
521
# Announcing 1 more header should not trigger any response
538
522
test_node .last_getdata = None
0 commit comments