aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
authorfurszy <matiasfurszyfer@protonmail.com>2023-05-16 18:35:35 -0300
committerfurszy <matiasfurszyfer@protonmail.com>2023-07-10 10:50:50 -0300
commitca91c244ef1ba7eac6643d66a5fc56d3a2a8b550 (patch)
tree425fd02022aac33a86087392dd201b5d9f1836cc /src/init.cpp
parentfcbdaeef4d5a63e3e5b479c6fcad730eb86fb923 (diff)
downloadbitcoin-ca91c244ef1ba7eac6643d66a5fc56d3a2a8b550.tar.xz
index: verify blocks data existence only once
At present, during init, we traverse the chain (once per index) to confirm that all necessary blocks to sync each index up to the current tip are present. To make the process more efficient, we can fetch the oldest block from the indexers and perform the chain data existence check from that point only once. This also moves the pruning violation check to the end of the 'loadinit' thread, which is where the reindex, block loading and chain activation processes happen. Making the node's startup process faster, allowing us to remove the global g_indexes_ready_to_sync flag, and enabling the execution of the pruning violation verification even when the reindex or reindex-chainstate flags are enabled (which has being skipped so far).
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp41
1 files changed, 38 insertions, 3 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 389654fe4f..e96485b3aa 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -125,7 +125,6 @@ using node::CalculateCacheSizes;
using node::DEFAULT_PERSIST_MEMPOOL;
using node::DEFAULT_PRINTPRIORITY;
using node::fReindex;
-using node::g_indexes_ready_to_sync;
using node::KernelNotifications;
using node::LoadChainstate;
using node::MempoolPath;
@@ -1545,8 +1544,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 8: start indexers
- // If reindex-chainstate was specified, delay syncing indexes until ImportBlocks has reindexed the chain
- if (!fReindexChainState) g_indexes_ready_to_sync = true;
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
auto result{WITH_LOCK(cs_main, return CheckLegacyTxindex(*Assert(chainman.m_blockman.m_block_tree_db)))};
if (!result) {
@@ -1884,6 +1881,44 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
bool StartIndexBackgroundSync(NodeContext& node)
{
+ // Find the oldest block among all indexes.
+ // This block is used to verify that we have the required blocks' data stored on disk,
+ // starting from that point up to the current tip.
+ // 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);
+ 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 (!indexes_start_block || !pindex || pindex->nHeight < indexes_start_block.value()->nHeight) {
+ indexes_start_block = pindex;
+ older_index_name = summary.name;
+ if (!pindex) break; // Starting from genesis so no need to look for earlier block.
+ }
+ };
+
+ // Verify all blocks needed to sync to current tip are present.
+ if (indexes_start_block) {
+ 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))) {
+ 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));
+ }
+ }
+
+ // Start threads
for (auto index : node.indexes) if (!index->StartBackgroundSync()) return false;
return true;
}