def send_get_headers(self, locator, hashstop):
     msg = msg_getheaders()
     msg.locator.vHave = locator
     msg.hashstop = hashstop
     self.send_message(msg)
Example #2
0
 def send_header_request(self, block_hash, node):
     msg = msg_getheaders()
     msg.hashstop = block_hash
     node.send_message(msg)
Example #3
0
    def run_test(self):
        # Start building a chain on node0.  node2 shouldn't be able to sync until node1's
        # minchainwork is exceeded
        starting_chain_work = REGTEST_WORK_PER_BLOCK  # Genesis block's work
        self.log.info(
            f"Testing relay across node 1 (minChainWork = {self.node_min_work[1]})"
        )

        starting_blockcount = self.nodes[2].getblockcount()

        num_blocks_to_generate = int(
            (self.node_min_work[1] - starting_chain_work) /
            REGTEST_WORK_PER_BLOCK)
        self.log.info(f"Generating {num_blocks_to_generate} blocks on node0")
        hashes = self.generate(self.nodes[0],
                               num_blocks_to_generate,
                               sync_fun=self.no_op)

        self.log.info(
            f"Node0 current chain work: {self.nodes[0].getblockheader(hashes[-1])['chainwork']}"
        )

        # Sleep a few seconds and verify that node2 didn't get any new blocks
        # or headers.  We sleep, rather than sync_blocks(node0, node1) because
        # it's reasonable either way for node1 to get the blocks, or not get
        # them (since they're below node1's minchainwork).
        time.sleep(3)

        self.log.info("Verifying node 2 has no more blocks than before")
        self.log.info(
            f"Blockcounts: {[n.getblockcount() for n in self.nodes]}")
        # Node2 shouldn't have any new headers yet, because node1 should not
        # have relayed anything.
        assert_equal(len(self.nodes[2].getchaintips()), 1)
        assert_equal(self.nodes[2].getchaintips()[0]['height'], 0)

        assert self.nodes[1].getbestblockhash(
        ) != self.nodes[0].getbestblockhash()
        assert_equal(self.nodes[2].getblockcount(), starting_blockcount)

        self.log.info("Check that getheaders requests to node2 are ignored")
        peer = self.nodes[2].add_p2p_connection(P2PInterface())
        msg = msg_getheaders()
        msg.locator.vHave = [int(self.nodes[2].getbestblockhash(), 16)]
        msg.hashstop = 0
        peer.send_and_ping(msg)
        time.sleep(5)
        assert ("headers" not in peer.last_message
                or len(peer.last_message["headers"].headers) == 0)

        self.log.info("Generating one more block")
        self.generate(self.nodes[0], 1)

        self.log.info("Verifying nodes are all synced")

        # Because nodes in regtest are all manual connections (eg using
        # addnode), node1 should not have disconnected node0. If not for that,
        # we'd expect node1 to have disconnected node0 for serving an
        # insufficient work chain, in which case we'd need to reconnect them to
        # continue the test.

        self.sync_all()
        self.log.info(
            f"Blockcounts: {[n.getblockcount() for n in self.nodes]}")

        self.log.info("Test that getheaders requests to node2 are not ignored")
        peer.send_and_ping(msg)
        assert "headers" in peer.last_message

        # Verify that node2 is in fact still in IBD (otherwise this test may
        # not be exercising the logic we want!)
        assert_equal(self.nodes[2].getblockchaininfo()['initialblockdownload'],
                     True)

        self.log.info("Test -minimumchainwork with a non-hex value")
        self.stop_node(0)
        self.nodes[0].assert_start_raises_init_error(
            ["-minimumchainwork=test"],
            expected_msg=
            'Error: Invalid non-hex (test) minimum chain work value specified',
        )