13 SendHeadersTest -- test behavior of headers messages to announce blocks. 17 - Two nodes, two p2p connections to node0. One p2p connection should only ever 18 receive inv's (omitted from testing description below, this is our control). 19 Second node is used for creating reorgs. 21 Part 1: No headers announcements before "sendheaders" 22 a. node mines a block [expect: inv] 23 send getdata for the block [expect: block] 24 b. node mines another block [expect: inv] 25 send getheaders and getdata [expect: headers, then block] 26 c. node mines another block [expect: inv] 27 peer mines a block, announces with header [expect: getdata] 28 d. node mines another block [expect: inv] 30 Part 2: After "sendheaders", headers announcements should generally work. 31 a. peer sends sendheaders [expect: no response] 32 peer sends getheaders with current tip [expect: no response] 33 b. node mines a block [expect: tip header] 34 c. for N in 1, ..., 10: 35 * for announce-type in {inv, header} 36 - peer mines N blocks, announces with announce-type 37 [ expect: getheaders/getdata or getdata, deliver block(s) ] 38 - node mines a block [ expect: 1 header ] 40 Part 3: Headers announcements stop after large reorg and resume after getheaders or inv from peer. 41 - For response-type in {inv, getheaders} 42 * node mines a 7 block reorg [ expect: headers announcement of 8 blocks ] 43 * node mines an 8-block reorg [ expect: inv at tip ] 44 * peer responds with getblocks/getdata [expect: inv, blocks ] 45 * node mines another block [ expect: inv at tip, peer sends getdata, expect: block ] 46 * node mines another block at tip [ expect: inv ] 47 * peer responds with getheaders with an old hashstop more than 8 blocks back [expect: headers] 48 * peer requests block [ expect: block ] 49 * node mines another block at tip [ expect: inv, peer sends getdata, expect: block ] 50 * peer sends response-type [expect headers if getheaders, getheaders/getdata if mining new block] 51 * node mines 1 block [expect: 1 header, peer responds with getdata] 53 Part 4: Test direct fetch behavior 54 a. Announce 2 old block headers. 55 Expect: no getdata requests. 56 b. Announce 3 new blocks via 1 headers message. 57 Expect: one getdata request for all 3 blocks. 59 c. Announce 1 header that forks off the last two blocks. 61 d. Announce 1 more header that builds on that fork. 62 Expect: one getdata request for two blocks. 63 e. Announce 16 more headers that build on that fork. 64 Expect: getdata request for 14 more blocks. 65 f. Announce 1 more header that builds on that fork. 71 NodeConnCB.__init__(self)
94 for x
in block_hashes:
95 msg.inv.append(
CInv(2, x))
100 msg.locator.vHave = locator
101 msg.hashstop = hashstop
106 msg.inv = [
CInv(2, blockhash)]
135 expect_headers = headers
if headers !=
None else []
136 expect_inv = inv
if inv !=
None else []
138 self.
sync(test_function)
145 compare_inv = [x.hash
for x
in self.
last_inv.inv]
146 if compare_inv != expect_inv:
152 hash_headers = [ x.sha256
for x
in self.
last_headers.headers ]
153 if hash_headers != expect_headers:
161 def sync(self, test_function, timeout=60):
168 raise AssertionError(
"Sync failed to complete")
173 self.
sync(test_function, timeout)
179 self.
sync(test_function, timeout)
187 self.
sync(test_function, timeout)
192 headers_message.headers = [
CBlockHeader(b)
for b
in new_blocks ]
197 getblocks_message.locator.vHave = locator
204 BaseNode.__init__(self)
209 BaseNode.__init__(self)
217 self.
nodes =
start_nodes(2, self.options.tmpdir, [[
"-debug",
"-logtimemicros=1"]]*2)
242 return [int(x, 16)
for x
in all_hashes]
256 inv_node.add_connection(connections[0])
257 test_node.add_connection(connections[1])
262 inv_node.wait_for_verack()
263 test_node.wait_for_verack()
269 print "Part 1: headers don't start before sendheaders message..." 273 assert_equal(inv_node.check_last_announcement(inv=[tip]),
True)
274 assert_equal(test_node.check_last_announcement(inv=[tip]),
True)
278 test_node.get_data([tip])
279 test_node.wait_for_block(tip, timeout=5)
282 test_node.get_headers(locator=[old_tip], hashstop=tip)
283 test_node.get_data([tip])
284 test_node.wait_for_block(tip)
285 test_node.clear_last_announcement()
290 block_time = last_time + 1
293 test_node.send_header_for_blocks([new_block])
294 test_node.wait_for_getdata([new_block.sha256], timeout=5)
295 test_node.send_message(
msg_block(new_block))
296 test_node.sync_with_ping()
297 inv_node.clear_last_announcement()
298 test_node.clear_last_announcement()
300 print "Part 1: success!" 301 print "Part 2: announce blocks with headers after sendheaders message..." 307 test_node.get_headers(locator=[prev_tip], hashstop=0L)
308 test_node.sync_with_ping()
312 assert_equal(inv_node.check_last_announcement(inv=[tip]),
True)
313 assert_equal(test_node.check_last_announcement(headers=[tip]),
True)
324 for b
in xrange(i+1):
327 tip = blocks[-1].sha256
332 test_node.send_block_inv(tip)
333 test_node.wait_for_getdata([tip], timeout=5)
336 inv_node.send_block_inv(tip)
338 test_node.send_header_for_blocks(blocks)
339 test_node.wait_for_getdata([x.sha256
for x
in blocks[0:-1]], timeout=5)
340 [ inv_node.send_block_inv(x.sha256)
for x
in blocks[0:-1] ]
341 inv_node.sync_with_ping()
344 test_node.send_header_for_blocks(blocks)
345 test_node.wait_for_getdata([x.sha256
for x
in blocks], timeout=5)
348 inv_node.send_header_for_blocks(blocks)
349 inv_node.sync_with_ping()
350 [ test_node.send_message(
msg_block(x))
for x
in blocks ]
351 test_node.sync_with_ping()
352 inv_node.sync_with_ping()
358 assert_equal(inv_node.check_last_announcement(inv=[tip]),
True)
359 assert_equal(test_node.check_last_announcement(headers=[tip]),
True)
363 print "Part 2: success!" 365 print "Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer..." 372 tip = new_block_hashes[-1]
373 assert_equal(inv_node.check_last_announcement(inv=[tip]),
True)
374 assert_equal(test_node.check_last_announcement(headers=new_block_hashes),
True)
380 tip = new_block_hashes[-1]
381 assert_equal(inv_node.check_last_announcement(inv=[tip]),
True)
382 assert_equal(test_node.check_last_announcement(inv=[tip]),
True)
386 fork_point = self.
nodes[0].
getblock(
"%02x" % new_block_hashes[0])[
"previousblockhash"]
387 fork_point = int(fork_point, 16)
390 test_node.send_getblocks(locator = [fork_point])
391 assert_equal(test_node.check_last_announcement(inv=new_block_hashes),
True)
392 test_node.get_data(new_block_hashes)
393 test_node.wait_for_block(new_block_hashes[-1])
398 assert_equal(inv_node.check_last_announcement(inv=[tip]),
True)
399 assert_equal(test_node.check_last_announcement(inv=[tip]),
True)
402 test_node.get_data([tip])
403 test_node.wait_for_block(tip)
407 test_node.get_headers(locator=[fork_point], hashstop=new_block_hashes[1])
408 test_node.get_data([tip])
409 test_node.wait_for_block(tip)
411 test_node.get_data([tip])
412 test_node.wait_for_block(tip)
417 test_node.get_headers(locator=[tip], hashstop=0L)
418 test_node.sync_with_ping()
420 test_node.send_block_inv(tip)
421 test_node.sync_with_ping()
424 assert_equal(inv_node.check_last_announcement(inv=[tip]),
True)
425 assert_equal(test_node.check_last_announcement(headers=[tip]),
True)
427 print "Part 3: success!" 429 print "Part 4: Testing direct fetch behavior..." 433 block_time = last_time + 1
440 tip = blocks[-1].sha256
443 inv_node.send_message(
msg_block(blocks[-1]))
445 inv_node.sync_with_ping()
446 test_node.last_getdata =
None 447 test_node.send_header_for_blocks(blocks)
448 test_node.sync_with_ping()
458 tip = blocks[-1].sha256
462 test_node.send_header_for_blocks(blocks)
463 test_node.sync_with_ping()
464 test_node.wait_for_getdata([x.sha256
for x
in blocks], timeout=test_node.sleep_time)
466 [ test_node.send_message(
msg_block(x))
for x
in blocks ]
468 test_node.sync_with_ping()
471 tip = blocks[0].sha256
479 tip = blocks[-1].sha256
485 test_node.last_getdata =
None 486 test_node.send_header_for_blocks(blocks[0:1])
487 test_node.sync_with_ping()
493 test_node.send_header_for_blocks(blocks[1:2])
494 test_node.sync_with_ping()
495 test_node.wait_for_getdata([x.sha256
for x
in blocks[0:2]], timeout=test_node.sleep_time)
499 test_node.send_header_for_blocks(blocks[2:18])
500 test_node.sync_with_ping()
501 test_node.wait_for_getdata([x.sha256
for x
in blocks[2:16]], timeout=test_node.sleep_time)
504 test_node.last_getdata =
None 505 test_node.send_header_for_blocks(blocks[18:19])
506 test_node.sync_with_ping()
510 print "Part 4: success!" 516 if __name__ ==
'__main__':
def start_nodes(num_nodes, dirname, extra_args=None, rpchost=None, binary=None)
UniValue getblock(const UniValue ¶ms, bool fHelp)
def connect_nodes(from_connection, node_num)
UniValue getblockhash(const UniValue ¶ms, bool fHelp)
UniValue getblockcount(const UniValue ¶ms, bool fHelp)
def initialize_chain_clean(test_dir, num_nodes)
UniValue generate(const UniValue ¶ms, bool fHelp)
def sync_blocks(rpc_connections, wait=1)
UniValue getbestblockhash(const UniValue ¶ms, bool fHelp)
def assert_equal(thing1, thing2)