Repository: dogecoin/dogecoin
File: qa/rpc-tests/pruning.py (Python)

Code before:

        # Create nodes 5 to test wallet in prune mode, but do not connect
        self.nodes.append(start_node(5, self.options.tmpdir, ["-debug=0", "-prune=2200"]))

        # Determine default relay fee
        self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]

        connect_nodes(self.nodes[0], 1)
        connect_nodes(self.nodes[1], 2)
        connect_nodes(self.nodes[2], 0)
        connect_nodes(self.nodes[3], 4)
        sync_blocks(self.nodes[0:5])

    def create_big_chain(self):
        # Start by creating some coinbases we can spend later
        self.nodes[1].generate(200)
        sync_blocks(self.nodes[0:2])
        self.nodes[0].generate(150)
        # # Then mine enough full blocks to cre
        # # ate more than 2200MiB of data
        mine_large_blocks(self.nodes[0], 2395, self.prunedir)

        sync_blocks(self.nodes[0:2])

        mine_large_blocks(self.nodes[3], 995, self.prunedir)
        mine_large_blocks(self.nodes[4], 995, self.prunedir)

    def test_height_min(self):
        if not os.path.isfile(self.prunedir+"blk00000.dat"):
            raise AssertionError("blk00000.dat is missing, pruning too early")
        print("Success")
        print("Though we're already using more than 2200MiB, current usage:", calc_usage(self.prunedir))
        print("Mining 20 more blocks should cause the first block file to be pruned")
        # Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
        mine_large_blocks(self.nodes[0], 20, self.prunedir)

        waitstart = time.time()
        while os.path.isfile(self.prunedir+"blk00000.dat"):
            time.sleep(0.1)
            if time.time() - waitstart > 30:
                raise AssertionError("blk00000.dat not pruned when it should be")

        print("Success")
        usage = calc_usage(self.prunedir)
        print("Usage should be below target:", usage)
        if (usage > 2200):
            raise AssertionError("Pruning target not being met")

    def create_chain_with_staleblocks(self):
        # Create stale blocks in manageable sized chunks
        print("Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds")

Review comment (suggestion):
I think this is what you meant by "Separated the manual testing from the main test"? So what we're saying is that it's faster / more reliable to mine 995 blocks than to sync 995 blocks? Even with the change to the download window? Doesn't have to be blocking for this PR, but I think this indicates further potential problems on the network stack.

Code after:
        self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]

        connect_nodes(self.nodes[0], 1)
        connect_nodes(self.nodes[1], 2)
        connect_nodes(self.nodes[2], 0)
        connect_nodes(self.nodes[3], 4)
        sync_blocks(self.nodes[0:5])

    def create_big_chain(self):
        # Start by creating some coinbases we can spend later
        self.nodes[1].generate(200)
        sync_blocks(self.nodes[0:2])
        self.nodes[0].generate(150)
        # Then mine enough full blocks to create more than 2200MiB of data
        mine_large_blocks(self.nodes[0], 2395)
        sync_blocks(self.nodes[0:2])
        # Note: Separated the manual testing from the main test
        # This can and should be improved in the future
        mine_large_blocks(self.nodes[3], 995)
        mine_large_blocks(self.nodes[4], 995)

    def test_height_min(self):
        if not os.path.isfile(self.prunedir+"blk00000.dat"):
            raise AssertionError("blk00000.dat is missing, pruning too early")
        print("Success")
        print("Though we're already using more than 2200MiB, current usage:", calc_usage(self.prunedir))
        print("Mining 20 more blocks should cause the first block file to be pruned")
        # Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
        mine_large_blocks(self.nodes[0], 20)

        waitstart = time.time()
        while os.path.isfile(self.prunedir+"blk00000.dat"):
            time.sleep(0.1)
            if time.time() - waitstart > 30:
                raise AssertionError("blk00000.dat not pruned when it should be")

        print("Success")
        usage = calc_usage(self.prunedir)
        print("Usage should be below target:", usage)
        if (usage > 2200):
            raise AssertionError("Pruning target not being met")

    def create_chain_with_staleblocks(self):
        # Create stale blocks in manageable sized chunks
        print("Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds")
        for j in range(12):
            # Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain
            # Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects
            # Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine
            self.stop_node(0)
            self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000", "-checkblocks=6"], timewait=1200)