Skip to content

Commit fa0998f

Browse files
author
MarcoFalke
committed
test: Avoid intermittent error in assert_equal(pruneheight_new, 248)
1 parent beac62e commit fa0998f

File tree

1 file changed

+25
-24
lines changed

1 file changed

+25
-24
lines changed

test/functional/feature_index_prune.py

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#!/usr/bin/env python3
2-
# Copyright (c) 2020-2022 The Bitcoin Core developers
2+
# Copyright (c) 2020-present The Bitcoin Core developers
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test indices in conjunction with prune."""
6+
import concurrent.futures
67
import os
78
from test_framework.test_framework import BitcoinTestFramework
89
from test_framework.util import (
@@ -19,9 +20,25 @@ def set_test_params(self):
1920
["-fastprune", "-prune=1", "-blockfilterindex=1"],
2021
["-fastprune", "-prune=1", "-coinstatsindex=1"],
2122
["-fastprune", "-prune=1", "-blockfilterindex=1", "-coinstatsindex=1"],
22-
[]
23+
[],
2324
]
2425

26+
def setup_network(self):
27+
self.setup_nodes() # No P2P connection, so that linear_sync works
28+
29+
def linear_sync(self, node_from, *, height_from=None):
30+
# Linear sync over RPC, because P2P sync may not be linear
31+
to_height = node_from.getblockcount()
32+
if height_from is None:
33+
height_from = min([n.getblockcount() for n in self.nodes]) + 1
34+
with concurrent.futures.ThreadPoolExecutor(max_workers=self.num_nodes) as rpc_threads:
35+
for i in range(height_from, to_height + 1):
36+
b = node_from.getblock(blockhash=node_from.getblockhash(i), verbosity=0)
37+
list(rpc_threads.map(lambda n: n.submitblock(b), self.nodes))
38+
39+
def generate(self, node, num_blocks, sync_fun=None):
40+
return super().generate(node, num_blocks, sync_fun=sync_fun or (lambda: self.linear_sync(node)))
41+
2542
def sync_index(self, height):
2643
expected_filter = {
2744
'basic block filter index': {'synced': True, 'best_block_height': height},
@@ -36,22 +53,9 @@ def sync_index(self, height):
3653
expected = {**expected_filter, **expected_stats}
3754
self.wait_until(lambda: self.nodes[2].getindexinfo() == expected)
3855

39-
def reconnect_nodes(self):
40-
self.connect_nodes(0,1)
41-
self.connect_nodes(0,2)
42-
self.connect_nodes(0,3)
43-
44-
def mine_batches(self, blocks):
45-
n = blocks // 250
46-
for _ in range(n):
47-
self.generate(self.nodes[0], 250)
48-
self.generate(self.nodes[0], blocks % 250)
49-
self.sync_blocks()
50-
5156
def restart_without_indices(self):
5257
for i in range(3):
5358
self.restart_node(i, extra_args=["-fastprune", "-prune=1"])
54-
self.reconnect_nodes()
5559

5660
def run_test(self):
5761
filter_nodes = [self.nodes[0], self.nodes[2]]
@@ -65,7 +69,7 @@ def run_test(self):
6569
for node in stats_nodes:
6670
assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=tip)['muhash']
6771

68-
self.mine_batches(500)
72+
self.generate(self.nodes[0], 500)
6973
self.sync_index(height=700)
7074

7175
self.log.info("prune some blocks")
@@ -104,7 +108,7 @@ def run_test(self):
104108
msg = "Querying specific block heights requires coinstatsindex"
105109
assert_raises_rpc_error(-8, msg, node.gettxoutsetinfo, "muhash", height_hash)
106110

107-
self.mine_batches(749)
111+
self.generate(self.nodes[0], 749)
108112

109113
self.log.info("prune exactly up to the indices best blocks while the indices are disabled")
110114
for i in range(3):
@@ -118,7 +122,7 @@ def run_test(self):
118122

119123
self.log.info("prune further than the indices best blocks while the indices are disabled")
120124
self.restart_without_indices()
121-
self.mine_batches(1000)
125+
self.generate(self.nodes[0], 1000)
122126

123127
for i in range(3):
124128
pruneheight_3 = self.nodes[i].pruneblockchain(2000)
@@ -134,12 +138,10 @@ def run_test(self):
134138

135139
self.log.info("make sure the nodes start again with the indices and an additional -reindex arg")
136140
for i in range(3):
137-
restart_args = self.extra_args[i]+["-reindex"]
141+
restart_args = self.extra_args[i] + ["-reindex"]
138142
self.restart_node(i, extra_args=restart_args)
139-
# The nodes need to be reconnected to the non-pruning node upon restart, otherwise they will be stuck
140-
self.connect_nodes(i, 3)
141143

142-
self.sync_blocks(timeout=300)
144+
self.linear_sync(self.nodes[3])
143145
self.sync_index(height=2500)
144146

145147
for node in self.nodes[:2]:
@@ -150,8 +152,7 @@ def run_test(self):
150152
self.log.info("ensure that prune locks don't prevent indices from failing in a reorg scenario")
151153
with self.nodes[0].assert_debug_log(['basic block filter index prune lock moved back to 2480']):
152154
self.nodes[3].invalidateblock(self.nodes[0].getblockhash(2480))
153-
self.generate(self.nodes[3], 30)
154-
self.sync_blocks()
155+
self.generate(self.nodes[3], 30, sync_fun=lambda: self.linear_sync(self.nodes[3], height_from=2480))
155156

156157

157158
if __name__ == '__main__':

0 commit comments

Comments
 (0)