mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 06:28:31 +01:00
validation: indexing changes for assumeutxo
When using an assumedvalid chainstate, only process validationinterface callbacks from the background chainstate within indexes. This ensures that all indexes are built in-order. Later, we can possibly designate indexes which can be built out of order and continue their operation during snapshot use. Once the background sync has completed, restart the indexes so that they continue to index the now-validated snapshot chainstate.
This commit is contained in:
committed by
James O'Beirne
parent
1fffdd76a1
commit
373cf91531
30
src/init.cpp
30
src/init.cpp
@@ -1478,6 +1478,25 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||
node.chainman = std::make_unique<ChainstateManager>(node.kernel->interrupt, chainman_opts, blockman_opts);
|
||||
ChainstateManager& chainman = *node.chainman;
|
||||
|
||||
// This is defined and set here instead of inline in validation.h to avoid a hard
|
||||
// dependency between validation and index/base, since the latter is not in
|
||||
// libbitcoinkernel.
|
||||
chainman.restart_indexes = [&node]() {
|
||||
LogPrintf("[snapshot] restarting indexes\n");
|
||||
|
||||
// Drain the validation interface queue to ensure that the old indexes
|
||||
// don't have any pending work.
|
||||
SyncWithValidationInterfaceQueue();
|
||||
|
||||
for (auto* index : node.indexes) {
|
||||
index->Interrupt();
|
||||
index->Stop();
|
||||
if (!(index->Init() && index->StartBackgroundSync())) {
|
||||
LogPrintf("[snapshot] WARNING failed to restart index %s on snapshot chain\n", index->GetName());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
node::ChainstateLoadOptions options;
|
||||
options.mempool = Assert(node.mempool.get());
|
||||
options.reindex = node::fReindex;
|
||||
@@ -1906,18 +1925,19 @@ bool StartIndexBackgroundSync(NodeContext& node)
|
||||
// indexes_start_block='nullptr' means "start from height 0".
|
||||
std::optional<const CBlockIndex*> indexes_start_block;
|
||||
std::string older_index_name;
|
||||
|
||||
ChainstateManager& chainman = *Assert(node.chainman);
|
||||
const Chainstate& chainstate = WITH_LOCK(::cs_main, return chainman.GetChainstateForIndexing());
|
||||
const CChain& index_chain = chainstate.m_chain;
|
||||
|
||||
for (auto index : node.indexes) {
|
||||
const IndexSummary& summary = index->GetSummary();
|
||||
if (summary.synced) continue;
|
||||
|
||||
// Get the last common block between the index best block and the active chain
|
||||
LOCK(::cs_main);
|
||||
const CChain& active_chain = chainman.ActiveChain();
|
||||
const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(summary.best_block_hash);
|
||||
if (!active_chain.Contains(pindex)) {
|
||||
pindex = active_chain.FindFork(pindex);
|
||||
if (!index_chain.Contains(pindex)) {
|
||||
pindex = index_chain.FindFork(pindex);
|
||||
}
|
||||
|
||||
if (!indexes_start_block || !pindex || pindex->nHeight < indexes_start_block.value()->nHeight) {
|
||||
@@ -1932,7 +1952,7 @@ bool StartIndexBackgroundSync(NodeContext& node)
|
||||
LOCK(::cs_main);
|
||||
const CBlockIndex* start_block = *indexes_start_block;
|
||||
if (!start_block) start_block = chainman.ActiveChain().Genesis();
|
||||
if (!chainman.m_blockman.CheckBlockDataAvailability(*chainman.ActiveChain().Tip(), *Assert(start_block))) {
|
||||
if (!chainman.m_blockman.CheckBlockDataAvailability(*index_chain.Tip(), *Assert(start_block))) {
|
||||
return InitError(strprintf(Untranslated("%s best block of the index goes beyond pruned data. Please disable the index or reindex (which will download the whole blockchain again)"), older_index_name));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user