Changeset View
Changeset View
Standalone View
Standalone View
test/functional/pruning.py
Show All 32 Lines | |||||
class PruneTest(BitcoinTestFramework): | class PruneTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.setup_clean_chain = True | self.setup_clean_chain = True | ||||
self.num_nodes = 6 | self.num_nodes = 6 | ||||
# Create nodes 0 and 1 to mine. | # Create nodes 0 and 1 to mine. | ||||
# Create node 2 to test pruning. | # Create node 2 to test pruning. | ||||
self.full_node_default_args = ["-maxreceivebuffer=20000", "-blockmaxsize=999000", | self.full_node_default_args = ["-maxreceivebuffer=20000", "-blockmaxsize=999000", | ||||
"-checkblocks=5", "-noparkdeepreorg", | "-checkblocks=5", "-noparkdeepreorg", "-maxreorgdepth=-1", | ||||
"-limitdescendantcount=100", "-limitdescendantsize=5000", | "-limitdescendantcount=100", "-limitdescendantsize=5000", | ||||
"-limitancestorcount=100", "-limitancestorsize=5000"] | "-limitancestorcount=100", "-limitancestorsize=5000"] | ||||
# Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later) | # Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later) | ||||
# Create nodes 5 to test wallet in prune mode, but do not connect | # Create nodes 5 to test wallet in prune mode, but do not connect | ||||
self.extra_args = [self.full_node_default_args, | self.extra_args = [self.full_node_default_args, | ||||
self.full_node_default_args, | self.full_node_default_args, | ||||
["-maxreceivebuffer=20000", | ["-maxreceivebuffer=20000", "-prune=550", | ||||
"-prune=550", "-noparkdeepreorg"], | "-noparkdeepreorg", "-maxreorgdepth=-1"], | ||||
["-maxreceivebuffer=20000", | ["-maxreceivebuffer=20000", "-blockmaxsize=999000", | ||||
"-blockmaxsize=999000", "-noparkdeepreorg"], | "-noparkdeepreorg", "-maxreorgdepth=-1"], | ||||
["-maxreceivebuffer=20000", | ["-maxreceivebuffer=20000", "-blockmaxsize=999000", | ||||
"-blockmaxsize=999000", "-noparkdeepreorg"], | "-noparkdeepreorg", "-maxreorgdepth=-1"], | ||||
["-prune=550", "-noparkdeepreorg"]] | ["-prune=550"]] | ||||
def setup_network(self): | def setup_network(self): | ||||
self.setup_nodes() | self.setup_nodes() | ||||
self.prunedir = self.options.tmpdir + "/node2/regtest/blocks/" | self.prunedir = self.options.tmpdir + "/node2/regtest/blocks/" | ||||
connect_nodes(self.nodes[0], 1) | connect_nodes(self.nodes[0], 1) | ||||
connect_nodes(self.nodes[1], 2) | connect_nodes(self.nodes[1], 2) | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | def reorg_test(self): | ||||
# 0 and Node 2's tip. This will cause Node 2 to do a reorg requiring | # 0 and Node 2's tip. This will cause Node 2 to do a reorg requiring | ||||
# 288 blocks of undo data to the reorg_test chain. Reboot node 1 to | # 288 blocks of undo data to the reorg_test chain. Reboot node 1 to | ||||
# clear its mempool (hopefully make the invalidate faster). Lower the | # clear its mempool (hopefully make the invalidate faster). Lower the | ||||
# block max size so we don't keep mining all our big mempool | # block max size so we don't keep mining all our big mempool | ||||
# transactions (from disconnected blocks) | # transactions (from disconnected blocks) | ||||
self.stop_node(1) | self.stop_node(1) | ||||
self.start_node(1, extra_args=[ | self.start_node(1, extra_args=[ | ||||
"-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5", | "-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5", | ||||
"-disablesafemode", "-noparkdeepreorg"]) | "-disablesafemode", "-noparkdeepreorg", "-maxreorgdepth=-1"]) | ||||
height = self.nodes[1].getblockcount() | height = self.nodes[1].getblockcount() | ||||
self.log.info("Current block height: %d" % height) | self.log.info("Current block height: %d" % height) | ||||
invalidheight = height - 287 | invalidheight = height - 287 | ||||
badhash = self.nodes[1].getblockhash(invalidheight) | badhash = self.nodes[1].getblockhash(invalidheight) | ||||
self.log.info("Invalidating block %s at height %d" % | self.log.info("Invalidating block %s at height %d" % | ||||
(badhash, invalidheight)) | (badhash, invalidheight)) | ||||
Show All 10 Lines | def reorg_test(self): | ||||
assert(self.nodes[1].getblockcount() == invalidheight - 1) | assert(self.nodes[1].getblockcount() == invalidheight - 1) | ||||
self.log.info("New best height: %d" % self.nodes[1].getblockcount()) | self.log.info("New best height: %d" % self.nodes[1].getblockcount()) | ||||
# Reboot node1 to clear those giant tx's from mempool | # Reboot node1 to clear those giant tx's from mempool | ||||
self.stop_node(1) | self.stop_node(1) | ||||
self.start_node(1, extra_args=[ | self.start_node(1, extra_args=[ | ||||
"-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5", | "-maxreceivebuffer=20000", "-blockmaxsize=5000", "-checkblocks=5", | ||||
"-disablesafemode", "-noparkdeepreorg"]) | "-disablesafemode", "-noparkdeepreorg", "-maxreorgdepth=-1"]) | ||||
self.log.info("Generating new longer chain of 300 more blocks") | self.log.info("Generating new longer chain of 300 more blocks") | ||||
self.nodes[1].generate(300) | self.nodes[1].generate(300) | ||||
self.log.info("Reconnect nodes") | self.log.info("Reconnect nodes") | ||||
connect_nodes(self.nodes[0], 1) | connect_nodes(self.nodes[0], 1) | ||||
connect_nodes(self.nodes[2], 1) | connect_nodes(self.nodes[2], 1) | ||||
sync_blocks(self.nodes[0:3], timeout=120) | sync_blocks(self.nodes[0:3], timeout=120) | ||||
▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | def manual_test(self, node_number, use_timestamp): | ||||
self.start_node(node_number, extra_args=["-prune=550"]) | self.start_node(node_number, extra_args=["-prune=550"]) | ||||
self.log.info("Success") | self.log.info("Success") | ||||
def wallet_test(self): | def wallet_test(self): | ||||
# check that the pruning node's wallet is still in good shape | # check that the pruning node's wallet is still in good shape | ||||
self.log.info("Stop and start pruning node to trigger wallet rescan") | self.log.info("Stop and start pruning node to trigger wallet rescan") | ||||
self.stop_node(2) | self.stop_node(2) | ||||
self.start_node(2, extra_args=["-prune=550", "-noparkdeepreorg"]) | self.start_node( | ||||
2, extra_args=["-prune=550", "-noparkdeepreorg", "-maxreorgdepth=-1"]) | |||||
self.log.info("Success") | self.log.info("Success") | ||||
# check that wallet loads loads successfully when restarting a pruned node after IBD. | # check that wallet loads loads successfully when restarting a pruned node after IBD. | ||||
# this was reported to fail in #7494. | # this was reported to fail in #7494. | ||||
self.log.info("Syncing node 5 to test wallet") | self.log.info("Syncing node 5 to test wallet") | ||||
connect_nodes(self.nodes[0], 5) | connect_nodes(self.nodes[0], 5) | ||||
nds = [self.nodes[0], self.nodes[5]] | nds = [self.nodes[0], self.nodes[5]] | ||||
sync_blocks(nds, wait=5, timeout=300) | sync_blocks(nds, wait=5, timeout=300) | ||||
self.stop_node(5) # stop and start to trigger rescan | self.stop_node(5) # stop and start to trigger rescan | ||||
self.start_node(5, extra_args=["-prune=550", "-noparkdeepreorg"]) | self.start_node( | ||||
5, extra_args=["-prune=550", "-noparkdeepreorg", "-maxreorgdepth=-1"]) | |||||
self.log.info("Success") | self.log.info("Success") | ||||
def run_test(self): | def run_test(self): | ||||
self.log.info( | self.log.info( | ||||
"Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)") | "Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)") | ||||
self.log.info("Mining a big blockchain of 995 blocks") | self.log.info("Mining a big blockchain of 995 blocks") | ||||
# Determine default relay fee | # Determine default relay fee | ||||
▲ Show 20 Lines • Show All 120 Lines • Show Last 20 Lines |