Skip to content

Commit 010aa53

Browse files
committed
test/reindex: only connect minchainwork chain
1 parent 91e6254 commit 010aa53

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

test/functional/feature_reindex.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,32 @@
88
- Stop the node and restart it with -reindex. Verify that the node has reindexed up to block 3.
99
- Stop the node and restart it with -reindex-chainstate. Verify that the node has reindexed up to block 3.
1010
- Verify that out-of-order blocks are correctly processed, see LoadExternalBlockFile()
11+
- Verify that -reindex does not attempt to connect blocks when best_header chainwork is below MinimumChainWork
1112
"""
1213

14+
from test_framework.blocktools import (
15+
create_block,
16+
create_coinbase,
17+
)
18+
from test_framework.messages import (
19+
CBlockHeader,
20+
msg_block,
21+
msg_headers,
22+
)
1323
from test_framework.test_framework import BitcoinTestFramework
1424
from test_framework.messages import MAGIC_BYTES
25+
from test_framework.p2p import P2PInterface
1526
from test_framework.util import (
1627
assert_equal,
1728
util_xor,
1829
)
1930

31+
class BaseNode(P2PInterface):
32+
def send_header_for_blocks(self, new_blocks):
33+
headers_message = msg_headers()
34+
headers_message.headers = [CBlockHeader(b) for b in new_blocks]
35+
self.send_without_ping(headers_message)
36+
2037

2138
class ReindexTest(BitcoinTestFramework):
2239
def set_test_params(self):
@@ -97,6 +114,45 @@ def continue_reindex_after_shutdown(self):
97114
node.wait_for_rpc_connection(wait_for_import=False)
98115
node.stop_node()
99116

117+
def only_connect_minchainwork_chain(self):
118+
self.start_node(0)
119+
node = self.nodes[0]
120+
self.generatetoaddress(self.nodes[0], 3, self.nodes[0].get_deterministic_priv_key().address)
121+
blockcount = node.getblockcount()
122+
best_header_target = int(node.getblock(node.getbestblockhash())['target'], 16)
123+
chainwork = (100 + blockcount) * (2**256) // (best_header_target + 1)
124+
chainwork = format(chainwork, '064x')
125+
126+
tip = int(node.getbestblockhash(), 16)
127+
block_time = node.getblock(node.getbestblockhash())['time'] + 1
128+
height = node.getblock(node.getbestblockhash())['height'] + 1
129+
130+
blocks = []
131+
for _ in range(100):
132+
block = create_block(tip, create_coinbase(height), block_time)
133+
block.solve()
134+
blocks.append(block)
135+
tip = block.hash_int
136+
block_time += 1
137+
height += 1
138+
139+
self.stop_node(0)
140+
extra_args = ["-reindex", "-minimumchainwork=" + chainwork]
141+
with node.assert_debug_log(expected_msgs=["Waiting for header sync to finish before activating chain..."]):
142+
# No blocks are connected because chainwork of best_header is too low
143+
self.start_node(0, extra_args)
144+
145+
p2p = node.add_p2p_connection(BaseNode())
146+
p2p.send_header_for_blocks(blocks)
147+
148+
# Reindexed blocks are connected after headers sync
149+
self.wait_until(lambda: node.getblockcount() == blockcount)
150+
151+
# Send headers again to ensure that the block is requested
152+
p2p.send_header_for_blocks(blocks)
153+
p2p.send_without_ping(msg_block(blocks[0]))
154+
self.wait_until(lambda: node.getblockcount() == blockcount + 1)
155+
100156
def run_test(self):
101157
self.reindex(False)
102158
self.reindex(True)
@@ -105,6 +161,7 @@ def run_test(self):
105161

106162
self.out_of_order()
107163
self.continue_reindex_after_shutdown()
164+
self.only_connect_minchainwork_chain()
108165

109166

110167
if __name__ == '__main__':

0 commit comments

Comments
 (0)