mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-22 23:07:59 +01:00
index: Use first block from locator instead of looking for fork point
The index sync code has logic to go back the chain to the forking point, while also updating index-specific state, which is necessary to prevent possible corruption of the coinstatsindex. Also add a test for this (a reorg happens while the index is deactivated) that would not pass before this change.
This commit is contained in:
parent
594f05db19
commit
60bec3c82d
2 changed files with 31 additions and 1 deletions
|
@ -92,7 +92,13 @@ bool BaseIndex::Init()
|
||||||
if (locator.IsNull()) {
|
if (locator.IsNull()) {
|
||||||
SetBestBlockIndex(nullptr);
|
SetBestBlockIndex(nullptr);
|
||||||
} else {
|
} else {
|
||||||
SetBestBlockIndex(m_chainstate->FindForkInGlobalIndex(locator));
|
// Setting the best block to the locator's top block. If it is not part of the
|
||||||
|
// best chain, we will rewind to the fork point during index sync
|
||||||
|
const CBlockIndex* locator_index{m_chainstate->m_blockman.LookupBlockIndex(locator.vHave.at(0))};
|
||||||
|
if (!locator_index) {
|
||||||
|
return InitError(strprintf(Untranslated("%s: best block of the index not found. Please rebuild the index."), GetName()));
|
||||||
|
}
|
||||||
|
SetBestBlockIndex(locator_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this will latch to true immediately if the user starts up with an empty
|
// Note: this will latch to true immediately if the user starts up with an empty
|
||||||
|
|
|
@ -52,6 +52,7 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
||||||
self._test_use_index_option()
|
self._test_use_index_option()
|
||||||
self._test_reorg_index()
|
self._test_reorg_index()
|
||||||
self._test_index_rejects_hash_serialized()
|
self._test_index_rejects_hash_serialized()
|
||||||
|
self._test_init_index_after_reorg()
|
||||||
|
|
||||||
def block_sanity_check(self, block_info):
|
def block_sanity_check(self, block_info):
|
||||||
block_subsidy = 50
|
block_subsidy = 50
|
||||||
|
@ -60,6 +61,9 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
||||||
block_info['new_outputs_ex_coinbase'] + block_info['coinbase'] + block_info['unspendable']
|
block_info['new_outputs_ex_coinbase'] + block_info['coinbase'] + block_info['unspendable']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def sync_index_node(self):
|
||||||
|
self.wait_until(lambda: self.nodes[1].getindexinfo()['coinstatsindex']['synced'] is True)
|
||||||
|
|
||||||
def _test_coin_stats_index(self):
|
def _test_coin_stats_index(self):
|
||||||
node = self.nodes[0]
|
node = self.nodes[0]
|
||||||
index_node = self.nodes[1]
|
index_node = self.nodes[1]
|
||||||
|
@ -296,6 +300,26 @@ class CoinStatsIndexTest(BitcoinTestFramework):
|
||||||
for use_index in {True, False, None}:
|
for use_index in {True, False, None}:
|
||||||
assert_raises_rpc_error(-8, msg, self.nodes[1].gettxoutsetinfo, hash_type='hash_serialized_2', hash_or_height=111, use_index=use_index)
|
assert_raises_rpc_error(-8, msg, self.nodes[1].gettxoutsetinfo, hash_type='hash_serialized_2', hash_or_height=111, use_index=use_index)
|
||||||
|
|
||||||
|
def _test_init_index_after_reorg(self):
|
||||||
|
self.log.info("Test a reorg while the index is deactivated")
|
||||||
|
index_node = self.nodes[1]
|
||||||
|
block = self.nodes[0].getbestblockhash()
|
||||||
|
self.generate(index_node, 2, sync_fun=self.no_op)
|
||||||
|
self.sync_index_node()
|
||||||
|
|
||||||
|
# Restart without index
|
||||||
|
self.restart_node(1, extra_args=[])
|
||||||
|
self.connect_nodes(0, 1)
|
||||||
|
index_node.invalidateblock(block)
|
||||||
|
self.generatetoaddress(index_node, 5, getnewdestination()[2])
|
||||||
|
res = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=None, use_index=False)
|
||||||
|
|
||||||
|
# Restart with index that still has its best block on the old chain
|
||||||
|
self.restart_node(1, extra_args=self.extra_args[1])
|
||||||
|
self.sync_index_node()
|
||||||
|
res1 = index_node.gettxoutsetinfo(hash_type='muhash', hash_or_height=None, use_index=True)
|
||||||
|
assert_equal(res["muhash"], res1["muhash"])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
CoinStatsIndexTest().main()
|
CoinStatsIndexTest().main()
|
||||||
|
|
Loading…
Add table
Reference in a new issue