kernel: De-globalize fReindex

fReindex is one of the last remaining globals exposed by the kernel
library, so move it into the blockstorage class to reduce the amount of
global mutable state and make the kernel library a bit less awkward to
use.
This commit is contained in:
TheCharlatan 2024-04-05 12:44:24 +02:00
parent 42d5a1ff25
commit b47bd95920
No known key found for this signature in database
GPG key ID: 9B79B45691DB4173
9 changed files with 40 additions and 35 deletions

View file

@ -151,7 +151,7 @@ int main(int argc, char* argv[])
{ {
LOCK(chainman.GetMutex()); LOCK(chainman.GetMutex());
std::cout std::cout
<< "\t" << "Reindexing: " << std::boolalpha << node::fReindex.load() << std::noboolalpha << std::endl << "\t" << "Reindexing: " << std::boolalpha << chainman.m_blockman.m_reindexing.load() << std::noboolalpha << std::endl
<< "\t" << "Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl << "\t" << "Snapshot Active: " << std::boolalpha << chainman.IsSnapshotActive() << std::noboolalpha << std::endl
<< "\t" << "Active Height: " << chainman.ActiveHeight() << std::endl << "\t" << "Active Height: " << chainman.ActiveHeight() << std::endl
<< "\t" << "Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl; << "\t" << "Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl;

View file

@ -126,7 +126,6 @@ using node::CalculateCacheSizes;
using node::DEFAULT_PERSIST_MEMPOOL; using node::DEFAULT_PERSIST_MEMPOOL;
using node::DEFAULT_PRINTPRIORITY; using node::DEFAULT_PRINTPRIORITY;
using node::DEFAULT_STOPATHEIGHT; using node::DEFAULT_STOPATHEIGHT;
using node::fReindex;
using node::KernelNotifications; using node::KernelNotifications;
using node::LoadChainstate; using node::LoadChainstate;
using node::MempoolPath; using node::MempoolPath;
@ -1483,7 +1482,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
node.notifications = std::make_unique<KernelNotifications>(*Assert(node.shutdown), node.exit_status); node.notifications = std::make_unique<KernelNotifications>(*Assert(node.shutdown), node.exit_status);
ReadNotificationArgs(args, *node.notifications); ReadNotificationArgs(args, *node.notifications);
fReindex = args.GetBoolArg("-reindex", false);
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false); bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
ChainstateManager::Options chainman_opts{ ChainstateManager::Options chainman_opts{
.chainparams = chainparams, .chainparams = chainparams,
@ -1560,7 +1558,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
node::ChainstateLoadOptions options; node::ChainstateLoadOptions options;
options.mempool = Assert(node.mempool.get()); options.mempool = Assert(node.mempool.get());
options.reindex = node::fReindex; options.reindex = chainman.m_blockman.m_reindexing;
options.reindex_chainstate = fReindexChainState; options.reindex_chainstate = fReindexChainState;
options.prune = chainman.m_blockman.IsPruneMode(); options.prune = chainman.m_blockman.IsPruneMode();
options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
@ -1608,7 +1606,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.", error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT); "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
if (fRet) { if (fRet) {
fReindex = true; chainman.m_blockman.m_reindexing = true;
if (!Assert(node.shutdown)->reset()) { if (!Assert(node.shutdown)->reset()) {
LogPrintf("Internal error: failed to reset shutdown signal.\n"); LogPrintf("Internal error: failed to reset shutdown signal.\n");
} }
@ -1641,17 +1639,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 8: start indexers // ********************************************************* Step 8: start indexers
if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, fReindex); g_txindex = std::make_unique<TxIndex>(interfaces::MakeChain(node), cache_sizes.tx_index, false, chainman.m_blockman.m_reindexing);
node.indexes.emplace_back(g_txindex.get()); node.indexes.emplace_back(g_txindex.get());
} }
for (const auto& filter_type : g_enabled_filter_types) { for (const auto& filter_type : g_enabled_filter_types) {
InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, fReindex); InitBlockFilterIndex([&]{ return interfaces::MakeChain(node); }, filter_type, cache_sizes.filter_index, false, chainman.m_blockman.m_reindexing);
node.indexes.emplace_back(GetBlockFilterIndex(filter_type)); node.indexes.emplace_back(GetBlockFilterIndex(filter_type));
} }
if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) { if (args.GetBoolArg("-coinstatsindex", DEFAULT_COINSTATSINDEX)) {
g_coin_stats_index = std::make_unique<CoinStatsIndex>(interfaces::MakeChain(node), /*cache_size=*/0, false, fReindex); g_coin_stats_index = std::make_unique<CoinStatsIndex>(interfaces::MakeChain(node), /*cache_size=*/0, false, chainman.m_blockman.m_reindexing);
node.indexes.emplace_back(g_coin_stats_index.get()); node.indexes.emplace_back(g_coin_stats_index.get());
} }
@ -1670,7 +1668,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// if pruning, perform the initial blockstore prune // if pruning, perform the initial blockstore prune
// after any wallet rescanning has taken place. // after any wallet rescanning has taken place.
if (chainman.m_blockman.IsPruneMode()) { if (chainman.m_blockman.IsPruneMode()) {
if (!fReindex) { if (!chainman.m_blockman.m_reindexing) {
LOCK(cs_main); LOCK(cs_main);
for (Chainstate* chainstate : chainman.GetAll()) { for (Chainstate* chainstate : chainman.GetAll()) {
uiInterface.InitMessage(_("Pruning blockstore…").translated); uiInterface.InitMessage(_("Pruning blockstore…").translated);
@ -1696,7 +1694,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
int chain_active_height = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); int chain_active_height = WITH_LOCK(cs_main, return chainman.ActiveChain().Height());
// On first startup, warn on low block storage space // On first startup, warn on low block storage space
if (!fReindex && !fReindexChainState && chain_active_height <= 1) { if (!chainman.m_blockman.m_reindexing && !fReindexChainState && chain_active_height <= 1) {
uint64_t assumed_chain_bytes{chainparams.AssumedBlockchainSize() * 1024 * 1024 * 1024}; uint64_t assumed_chain_bytes{chainparams.AssumedBlockchainSize() * 1024 * 1024 * 1024};
uint64_t additional_bytes_needed{ uint64_t additional_bytes_needed{
chainman.m_blockman.IsPruneMode() ? chainman.m_blockman.IsPruneMode() ?

View file

@ -24,6 +24,7 @@ struct BlockManagerOpts {
bool fast_prune{false}; bool fast_prune{false};
const fs::path blocks_dir; const fs::path blocks_dir;
Notifications& notifications; Notifications& notifications;
bool reindex{false};
}; };
} // namespace kernel } // namespace kernel

View file

@ -33,6 +33,8 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Op
if (auto value{args.GetBoolArg("-fastprune")}) opts.fast_prune = *value; if (auto value{args.GetBoolArg("-fastprune")}) opts.fast_prune = *value;
if (auto value{args.GetBoolArg("-reindex")}) opts.reindex = *value;
return {}; return {};
} }
} // namespace node } // namespace node

View file

@ -150,7 +150,6 @@ bool BlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, s
} // namespace kernel } // namespace kernel
namespace node { namespace node {
std::atomic_bool fReindex(false);
bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const
{ {
@ -552,7 +551,7 @@ bool BlockManager::LoadBlockIndexDB(const std::optional<uint256>& snapshot_block
// Check whether we need to continue reindexing // Check whether we need to continue reindexing
bool fReindexing = false; bool fReindexing = false;
m_block_tree_db->ReadReindexing(fReindexing); m_block_tree_db->ReadReindexing(fReindexing);
if (fReindexing) fReindex = true; if (fReindexing) m_reindexing = true;
return true; return true;
} }
@ -1178,7 +1177,7 @@ void ImportBlocks(ChainstateManager& chainman, std::vector<fs::path> vImportFile
ImportingNow imp{chainman.m_blockman.m_importing}; ImportingNow imp{chainman.m_blockman.m_importing};
// -reindex // -reindex
if (fReindex) { if (chainman.m_blockman.m_reindexing) {
int nFile = 0; int nFile = 0;
// Map of disk positions for blocks with unknown parent (only used for reindex); // 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. // parent hash -> child disk position, multiple children can have the same parent.
@ -1201,7 +1200,7 @@ void ImportBlocks(ChainstateManager& chainman, std::vector<fs::path> vImportFile
nFile++; nFile++;
} }
WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db->WriteReindexing(false)); WITH_LOCK(::cs_main, chainman.m_blockman.m_block_tree_db->WriteReindexing(false));
fReindex = false; chainman.m_blockman.m_reindexing = false;
LogPrintf("Reindexing finished\n"); LogPrintf("Reindexing finished\n");
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
chainman.ActiveChainstate().LoadGenesisBlock(); chainman.ActiveChainstate().LoadGenesisBlock();

View file

@ -76,8 +76,6 @@ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
/** Size of header written by WriteBlockToDisk before a serialized CBlock */ /** Size of header written by WriteBlockToDisk before a serialized CBlock */
static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE = std::tuple_size_v<MessageStartChars> + sizeof(unsigned int); static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE = std::tuple_size_v<MessageStartChars> + sizeof(unsigned int);
extern std::atomic_bool fReindex;
// Because validation code takes pointers to the map's CBlockIndex objects, if // Because validation code takes pointers to the map's CBlockIndex objects, if
// we ever switch to another associative container, we need to either use a // we ever switch to another associative container, we need to either use a
// container that has stable addressing (true of all std associative // container that has stable addressing (true of all std associative
@ -254,11 +252,19 @@ public:
explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts) explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts)
: m_prune_mode{opts.prune_target > 0}, : m_prune_mode{opts.prune_target > 0},
m_opts{std::move(opts)}, m_opts{std::move(opts)},
m_interrupt{interrupt} {}; m_interrupt{interrupt},
m_reindexing{m_opts.reindex} {};
const util::SignalInterrupt& m_interrupt; const util::SignalInterrupt& m_interrupt;
std::atomic<bool> m_importing{false}; 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.
*/
std::atomic_bool m_reindexing;
BlockMap m_block_index GUARDED_BY(cs_main); BlockMap m_block_index GUARDED_BY(cs_main);
/** /**
@ -322,7 +328,7 @@ public:
[[nodiscard]] uint64_t GetPruneTarget() const { return m_opts.prune_target; } [[nodiscard]] uint64_t GetPruneTarget() const { return m_opts.prune_target; }
static constexpr auto PRUNE_TARGET_MANUAL{std::numeric_limits<uint64_t>::max()}; static constexpr auto PRUNE_TARGET_MANUAL{std::numeric_limits<uint64_t>::max()};
[[nodiscard]] bool LoadingBlocks() const { return m_importing || fReindex; } [[nodiscard]] bool LoadingBlocks() const { return m_importing || m_reindexing; }
/** Calculate the amount of disk space the block & undo files currently use */ /** Calculate the amount of disk space the block & undo files currently use */
uint64_t CalculateCurrentUsage(); uint64_t CalculateCurrentUsage();

View file

@ -60,8 +60,8 @@ static ChainstateLoadResult CompleteChainstateInitialization(
// LoadBlockIndex will load m_have_pruned if we've ever removed a // LoadBlockIndex will load m_have_pruned if we've ever removed a
// block file from disk. // block file from disk.
// Note that it also sets fReindex global based on the disk flag! // Note that it also sets m_reindexing based on the disk flag!
// From here on, fReindex and options.reindex values may be different! // From here on, m_reindexing and options.reindex values may be different!
if (!chainman.LoadBlockIndex()) { if (!chainman.LoadBlockIndex()) {
if (chainman.m_interrupt) return {ChainstateLoadStatus::INTERRUPTED, {}}; if (chainman.m_interrupt) return {ChainstateLoadStatus::INTERRUPTED, {}};
return {ChainstateLoadStatus::FAILURE, _("Error loading block database")}; return {ChainstateLoadStatus::FAILURE, _("Error loading block database")};
@ -84,7 +84,7 @@ static ChainstateLoadResult CompleteChainstateInitialization(
// If we're not mid-reindex (based on disk + args), add a genesis block on disk // If we're not mid-reindex (based on disk + args), add a genesis block on disk
// (otherwise we use the one already on disk). // (otherwise we use the one already on disk).
// This is called again in ImportBlocks after the reindex completes. // This is called again in ImportBlocks after the reindex completes.
if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock()) { if (!chainman.m_blockman.m_reindexing && !chainman.ActiveChainstate().LoadGenesisBlock()) {
return {ChainstateLoadStatus::FAILURE, _("Error initializing block database")}; return {ChainstateLoadStatus::FAILURE, _("Error initializing block database")};
} }

View file

@ -276,7 +276,7 @@ void ChainTestingSetup::LoadVerifyActivateChainstate()
options.mempool = Assert(m_node.mempool.get()); options.mempool = Assert(m_node.mempool.get());
options.block_tree_db_in_memory = m_block_tree_db_in_memory; options.block_tree_db_in_memory = m_block_tree_db_in_memory;
options.coins_db_in_memory = m_coins_db_in_memory; options.coins_db_in_memory = m_coins_db_in_memory;
options.reindex = node::fReindex; options.reindex = chainman.m_blockman.m_reindexing;
options.reindex_chainstate = m_args.GetBoolArg("-reindex-chainstate", false); options.reindex_chainstate = m_args.GetBoolArg("-reindex-chainstate", false);
options.prune = chainman.m_blockman.IsPruneMode(); options.prune = chainman.m_blockman.IsPruneMode();
options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS); options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);

View file

@ -83,7 +83,6 @@ using node::BlockManager;
using node::BlockMap; using node::BlockMap;
using node::CBlockIndexHeightOnlyComparator; using node::CBlockIndexHeightOnlyComparator;
using node::CBlockIndexWorkComparator; using node::CBlockIndexWorkComparator;
using node::fReindex;
using node::SnapshotMetadata; using node::SnapshotMetadata;
/** Time to wait between writing blocks/block index to disk. */ /** Time to wait between writing blocks/block index to disk. */
@ -2642,7 +2641,7 @@ bool Chainstate::FlushStateToDisk(
CoinsCacheSizeState cache_state = GetCoinsCacheSizeState(); CoinsCacheSizeState cache_state = GetCoinsCacheSizeState();
LOCK(m_blockman.cs_LastBlockFile); LOCK(m_blockman.cs_LastBlockFile);
if (m_blockman.IsPruneMode() && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && !fReindex) { if (m_blockman.IsPruneMode() && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && !m_chainman.m_blockman.m_reindexing) {
// make sure we don't prune above any of the prune locks bestblocks // make sure we don't prune above any of the prune locks bestblocks
// pruning is height-based // pruning is height-based
int last_prune{m_chain.Height()}; // last height we can prune int last_prune{m_chain.Height()}; // last height we can prune
@ -3255,10 +3254,10 @@ bool Chainstate::ActivateBestChainStep(BlockValidationState& state, CBlockIndex*
return true; return true;
} }
static SynchronizationState GetSynchronizationState(bool init) static SynchronizationState GetSynchronizationState(bool init, bool reindexing)
{ {
if (!init) return SynchronizationState::POST_INIT; if (!init) return SynchronizationState::POST_INIT;
if (::fReindex) return SynchronizationState::INIT_REINDEX; if (reindexing) return SynchronizationState::INIT_REINDEX;
return SynchronizationState::INIT_DOWNLOAD; return SynchronizationState::INIT_DOWNLOAD;
} }
@ -3280,7 +3279,7 @@ static bool NotifyHeaderTip(ChainstateManager& chainman) LOCKS_EXCLUDED(cs_main)
} }
// Send block tip changed notifications without cs_main // Send block tip changed notifications without cs_main
if (fNotify) { if (fNotify) {
chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload), pindexHeader->nHeight, pindexHeader->nTime, false); chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload, chainman.m_blockman.m_reindexing), pindexHeader->nHeight, pindexHeader->nTime, false);
} }
return fNotify; return fNotify;
} }
@ -3399,7 +3398,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
} }
// Always notify the UI if a new block tip was connected // Always notify the UI if a new block tip was connected
if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd), *pindexNewTip))) { if (kernel::IsInterrupted(m_chainman.GetNotifications().blockTip(GetSynchronizationState(still_in_ibd, m_chainman.m_blockman.m_reindexing), *pindexNewTip))) {
// Just breaking and returning success for now. This could // Just breaking and returning success for now. This could
// be changed to bubble up the kernel::Interrupted value to // be changed to bubble up the kernel::Interrupted value to
// the caller so the caller could distinguish between // the caller so the caller could distinguish between
@ -3625,7 +3624,7 @@ bool Chainstate::InvalidateBlock(BlockValidationState& state, CBlockIndex* pinde
// parameter indicating the source of the tip change so hooks can // parameter indicating the source of the tip change so hooks can
// distinguish user-initiated invalidateblock changes from other // distinguish user-initiated invalidateblock changes from other
// changes. // changes.
(void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload()), *to_mark_failed->pprev); (void)m_chainman.GetNotifications().blockTip(GetSynchronizationState(m_chainman.IsInitialBlockDownload(), m_chainman.m_blockman.m_reindexing), *to_mark_failed->pprev);
} }
return true; return true;
} }
@ -4264,7 +4263,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t
m_last_presync_update = now; m_last_presync_update = now;
} }
bool initial_download = IsInitialBlockDownload(); bool initial_download = IsInitialBlockDownload();
GetNotifications().headerTip(GetSynchronizationState(initial_download), height, timestamp, /*presync=*/true); GetNotifications().headerTip(GetSynchronizationState(initial_download, m_blockman.m_reindexing), height, timestamp, /*presync=*/true);
if (initial_download) { if (initial_download) {
int64_t blocks_left{(NodeClock::now() - NodeSeconds{std::chrono::seconds{timestamp}}) / GetConsensus().PowTargetSpacing()}; int64_t blocks_left{(NodeClock::now() - NodeSeconds{std::chrono::seconds{timestamp}}) / GetConsensus().PowTargetSpacing()};
blocks_left = std::max<int64_t>(0, blocks_left); blocks_left = std::max<int64_t>(0, blocks_left);
@ -4785,8 +4784,8 @@ bool ChainstateManager::LoadBlockIndex()
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
// Load block index from databases // Load block index from databases
bool needs_init = fReindex; bool needs_init = m_blockman.m_reindexing;
if (!fReindex) { if (!m_blockman.m_reindexing) {
bool ret{m_blockman.LoadBlockIndexDB(SnapshotBlockhash())}; bool ret{m_blockman.LoadBlockIndexDB(SnapshotBlockhash())};
if (!ret) return false; if (!ret) return false;
@ -4823,8 +4822,8 @@ bool ChainstateManager::LoadBlockIndex()
if (needs_init) { if (needs_init) {
// Everything here is for *new* reindex/DBs. Thus, though // Everything here is for *new* reindex/DBs. Thus, though
// LoadBlockIndexDB may have set fReindex if we shut down // LoadBlockIndexDB may have set m_reindexing if we shut down
// mid-reindex previously, we don't check fReindex and // mid-reindex previously, we don't check m_reindexing and
// instead only check it prior to LoadBlockIndexDB to set // instead only check it prior to LoadBlockIndexDB to set
// needs_init. // needs_init.
@ -4969,7 +4968,7 @@ void ChainstateManager::LoadExternalBlockFile(
} }
} }
if (m_blockman.IsPruneMode() && !fReindex && pblock) { if (m_blockman.IsPruneMode() && !m_blockman.m_reindexing && pblock) {
// must update the tip for pruning to work while importing with -loadblock. // 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 // this is a tradeoff to conserve disk space at the expense of time
// spent updating the tip to be able to prune. // spent updating the tip to be able to prune.