mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-17 13:07:54 +02:00
Merge ef29d5d7e2 into merged_master (Bitcoin PR bitcoin/bitcoin#27607)
This commit is contained in:
commit
f61ec91393
20 changed files with 189 additions and 110 deletions
81
src/init.cpp
81
src/init.cpp
|
|
@ -129,13 +129,12 @@ 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;
|
||||
using node::NodeContext;
|
||||
using node::ShouldPersistMempool;
|
||||
using node::ThreadImport;
|
||||
using node::ImportBlocks;
|
||||
using node::VerifyLoadedChainstate;
|
||||
|
||||
static constexpr bool DEFAULT_PROXYRANDOMIZE{true};
|
||||
|
|
@ -277,7 +276,7 @@ void Shutdown(NodeContext& node)
|
|||
// CScheduler/checkqueue, scheduler and load block thread.
|
||||
if (node.scheduler) node.scheduler->stop();
|
||||
if (node.reverification_scheduler) node.reverification_scheduler->stop();
|
||||
if (node.chainman && node.chainman->m_load_block.joinable()) node.chainman->m_load_block.join();
|
||||
if (node.chainman && node.chainman->m_thread_load.joinable()) node.chainman->m_thread_load.join();
|
||||
StopScriptCheckWorkerThreads();
|
||||
|
||||
// After the threads that potentially access these pointers have been stopped,
|
||||
|
|
@ -1687,8 +1686,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
|
||||
// ********************************************************* Step 8: start indexers
|
||||
|
||||
// If reindex-chainstate was specified, delay syncing indexes until ThreadImport 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) {
|
||||
|
|
@ -1696,25 +1693,22 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
}
|
||||
|
||||
g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, fReindex);
|
||||
if (!g_txindex->Start()) {
|
||||
return false;
|
||||
}
|
||||
node.indexes.emplace_back(g_txindex.get());
|
||||
}
|
||||
|
||||
for (const auto& filter_type : g_enabled_filter_types) {
|
||||
InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, fReindex);
|
||||
if (!GetBlockFilterIndex(filter_type)->Start()) {
|
||||
return false;
|
||||
}
|
||||
node.indexes.emplace_back(GetBlockFilterIndex(filter_type));
|
||||
}
|
||||
|
||||
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
|
||||
g_coin_stats_index = std::make_unique<CoinStatsIndex>(interfaces::MakeChain(node), /*cache_size=*/0, false, fReindex);
|
||||
if (!g_coin_stats_index->Start()) {
|
||||
return false;
|
||||
}
|
||||
node.indexes.emplace_back(g_coin_stats_index.get());
|
||||
}
|
||||
|
||||
// Init indexes
|
||||
for (auto index : node.indexes) if (!index->Init()) return false;
|
||||
|
||||
// ********************************************************* Step 9: load wallet
|
||||
for (const auto& client : node.chain_clients) {
|
||||
if (!client->load()) {
|
||||
|
|
@ -1798,15 +1792,24 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
vImportFiles.push_back(fs::PathFromString(strFile));
|
||||
}
|
||||
|
||||
chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &chainman, &args] {
|
||||
ThreadImport(chainman, vImportFiles, ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{});
|
||||
chainman.m_thread_load = std::thread(&util::TraceThread, "initload", [=, &chainman, &args, &node] {
|
||||
// Import blocks
|
||||
ImportBlocks(chainman, vImportFiles);
|
||||
// Start indexes initial sync
|
||||
if (!StartIndexBackgroundSync(node)) {
|
||||
bilingual_str err_str = _("Failed to start indexes, shutting down..");
|
||||
chainman.GetNotifications().fatalError(err_str.original, err_str);
|
||||
return;
|
||||
}
|
||||
// Load mempool from disk
|
||||
chainman.ActiveChainstate().LoadMempool(ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{});
|
||||
});
|
||||
|
||||
// Wait for genesis block to be processed
|
||||
{
|
||||
WAIT_LOCK(g_genesis_wait_mutex, lock);
|
||||
// We previously could hang here if StartShutdown() is called prior to
|
||||
// ThreadImport getting started, so instead we just wait on a timer to
|
||||
// ImportBlocks getting started, so instead we just wait on a timer to
|
||||
// check ShutdownRequested() regularly.
|
||||
while (!fHaveGenesis && !ShutdownRequested()) {
|
||||
g_genesis_wait_cv.wait_for(lock, std::chrono::milliseconds(500));
|
||||
|
|
@ -2059,3 +2062,47 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue