From c32423758ff9645df41a9e9f048805c481b4d756 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Thu, 10 Oct 2024 12:25:56 -0400 Subject: [PATCH] test: increases test coverage of near-tip parallel block dl --- test/functional/p2p_ibd_stalling.py | 78 ++++++++++++++++++----------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/test/functional/p2p_ibd_stalling.py b/test/functional/p2p_ibd_stalling.py index 424a4cc978332..de78a751b51e9 100755 --- a/test/functional/p2p_ibd_stalling.py +++ b/test/functional/p2p_ibd_stalling.py @@ -154,38 +154,60 @@ def ibd_stalling(self): def near_tip_stalling(self): node = self.nodes[1] - peers = [] - stall_block = self.blocks[0].sha256 - self.log.info("Part 2: Test stalling close to the tip") - # only send 1024 headers, so that the window can't overshoot and the ibd stalling mechanism isn't triggered - headers_message = msg_headers() - headers_message.headers = [CBlockHeader(b) for b in self.blocks[:self.NUM_BLOCKS-1]] - self.log.info("Add three stalling peers") - for id in range(3): - peers.append(node.add_outbound_p2p_connection(P2PStaller(stall_block), p2p_idx=id, connection_type="outbound-full-relay")) - peers[-1].block_store = self.block_dict - peers[-1].send_message(headers_message) - self.wait_until(lambda: sum(len(peer['inflight']) for peer in node.getpeerinfo()) == 1) - self.all_sync_send_with_ping(peers) - assert_equal(sum(peer.stall_block_requested for peer in peers), 1) + self.log.info("Part 3: Test stalling close to the tip") - self.log.info("Check that after 30 seconds we request the block from a second peer") - self.mocktime = int(time.time()) + 31 - node.setmocktime(self.mocktime) - self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 2) + # only send <= 1024 headers, so that the window can't overshoot and the ibd stalling mechanism isn't triggered + # make sure it works at different lengths + for header_length in [1, 10, 1024]: + peers = [] + stall_block = self.blocks[0].sha256 + headers_message = msg_headers() + headers_message.headers = [CBlockHeader(b) for b in self.blocks[:self.NUM_BLOCKS-1][:header_length]] - self.log.info("Check that after another 30 seconds we request the block from a third peer") - self.mocktime += 31 - node.setmocktime(self.mocktime) - self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 3) + self.mocktime = int(time.time()) + node.setmocktime(self.mocktime) + + self.log.info(f"Add three stalling peers, sending {header_length} headers") + for id in range(4): + peers.append(node.add_outbound_p2p_connection(P2PStaller(stall_block), p2p_idx=id, connection_type="outbound-full-relay")) + peers[-1].block_store = self.block_dict + peers[-1].send_message(headers_message) + + self.wait_until(lambda: sum(len(peer['inflight']) for peer in node.getpeerinfo()) == 1) + self.all_sync_send_with_ping(peers) + assert_equal(sum(peer.stall_block_requested for peer in peers), 1) + + self.log.info("Check that after 30 seconds we request the block from a second peer") + self.mocktime += 31 + node.setmocktime(self.mocktime) + self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 2) + + self.log.info("Check that after another 30 seconds we request the block from a third peer") + self.mocktime += 31 + node.setmocktime(self.mocktime) + self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 3) + + self.log.info("Check that after another 30 seconds we aren't requesting it from a fourth peer yet") + self.mocktime += 31 + node.setmocktime(self.mocktime) + self.all_sync_send_with_ping(peers) + self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 3) + + self.log.info("Check that after another 20 minutes, first three stalling peers are disconnected") + # 10 minutes BLOCK_DOWNLOAD_TIMEOUT_BASE + 2*5 minutes BLOCK_DOWNLOAD_TIMEOUT_PER_PEER + self.mocktime += 20 * 60 + node.setmocktime(self.mocktime) + # all peers have been requested + self.wait_until(lambda: sum(peer.stall_block_requested for peer in peers) == 4) + + self.log.info("Check that after another 20 minutes, last stalling peer is disconnected") + # 10 minutes BLOCK_DOWNLOAD_TIMEOUT_BASE + 2*5 minutes BLOCK_DOWNLOAD_TIMEOUT_PER_PEER + self.mocktime += 20 * 60 + node.setmocktime(self.mocktime) + for peer in peers: + peer.wait_for_disconnect() - self.log.info("Check that after another 20 minutes, all stalling peers are disconnected") - # 10 minutes BLOCK_DOWNLOAD_TIMEOUT_BASE + 2*5 minutes BLOCK_DOWNLOAD_TIMEOUT_PER_PEER - self.mocktime += 20 * 60 - node.setmocktime(self.mocktime) - for peer in peers: - peer.wait_for_disconnect() def total_bytes_recv_for_blocks(self, node): total = 0