mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 11:27:28 -03:00
Merge bitcoin/bitcoin#31468: test: Avoid intermittent error in assert_equal(pruneheight_new, 248)
fa0998f0a0
test: Avoid intermittent error in assert_equal(pruneheight_new, 248) (MarcoFalke) Pull request description: Fixes https://github.com/bitcoin/bitcoin/issues/31446 The test uses the P2P network to sync blocks, which has no inherent guarantee that the blocks are sent and received in the right order, assuming the headers are received first. This can mean that the first block file is flushed with block at height 249 and block at height 248 is added to the second file. In the log it looks like: `Leaving block file 0: CBlockFileInfo(blocks=249, size=65319, heights=0...249, time=2011-02-02...2024-12-03) (onto 1) (height 248)`. The test assumes that the height of the last pruned block in the first file is 248, expecting it to look like: `Leaving block file 0: CBlockFileInfo(blocks=249, size=65319, heights=0...248, time=2011-02-02...2024-12-09) (onto 1) (height 249) `. Fix the issue by using a linear dumb sync. ACKs for top commit: achow101: ACKfa0998f0a0
mzumsande: Code Review ACKfa0998f0a0
i-am-yuvi: Code Review ACKfa0998f0a0
fjahr: Code review ACKfa0998f0a0
Tree-SHA512: 59cb4317be6cf9012c9bf7a3e9f5ba96b8b114b30bd2ac42af4fe742cd26a634d685b075f04a84bd782b2a43a342d75bb20a042bd82ad2831dbf844d39517ca2
This commit is contained in:
commit
ba0cb7d5a5
1 changed files with 25 additions and 24 deletions
|
@ -1,8 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2020-2022 The Bitcoin Core developers
|
||||
# Copyright (c) 2020-present The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test indices in conjunction with prune."""
|
||||
import concurrent.futures
|
||||
import os
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
|
@ -19,9 +20,25 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
|
|||
["-fastprune", "-prune=1", "-blockfilterindex=1"],
|
||||
["-fastprune", "-prune=1", "-coinstatsindex=1"],
|
||||
["-fastprune", "-prune=1", "-blockfilterindex=1", "-coinstatsindex=1"],
|
||||
[]
|
||||
[],
|
||||
]
|
||||
|
||||
def setup_network(self):
|
||||
self.setup_nodes() # No P2P connection, so that linear_sync works
|
||||
|
||||
def linear_sync(self, node_from, *, height_from=None):
|
||||
# Linear sync over RPC, because P2P sync may not be linear
|
||||
to_height = node_from.getblockcount()
|
||||
if height_from is None:
|
||||
height_from = min([n.getblockcount() for n in self.nodes]) + 1
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=self.num_nodes) as rpc_threads:
|
||||
for i in range(height_from, to_height + 1):
|
||||
b = node_from.getblock(blockhash=node_from.getblockhash(i), verbosity=0)
|
||||
list(rpc_threads.map(lambda n: n.submitblock(b), self.nodes))
|
||||
|
||||
def generate(self, node, num_blocks, sync_fun=None):
|
||||
return super().generate(node, num_blocks, sync_fun=sync_fun or (lambda: self.linear_sync(node)))
|
||||
|
||||
def sync_index(self, height):
|
||||
expected_filter = {
|
||||
'basic block filter index': {'synced': True, 'best_block_height': height},
|
||||
|
@ -36,22 +53,9 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
|
|||
expected = {**expected_filter, **expected_stats}
|
||||
self.wait_until(lambda: self.nodes[2].getindexinfo() == expected)
|
||||
|
||||
def reconnect_nodes(self):
|
||||
self.connect_nodes(0,1)
|
||||
self.connect_nodes(0,2)
|
||||
self.connect_nodes(0,3)
|
||||
|
||||
def mine_batches(self, blocks):
|
||||
n = blocks // 250
|
||||
for _ in range(n):
|
||||
self.generate(self.nodes[0], 250)
|
||||
self.generate(self.nodes[0], blocks % 250)
|
||||
self.sync_blocks()
|
||||
|
||||
def restart_without_indices(self):
|
||||
for i in range(3):
|
||||
self.restart_node(i, extra_args=["-fastprune", "-prune=1"])
|
||||
self.reconnect_nodes()
|
||||
|
||||
def run_test(self):
|
||||
filter_nodes = [self.nodes[0], self.nodes[2]]
|
||||
|
@ -65,7 +69,7 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
|
|||
for node in stats_nodes:
|
||||
assert node.gettxoutsetinfo(hash_type="muhash", hash_or_height=tip)['muhash']
|
||||
|
||||
self.mine_batches(500)
|
||||
self.generate(self.nodes[0], 500)
|
||||
self.sync_index(height=700)
|
||||
|
||||
self.log.info("prune some blocks")
|
||||
|
@ -104,7 +108,7 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
|
|||
msg = "Querying specific block heights requires coinstatsindex"
|
||||
assert_raises_rpc_error(-8, msg, node.gettxoutsetinfo, "muhash", height_hash)
|
||||
|
||||
self.mine_batches(749)
|
||||
self.generate(self.nodes[0], 749)
|
||||
|
||||
self.log.info("prune exactly up to the indices best blocks while the indices are disabled")
|
||||
for i in range(3):
|
||||
|
@ -118,7 +122,7 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
|
|||
|
||||
self.log.info("prune further than the indices best blocks while the indices are disabled")
|
||||
self.restart_without_indices()
|
||||
self.mine_batches(1000)
|
||||
self.generate(self.nodes[0], 1000)
|
||||
|
||||
for i in range(3):
|
||||
pruneheight_3 = self.nodes[i].pruneblockchain(2000)
|
||||
|
@ -134,12 +138,10 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
|
|||
|
||||
self.log.info("make sure the nodes start again with the indices and an additional -reindex arg")
|
||||
for i in range(3):
|
||||
restart_args = self.extra_args[i]+["-reindex"]
|
||||
restart_args = self.extra_args[i] + ["-reindex"]
|
||||
self.restart_node(i, extra_args=restart_args)
|
||||
# The nodes need to be reconnected to the non-pruning node upon restart, otherwise they will be stuck
|
||||
self.connect_nodes(i, 3)
|
||||
|
||||
self.sync_blocks(timeout=300)
|
||||
self.linear_sync(self.nodes[3])
|
||||
self.sync_index(height=2500)
|
||||
|
||||
for node in self.nodes[:2]:
|
||||
|
@ -150,8 +152,7 @@ class FeatureIndexPruneTest(BitcoinTestFramework):
|
|||
self.log.info("ensure that prune locks don't prevent indices from failing in a reorg scenario")
|
||||
with self.nodes[0].assert_debug_log(['basic block filter index prune lock moved back to 2480']):
|
||||
self.nodes[3].invalidateblock(self.nodes[0].getblockhash(2480))
|
||||
self.generate(self.nodes[3], 30)
|
||||
self.sync_blocks()
|
||||
self.generate(self.nodes[3], 30, sync_fun=lambda: self.linear_sync(self.nodes[3], height_from=2480))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in a new issue