Changeset View
Changeset View
Standalone View
Standalone View
test/functional/pruning.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2014-2016 The Bitcoin Core developers | # Copyright (c) 2014-2016 The Bitcoin Core developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
# | # | ||||
# Test pruning code | # Test pruning code | ||||
# ******** | # ******** | ||||
# WARNING: | # WARNING: | ||||
# This test uses 4GB of disk space. | # This test uses 4GB of disk space. | ||||
# This test takes 30 mins or more (up to 2 hours) | # This test takes 30 mins or more (up to 2 hours) | ||||
# ******** | # ******** | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import * | from test_framework.util import * | ||||
from test_framework.blocktools import mine_big_block | |||||
import time | import time | ||||
import os | import os | ||||
MIN_BLOCKS_TO_KEEP = 288 | MIN_BLOCKS_TO_KEEP = 288 | ||||
# Rescans start at the earliest block up to 2 hours before a key timestamp, so | # Rescans start at the earliest block up to 2 hours before a key timestamp, so | ||||
# the manual prune RPC avoids pruning blocks in the same window to be | # the manual prune RPC avoids pruning blocks in the same window to be | ||||
# compatible with pruning based on key creation time. | # compatible with pruning based on key creation time. | ||||
Show All 40 Lines | class PruneTest(BitcoinTestFramework): | ||||
def create_big_chain(self): | def create_big_chain(self): | ||||
# Start by creating some coinbases we can spend later | # Start by creating some coinbases we can spend later | ||||
self.nodes[1].generate(200) | self.nodes[1].generate(200) | ||||
sync_blocks(self.nodes[0:2]) | sync_blocks(self.nodes[0:2]) | ||||
self.nodes[0].generate(150) | self.nodes[0].generate(150) | ||||
# Then mine enough full blocks to create more than 550MiB of data | # Then mine enough full blocks to create more than 550MiB of data | ||||
for i in range(645): | for i in range(645): | ||||
mine_large_block(self.nodes[0], self.utxo_cache_0) | mine_big_block(self.nodes[0], self.utxo_cache_0) | ||||
sync_blocks(self.nodes[0:5]) | sync_blocks(self.nodes[0:5]) | ||||
def test_height_min(self): | def test_height_min(self): | ||||
if not os.path.isfile(self.prunedir + "blk00000.dat"): | if not os.path.isfile(self.prunedir + "blk00000.dat"): | ||||
raise AssertionError("blk00000.dat is missing, pruning too early") | raise AssertionError("blk00000.dat is missing, pruning too early") | ||||
self.log.info("Success") | self.log.info("Success") | ||||
self.log.info("Though we're already using more than 550MiB, current usage: %d" % | self.log.info("Though we're already using more than 550MiB, current usage: %d" % | ||||
calc_usage(self.prunedir)) | calc_usage(self.prunedir)) | ||||
self.log.info( | self.log.info( | ||||
"Mining 25 more blocks should cause the first block file to be pruned") | "Mining 25 more blocks should cause the first block file to be pruned") | ||||
# Pruning doesn't run until we're allocating another chunk, 20 full | # Pruning doesn't run until we're allocating another chunk, 20 full | ||||
# blocks past the height cutoff will ensure this | # blocks past the height cutoff will ensure this | ||||
for i in range(25): | for i in range(25): | ||||
mine_large_block(self.nodes[0], self.utxo_cache_0) | mine_big_block(self.nodes[0], self.utxo_cache_0) | ||||
waitstart = time.time() | waitstart = time.time() | ||||
while os.path.isfile(self.prunedir + "blk00000.dat"): | while os.path.isfile(self.prunedir + "blk00000.dat"): | ||||
time.sleep(0.1) | time.sleep(0.1) | ||||
if time.time() - waitstart > 30: | if time.time() - waitstart > 30: | ||||
raise AssertionError( | raise AssertionError( | ||||
"blk00000.dat not pruned when it should be") | "blk00000.dat not pruned when it should be") | ||||
Show All 13 Lines | def create_chain_with_staleblocks(self): | ||||
# Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects | # 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 | # Stopping node 0 also clears its mempool, so it doesn't have | ||||
# node1's transactions to accidentally mine | # node1's transactions to accidentally mine | ||||
self.stop_node(0) | self.stop_node(0) | ||||
self.start_node(0, extra_args=self.full_node_default_args) | self.start_node(0, extra_args=self.full_node_default_args) | ||||
# Mine 24 blocks in node 1 | # Mine 24 blocks in node 1 | ||||
for i in range(24): | for i in range(24): | ||||
if j == 0: | if j == 0: | ||||
mine_large_block(self.nodes[1], self.utxo_cache_1) | mine_big_block(self.nodes[1], self.utxo_cache_1) | ||||
else: | else: | ||||
# Add node1's wallet transactions back to the mempool, to | # Add node1's wallet transactions back to the mempool, to | ||||
# avoid the mined blocks from being too small. | # avoid the mined blocks from being too small. | ||||
self.nodes[1].resendwallettransactions() | self.nodes[1].resendwallettransactions() | ||||
# tx's already in mempool from previous disconnects | # tx's already in mempool from previous disconnects | ||||
self.nodes[1].generate(1) | self.nodes[1].generate(1) | ||||
# Reorg back with 25 block chain from node 0 | # Reorg back with 25 block chain from node 0 | ||||
for i in range(25): | for i in range(25): | ||||
mine_large_block(self.nodes[0], self.utxo_cache_0) | mine_big_block(self.nodes[0], self.utxo_cache_0) | ||||
# Create connections in the order so both nodes can see the reorg | # Create connections in the order so both nodes can see the reorg | ||||
# at the same time | # at the same time | ||||
connect_nodes(self.nodes[1], 0) | connect_nodes(self.nodes[1], 0) | ||||
connect_nodes(self.nodes[2], 0) | connect_nodes(self.nodes[2], 0) | ||||
sync_blocks(self.nodes[0:3]) | sync_blocks(self.nodes[0:3]) | ||||
self.log.info("Usage can be over target because of high stale rate: %d" % | self.log.info("Usage can be over target because of high stale rate: %d" % | ||||
▲ Show 20 Lines • Show All 368 Lines • Show Last 20 Lines |