mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-16 13:01:19 +02:00
Merge b1ba1b178f into merged_master (Bitcoin PR bitcoin/bitcoin#30132)
This commit is contained in:
commit
af7931ef34
12 changed files with 73 additions and 62 deletions
|
|
@ -151,7 +151,7 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
LOCK(chainman.GetMutex());
|
||||
std::cout
|
||||
<< "\t" << "Reindexing: " << std::boolalpha << chainman.m_blockman.m_reindexing.load() << std::noboolalpha << std::endl
|
||||
<< "\t" << "Blockfiles Indexed: " << std::boolalpha << chainman.m_blockman.m_blockfiles_indexed.load() << std::noboolalpha << std::endl
|
||||
<< "\t" << "Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl
|
||||
<< "\t" << "Active Height: " << chainman.ActiveHeight() << std::endl
|
||||
<< "\t" << "Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl;
|
||||
|
|
|
|||
22
src/init.cpp
22
src/init.cpp
|
|
@ -1628,7 +1628,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
|
||||
node.notifications = std::make_unique<KernelNotifications>(*Assert(node.shutdown), node.exit_status);
|
||||
ReadNotificationArgs(args, *node.notifications);
|
||||
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
|
||||
ChainstateManager::Options chainman_opts{
|
||||
.chainparams = chainparams,
|
||||
.datadir = args.GetDataDirNet(),
|
||||
|
|
@ -1679,6 +1678,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
}
|
||||
LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n", cache_sizes.coins * (1.0 / 1024 / 1024), mempool_opts.max_size_bytes * (1.0 / 1024 / 1024));
|
||||
|
||||
bool do_reindex{args.GetBoolArg("-reindex", false)};
|
||||
const bool do_reindex_chainstate{args.GetBoolArg("-reindex-chainstate", false)};
|
||||
|
||||
for (bool fLoaded = false; !fLoaded && !ShutdownRequested(node);) {
|
||||
node.mempool = std::make_unique<CTxMemPool>(mempool_opts);
|
||||
|
||||
|
|
@ -1706,8 +1708,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
|
||||
node::ChainstateLoadOptions options;
|
||||
options.mempool = Assert(node.mempool.get());
|
||||
options.reindex = chainman.m_blockman.m_reindexing;
|
||||
options.reindex_chainstate = fReindexChainState;
|
||||
options.wipe_block_tree_db = do_reindex;
|
||||
options.wipe_chainstate_db = do_reindex || do_reindex_chainstate;
|
||||
options.prune = chainman.m_blockman.IsPruneMode();
|
||||
options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
|
||||
options.check_level = args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
|
||||
|
|
@ -1748,13 +1750,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
|
||||
if (!fLoaded && !ShutdownRequested(node)) {
|
||||
// first suggest a reindex
|
||||
if (!options.reindex) {
|
||||
if (!do_reindex) {
|
||||
bool fRet = uiInterface.ThreadSafeQuestion(
|
||||
error + Untranslated(".\n\n") + _("Do you want to rebuild the block database now?"),
|
||||
error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
|
||||
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
|
||||
if (fRet) {
|
||||
chainman.m_blockman.m_reindexing = true;
|
||||
do_reindex = true;
|
||||
if (!Assert(node.shutdown)->reset()) {
|
||||
LogPrintf("Internal error: failed to reset shutdown signal.\n");
|
||||
}
|
||||
|
|
@ -1787,17 +1789,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
// ********************************************************* Step 8: start indexers
|
||||
|
||||
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
|
||||
g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, chainman.m_blockman.m_reindexing);
|
||||
g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, do_reindex);
|
||||
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, chainman.m_blockman.m_reindexing);
|
||||
InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, do_reindex);
|
||||
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, chainman.m_blockman.m_reindexing);
|
||||
g_coin_stats_index = std::make_unique<CoinStatsIndex>(interfaces::MakeChain(node), /*cache_size=*/0, false, do_reindex);
|
||||
node.indexes.emplace_back(g_coin_stats_index.get());
|
||||
}
|
||||
|
||||
|
|
@ -1816,7 +1818,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
// if pruning, perform the initial blockstore prune
|
||||
// after any wallet rescanning has taken place.
|
||||
if (chainman.m_blockman.IsPruneMode()) {
|
||||
if (!chainman.m_blockman.m_reindexing) {
|
||||
if (chainman.m_blockman.m_blockfiles_indexed) {
|
||||
LOCK(cs_main);
|
||||
for (Chainstate* chainstate : chainman.GetAll()) {
|
||||
uiInterface.InitMessage(_("Pruning blockstore…").translated);
|
||||
|
|
@ -1842,7 +1844,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||
int chain_active_height = WITH_LOCK(cs_main, return chainman.ActiveChain().Height());
|
||||
|
||||
// On first startup, warn on low block storage space
|
||||
if (!chainman.m_blockman.m_reindexing && !fReindexChainState && chain_active_height <= 1) {
|
||||
if (!do_reindex && !do_reindex_chainstate && chain_active_height <= 1) {
|
||||
uint64_t assumed_chain_bytes{chainparams.AssumedBlockchainSize() * 1024 * 1024 * 1024};
|
||||
uint64_t additional_bytes_needed{
|
||||
chainman.m_blockman.IsPruneMode() ?
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ struct BlockManagerOpts {
|
|||
bool fast_prune{false};
|
||||
const fs::path blocks_dir;
|
||||
Notifications& notifications;
|
||||
bool reindex{false};
|
||||
};
|
||||
|
||||
} // namespace kernel
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Op
|
|||
|
||||
if (auto value{args.GetBoolArg("-fastprune")}) opts.fast_prune = *value;
|
||||
|
||||
if (auto value{args.GetBoolArg("-reindex")}) opts.reindex = *value;
|
||||
|
||||
return {};
|
||||
}
|
||||
} // namespace node
|
||||
|
|
|
|||
|
|
@ -644,7 +644,7 @@ bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman, const std::opti
|
|||
// Check whether we need to continue reindexing
|
||||
bool fReindexing = false;
|
||||
m_block_tree_db->ReadReindexing(fReindexing);
|
||||
if (fReindexing) m_reindexing = true;
|
||||
if (fReindexing) m_blockfiles_indexed = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1277,7 +1277,7 @@ void ImportBlocks(ChainstateManager& chainman, std::vector<fs::path> vImportFile
|
|||
ImportingNow imp{chainman.m_blockman.m_importing};
|
||||
|
||||
// -reindex
|
||||
if (chainman.m_blockman.m_reindexing) {
|
||||
if (!chainman.m_blockman.m_blockfiles_indexed) {
|
||||
int nFile = 0;
|
||||
// Map of disk positions for blocks with unknown parent (only used for reindex);
|
||||
// parent hash -> child disk position, multiple children can have the same parent.
|
||||
|
|
@ -1300,7 +1300,7 @@ void ImportBlocks(ChainstateManager& chainman, std::vector<fs::path> vImportFile
|
|||
nFile++;
|
||||
}
|
||||
WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db->WriteReindexing(false));
|
||||
chainman.m_blockman.m_reindexing = false;
|
||||
chainman.m_blockman.m_blockfiles_indexed = true;
|
||||
LogPrintf("Reindexing finished\n");
|
||||
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
|
||||
chainman.ActiveChainstate().LoadGenesisBlock();
|
||||
|
|
|
|||
|
|
@ -281,18 +281,18 @@ public:
|
|||
explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts)
|
||||
: m_prune_mode{opts.prune_target > 0},
|
||||
m_opts{std::move(opts)},
|
||||
m_interrupt{interrupt},
|
||||
m_reindexing{m_opts.reindex} {};
|
||||
m_interrupt{interrupt} {}
|
||||
|
||||
const util::SignalInterrupt& m_interrupt;
|
||||
std::atomic<bool> m_importing{false};
|
||||
|
||||
/**
|
||||
* Tracks if a reindex is currently in progress. Set to true when a reindex
|
||||
* is requested and false when reindexing completes. Its value is persisted
|
||||
* in the BlockTreeDB across restarts.
|
||||
* Whether all blockfiles have been added to the block tree database.
|
||||
* Normally true, but set to false when a reindex is requested and the
|
||||
* database is wiped. The value is persisted in the database across restarts
|
||||
* and will be false until reindexing completes.
|
||||
*/
|
||||
std::atomic_bool m_reindexing;
|
||||
std::atomic_bool m_blockfiles_indexed{true};
|
||||
|
||||
BlockMap m_block_index GUARDED_BY(cs_main);
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ public:
|
|||
[[nodiscard]] uint64_t GetPruneTarget() const { return m_opts.prune_target; }
|
||||
static constexpr auto PRUNE_TARGET_MANUAL{std::numeric_limits<uint64_t>::max()};
|
||||
|
||||
[[nodiscard]] bool LoadingBlocks() const { return m_importing || m_reindexing; }
|
||||
[[nodiscard]] bool LoadingBlocks() const { return m_importing || !m_blockfiles_indexed; }
|
||||
|
||||
/** Calculate the amount of disk space the block & undo files currently use */
|
||||
uint64_t CalculateCurrentUsage();
|
||||
|
|
|
|||
|
|
@ -45,11 +45,12 @@ static ChainstateLoadResult CompleteChainstateInitialization(
|
|||
.path = chainman.m_options.datadir / "blocks" / "index",
|
||||
.cache_bytes = static_cast<size_t>(cache_sizes.block_tree_db),
|
||||
.memory_only = options.block_tree_db_in_memory,
|
||||
.wipe_data = options.reindex,
|
||||
.wipe_data = options.wipe_block_tree_db,
|
||||
.options = chainman.m_options.block_tree_db});
|
||||
|
||||
if (options.reindex) {
|
||||
if (options.wipe_block_tree_db) {
|
||||
pblocktree->WriteReindexing(true);
|
||||
chainman.m_blockman.m_blockfiles_indexed = false;
|
||||
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
|
||||
if (options.prune) {
|
||||
chainman.m_blockman.CleanupBlockRevFiles();
|
||||
|
|
@ -60,8 +61,7 @@ static ChainstateLoadResult CompleteChainstateInitialization(
|
|||
|
||||
// LoadBlockIndex will load m_have_pruned if we've ever removed a
|
||||
// block file from disk.
|
||||
// Note that it also sets m_reindexing based on the disk flag!
|
||||
// From here on, m_reindexing and options.reindex values may be different!
|
||||
// Note that it also sets m_blockfiles_indexed based on the disk flag!
|
||||
if (!chainman.LoadBlockIndex()) {
|
||||
if (chainman.m_interrupt) return {ChainstateLoadStatus::INTERRUPTED, {}};
|
||||
return {ChainstateLoadStatus::FAILURE, _("Error loading block database")};
|
||||
|
|
@ -84,12 +84,12 @@ static ChainstateLoadResult CompleteChainstateInitialization(
|
|||
// If we're not mid-reindex (based on disk + args), add a genesis block on disk
|
||||
// (otherwise we use the one already on disk).
|
||||
// This is called again in ImportBlocks after the reindex completes.
|
||||
if (!chainman.m_blockman.m_reindexing && !chainman.ActiveChainstate().LoadGenesisBlock()) {
|
||||
if (chainman.m_blockman.m_blockfiles_indexed && !chainman.ActiveChainstate().LoadGenesisBlock()) {
|
||||
return {ChainstateLoadStatus::FAILURE, _("Error initializing block database")};
|
||||
}
|
||||
|
||||
auto is_coinsview_empty = [&](Chainstate* chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
|
||||
return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull();
|
||||
return options.wipe_chainstate_db || chainstate->CoinsTip().GetBestBlock().IsNull();
|
||||
};
|
||||
|
||||
assert(chainman.m_total_coinstip_cache > 0);
|
||||
|
|
@ -110,7 +110,7 @@ static ChainstateLoadResult CompleteChainstateInitialization(
|
|||
chainstate->InitCoinsDB(
|
||||
/*cache_size_bytes=*/chainman.m_total_coinsdb_cache * init_cache_fraction,
|
||||
/*in_memory=*/options.coins_db_in_memory,
|
||||
/*should_wipe=*/options.reindex || options.reindex_chainstate);
|
||||
/*should_wipe=*/options.wipe_chainstate_db);
|
||||
|
||||
if (options.coins_error_cb) {
|
||||
chainstate->CoinsErrorCatcher().AddReadErrCallback(options.coins_error_cb);
|
||||
|
|
@ -142,7 +142,7 @@ static ChainstateLoadResult CompleteChainstateInitialization(
|
|||
}
|
||||
}
|
||||
|
||||
if (!options.reindex) {
|
||||
if (!options.wipe_block_tree_db) {
|
||||
auto chainstates{chainman.GetAll()};
|
||||
if (std::any_of(chainstates.begin(), chainstates.end(),
|
||||
[](const Chainstate* cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->NeedsRedownload(); })) {
|
||||
|
|
@ -188,7 +188,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
|
|||
// Load a chain created from a UTXO snapshot, if any exist.
|
||||
bool has_snapshot = chainman.DetectSnapshotChainstate();
|
||||
|
||||
if (has_snapshot && (options.reindex || options.reindex_chainstate)) {
|
||||
if (has_snapshot && options.wipe_chainstate_db) {
|
||||
LogPrintf("[snapshot] deleting snapshot chainstate due to reindexing\n");
|
||||
if (!chainman.DeleteSnapshotChainstate()) {
|
||||
return {ChainstateLoadStatus::FAILURE_FATAL, Untranslated("Couldn't remove snapshot chainstate.")};
|
||||
|
|
@ -247,7 +247,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
|
|||
ChainstateLoadResult VerifyLoadedChainstate(ChainstateManager& chainman, const ChainstateLoadOptions& options)
|
||||
{
|
||||
auto is_coinsview_empty = [&](Chainstate* chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
|
||||
return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull();
|
||||
return options.wipe_chainstate_db || chainstate->CoinsTip().GetBestBlock().IsNull();
|
||||
};
|
||||
|
||||
LOCK(cs_main);
|
||||
|
|
|
|||
|
|
@ -22,8 +22,13 @@ struct ChainstateLoadOptions {
|
|||
CTxMemPool* mempool{nullptr};
|
||||
bool block_tree_db_in_memory{false};
|
||||
bool coins_db_in_memory{false};
|
||||
bool reindex{false};
|
||||
bool reindex_chainstate{false};
|
||||
// Whether to wipe the block tree database when loading it. If set, this
|
||||
// will also set a reindexing flag so any existing block data files will be
|
||||
// scanned and added to the database.
|
||||
bool wipe_block_tree_db{false};
|
||||
// Whether to wipe the chainstate database when loading it. If set, this
|
||||
// will cause the chainstate database to be rebuilt starting from genesis.
|
||||
bool wipe_chainstate_db{false};
|
||||
bool prune{false};
|
||||
//! Setting require_full_verification to true will require all checks at
|
||||
//! check_level (below) to succeed for loading to succeed. Setting it to
|
||||
|
|
|
|||
|
|
@ -298,8 +298,8 @@ void ChainTestingSetup::LoadVerifyActivateChainstate()
|
|||
options.mempool = Assert(m_node.mempool.get());
|
||||
options.block_tree_db_in_memory = m_block_tree_db_in_memory;
|
||||
options.coins_db_in_memory = m_coins_db_in_memory;
|
||||
options.reindex = chainman.m_blockman.m_reindexing;
|
||||
options.reindex_chainstate = m_args.GetBoolArg("-reindex-chainstate", false);
|
||||
options.wipe_block_tree_db = m_args.GetBoolArg("-reindex", false);
|
||||
options.wipe_chainstate_db = m_args.GetBoolArg("-reindex", false) || m_args.GetBoolArg("-reindex-chainstate", false);
|
||||
options.prune = chainman.m_blockman.IsPruneMode();
|
||||
options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
|
||||
options.check_level = m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
|
||||
|
|
|
|||
|
|
@ -3074,7 +3074,7 @@ bool Chainstate::FlushStateToDisk(
|
|||
|
||||
CoinsCacheSizeState cache_state = GetCoinsCacheSizeState();
|
||||
LOCK(m_blockman.cs_LastBlockFile);
|
||||
if (m_blockman.IsPruneMode() && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && !m_chainman.m_blockman.m_reindexing) {
|
||||
if (m_blockman.IsPruneMode() && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && m_chainman.m_blockman.m_blockfiles_indexed) {
|
||||
// make sure we don't prune above any of the prune locks bestblocks
|
||||
// pruning is height-based
|
||||
int last_prune{m_chain.Height()}; // last height we can prune
|
||||
|
|
@ -3775,10 +3775,10 @@ bool Chainstate::ActivateBestChainStep(BlockValidationState& state, CBlockIndex*
|
|||
return true;
|
||||
}
|
||||
|
||||
static SynchronizationState GetSynchronizationState(bool init, bool reindexing)
|
||||
static SynchronizationState GetSynchronizationState(bool init, bool blockfiles_indexed)
|
||||
{
|
||||
if (!init) return SynchronizationState::POST_INIT;
|
||||
if (reindexing) return SynchronizationState::INIT_REINDEX;
|
||||
if (!blockfiles_indexed) return SynchronizationState::INIT_REINDEX;
|
||||
return SynchronizationState::INIT_DOWNLOAD;
|
||||
}
|
||||
|
||||
|
|
@ -3800,7 +3800,7 @@ static bool NotifyHeaderTip(ChainstateManager& chainman) LOCKS_EXCLUDED(cs_main)
|
|||
}
|
||||
// Send block tip changed notifications without cs_main
|
||||
if (fNotify) {
|
||||
chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload, chainman.m_blockman.m_reindexing), pindexHeader->nHeight, pindexHeader->nTime, false);
|
||||
chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload, chainman.m_blockman.m_blockfiles_indexed), pindexHeader->nHeight, pindexHeader->nTime, false);
|
||||
}
|
||||
return fNotify;
|
||||
}
|
||||
|
|
@ -3926,7 +3926,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
|
|||
}
|
||||
|
||||
// Always notify the UI if a new block tip was connected
|
||||
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_reindexing), *pindexNewTip))) {
|
||||
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_blockfiles_indexed), *pindexNewTip))) {
|
||||
// Just breaking and returning success for now. This could
|
||||
// be changed to bubble up the kernel::Interrupted value to
|
||||
// the caller so the caller could distinguish between
|
||||
|
|
@ -4157,7 +4157,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
|
|||
// parameter indicating the source of the tip change so hooks can
|
||||
// distinguish user-initiated invalidateblock changes from other
|
||||
// changes.
|
||||
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_reindexing), *to_mark_failed->pprev);
|
||||
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_blockfiles_indexed), *to_mark_failed->pprev);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -4935,7 +4935,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t
|
|||
m_last_presync_update = now;
|
||||
}
|
||||
bool initial_download = IsInitialBlockDownload();
|
||||
GetNotifications().headerTip(GetSynchronizationState(initial_download, m_blockman.m_reindexing), height, timestamp, /*presync=*/true);
|
||||
GetNotifications().headerTip(GetSynchronizationState(initial_download, m_blockman.m_blockfiles_indexed), height, timestamp, /*presync=*/true);
|
||||
if (initial_download) {
|
||||
int64_t blocks_left{(NodeClock::now() - NodeSeconds{std::chrono::seconds{timestamp}}) / GetConsensus().PowTargetSpacing()};
|
||||
blocks_left = std::max<int64_t>(0, blocks_left);
|
||||
|
|
@ -5463,8 +5463,7 @@ bool ChainstateManager::LoadBlockIndex()
|
|||
{
|
||||
AssertLockHeld(cs_main);
|
||||
// Load block index from databases
|
||||
bool needs_init = m_blockman.m_reindexing;
|
||||
if (!m_blockman.m_reindexing) {
|
||||
if (m_blockman.m_blockfiles_indexed) {
|
||||
bool ret{m_blockman.LoadBlockIndexDB(*this, SnapshotBlockhash())};
|
||||
if (!ret) return false;
|
||||
|
||||
|
|
@ -5495,18 +5494,6 @@ bool ChainstateManager::LoadBlockIndex()
|
|||
if (pindex->IsValid(BLOCK_VALID_TREE) && (m_best_header == nullptr || CBlockIndexWorkComparator()(m_best_header, pindex)))
|
||||
m_best_header = pindex;
|
||||
}
|
||||
|
||||
needs_init = m_blockman.m_block_index.empty();
|
||||
}
|
||||
|
||||
if (needs_init) {
|
||||
// Everything here is for *new* reindex/DBs. Thus, though
|
||||
// LoadBlockIndexDB may have set m_reindexing if we shut down
|
||||
// mid-reindex previously, we don't check m_reindexing and
|
||||
// instead only check it prior to LoadBlockIndexDB to set
|
||||
// needs_init.
|
||||
|
||||
LogPrintf("Initializing databases...\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5647,7 +5634,7 @@ void ChainstateManager::LoadExternalBlockFile(
|
|||
}
|
||||
}
|
||||
|
||||
if (m_blockman.IsPruneMode() && !m_blockman.m_reindexing && pblock) {
|
||||
if (m_blockman.IsPruneMode() && m_blockman.m_blockfiles_indexed && pblock) {
|
||||
// must update the tip for pruning to work while importing with -loadblock.
|
||||
// this is a tradeoff to conserve disk space at the expense of time
|
||||
// spent updating the tip to be able to prune.
|
||||
|
|
|
|||
|
|
@ -73,6 +73,25 @@ class ReindexTest(BitcoinTestFramework):
|
|||
# All blocks should be accepted and processed.
|
||||
assert_equal(self.nodes[0].getblockcount(), 12)
|
||||
|
||||
def continue_reindex_after_shutdown(self):
|
||||
node = self.nodes[0]
|
||||
self.generate(node, 1500)
|
||||
|
||||
# Restart node with reindex and stop reindex as soon as it starts reindexing
|
||||
self.log.info("Restarting node while reindexing..")
|
||||
node.stop_node()
|
||||
with node.busy_wait_for_debug_log([b'initload thread start']):
|
||||
node.start(['-blockfilterindex', '-reindex'])
|
||||
node.wait_for_rpc_connection(wait_for_import=False)
|
||||
node.stop_node()
|
||||
|
||||
# Start node without the reindex flag and verify it does not wipe the indexes data again
|
||||
db_path = node.chain_path / 'indexes' / 'blockfilter' / 'basic' / 'db'
|
||||
with node.assert_debug_log(expected_msgs=[f'Opening LevelDB in {db_path}'], unexpected_msgs=[f'Wiping LevelDB in {db_path}']):
|
||||
node.start(['-blockfilterindex'])
|
||||
node.wait_for_rpc_connection(wait_for_import=False)
|
||||
node.stop_node()
|
||||
|
||||
def run_test(self):
|
||||
self.reindex(False)
|
||||
self.reindex(True)
|
||||
|
|
@ -80,6 +99,7 @@ class ReindexTest(BitcoinTestFramework):
|
|||
self.reindex(True)
|
||||
|
||||
self.out_of_order()
|
||||
self.continue_reindex_after_shutdown()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ class TestNode():
|
|||
if self.start_perf:
|
||||
self._start_perf()
|
||||
|
||||
def wait_for_rpc_connection(self):
|
||||
def wait_for_rpc_connection(self, *, wait_for_import=True):
|
||||
"""Sets up an RPC connection to the bitcoind process. Returns False if unable to connect."""
|
||||
# Poll at a rate of four times per second
|
||||
poll_per_s = 4
|
||||
|
|
@ -276,7 +276,7 @@ class TestNode():
|
|||
)
|
||||
rpc.getblockcount()
|
||||
# If the call to getblockcount() succeeds then the RPC connection is up
|
||||
if self.version_is_at_least(190000):
|
||||
if self.version_is_at_least(190000) and wait_for_import:
|
||||
# getmempoolinfo.loaded is available since commit
|
||||
# bb8ae2c (version 0.19.0)
|
||||
self.wait_until(lambda: rpc.getmempoolinfo()['loaded'])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue