Skip to content

Commit

Permalink
Merge bitcoin/bitcoin#29817: kernel: De-globalize fReindex
Browse files Browse the repository at this point in the history
b47bd95 kernel: De-globalize fReindex (TheCharlatan)

Pull request description:

  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 pull request is part of the [libbitcoinkernel project](bitcoin/bitcoin#27587).

ACKs for top commit:
  achow101:
    ACK b47bd95
  ryanofsky:
    Code review ACK b47bd95. I rereviewed the whole PR, but the only change since last review was reverting the bugfix bitcoin/bitcoin#29817 (comment) and make the change a pure refactoring.
  mzumsande:
    Code Review ACK b47bd95
  stickies-v:
    ACK b47bd95

Tree-SHA512: f7399d01f93bc0c0c7428fe95d19b9d29b4ed00a4f1deabca78fb0c4fecb434ec971e890feecb105938b5247c926850b1b7b4a4a9caa333a061e40777d0c8463
  • Loading branch information
achow101 committed May 17, 2024
2 parents 4877fcd + b47bd95 commit 058af75
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/bitcoin-chainstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ int main(int argc, char* argv[])
{
LOCK(chainman.GetMutex());
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" << "Active Height: " << chainman.ActiveHeight() << std::endl
<< "\t" << "Active IBD: " << std::boolalpha << chainman.IsInitialBlockDownload() << std::noboolalpha << std::endl;
Expand Down
16 changes: 7 additions & 9 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ using node::CalculateCacheSizes;
using node::DEFAULT_PERSIST_MEMPOOL;
using node::DEFAULT_PRINTPRIORITY;
using node::DEFAULT_STOPATHEIGHT;
using node::fReindex;
using node::KernelNotifications;
using node::LoadChainstate;
using node::MempoolPath;
Expand Down Expand Up @@ -1483,7 +1482,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);
fReindex = args.GetBoolArg("-reindex", false);
bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
ChainstateManager::Options chainman_opts{
.chainparams = chainparams,
Expand Down Expand Up @@ -1560,7 +1558,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)

node::ChainstateLoadOptions options;
options.mempool = Assert(node.mempool.get());
options.reindex = node::fReindex;
options.reindex = chainman.m_blockman.m_reindexing;
options.reindex_chainstate = fReindexChainState;
options.prune = chainman.m_blockman.IsPruneMode();
options.check_blocks = args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
Expand Down Expand Up @@ -1608,7 +1606,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
error.original + ".\nPlease restart with -reindex or -reindex-chainstate to recover.",
"", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
if (fRet) {
fReindex = true;
chainman.m_blockman.m_reindexing = true;
if (!Assert(node.shutdown)->reset()) {
LogPrintf("Internal error: failed to reset shutdown signal.\n");
}
Expand Down Expand Up @@ -1641,17 +1639,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, 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());
}

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));
}

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());
}

Expand All @@ -1670,7 +1668,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 (!fReindex) {
if (!chainman.m_blockman.m_reindexing) {
LOCK(cs_main);
for (Chainstate* chainstate : chainman.GetAll()) {
uiInterface.InitMessage(_("Pruning blockstore…").translated);
Expand All @@ -1696,7 +1694,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 (!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 additional_bytes_needed{
chainman.m_blockman.IsPruneMode() ?
Expand Down
1 change: 1 addition & 0 deletions src/kernel/blockmanager_opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct BlockManagerOpts {
bool fast_prune{false};
const fs::path blocks_dir;
Notifications& notifications;
bool reindex{false};
};

} // namespace kernel
Expand Down
2 changes: 2 additions & 0 deletions src/node/blockmanager_args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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("-reindex")}) opts.reindex = *value;

return {};
}
} // namespace node
7 changes: 3 additions & 4 deletions src/node/blockstorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ bool BlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, s
} // namespace kernel

namespace node {
std::atomic_bool fReindex(false);

bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const
{
Expand Down Expand Up @@ -552,7 +551,7 @@ bool BlockManager::LoadBlockIndexDB(const std::optional<uint256>& snapshot_block
// Check whether we need to continue reindexing
bool fReindexing = false;
m_block_tree_db->ReadReindexing(fReindexing);
if (fReindexing) fReindex = true;
if (fReindexing) m_reindexing = true;

return true;
}
Expand Down Expand Up @@ -1183,7 +1182,7 @@ void ImportBlocks(ChainstateManager& chainman, std::vector<fs::path> vImportFile
ImportingNow imp{chainman.m_blockman.m_importing};

// -reindex
if (fReindex) {
if (chainman.m_blockman.m_reindexing) {
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.
Expand All @@ -1206,7 +1205,7 @@ void ImportBlocks(ChainstateManager& chainman, std::vector<fs::path> vImportFile
nFile++;
}
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");
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
chainman.ActiveChainstate().LoadGenesisBlock();
Expand Down
14 changes: 10 additions & 4 deletions src/node/blockstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
/** 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);

extern std::atomic_bool fReindex;

// 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
// container that has stable addressing (true of all std associative
Expand Down Expand Up @@ -269,11 +267,19 @@ class BlockManager
explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts)
: m_prune_mode{opts.prune_target > 0},
m_opts{std::move(opts)},
m_interrupt{interrupt} {};
m_interrupt{interrupt},
m_reindexing{m_opts.reindex} {};

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.
*/
std::atomic_bool m_reindexing;

BlockMap m_block_index GUARDED_BY(cs_main);

/**
Expand Down Expand Up @@ -353,7 +359,7 @@ class BlockManager
[[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 || fReindex; }
[[nodiscard]] bool LoadingBlocks() const { return m_importing || m_reindexing; }

/** Calculate the amount of disk space the block & undo files currently use */
uint64_t CalculateCurrentUsage();
Expand Down
6 changes: 3 additions & 3 deletions src/node/chainstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ static ChainstateLoadResult CompleteChainstateInitialization(

// LoadBlockIndex will load m_have_pruned if we've ever removed a
// block file from disk.
// Note that it also sets fReindex global based on the disk flag!
// From here on, fReindex and options.reindex values may be different!
// Note that it also sets m_reindexing based on the disk flag!
// From here on, m_reindexing and options.reindex values may be different!
if (!chainman.LoadBlockIndex()) {
if (chainman.m_interrupt) return {ChainstateLoadStatus::INTERRUPTED, {}};
return {ChainstateLoadStatus::FAILURE, _("Error loading block database")};
Expand All @@ -84,7 +84,7 @@ 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 (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock()) {
if (!chainman.m_blockman.m_reindexing && !chainman.ActiveChainstate().LoadGenesisBlock()) {
return {ChainstateLoadStatus::FAILURE, _("Error initializing block database")};
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/util/setup_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ 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 = node::fReindex;
options.reindex = chainman.m_blockman.m_reindexing;
options.reindex_chainstate = m_args.GetBoolArg("-reindex-chainstate", false);
options.prune = chainman.m_blockman.IsPruneMode();
options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
Expand Down
25 changes: 12 additions & 13 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ using node::BlockManager;
using node::BlockMap;
using node::CBlockIndexHeightOnlyComparator;
using node::CBlockIndexWorkComparator;
using node::fReindex;
using node::SnapshotMetadata;

/** Time to wait between writing blocks/block index to disk. */
Expand Down Expand Up @@ -2642,7 +2641,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) && !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
// pruning is height-based
int last_prune{m_chain.Height()}; // last height we can prune
Expand Down Expand Up @@ -3255,10 +3254,10 @@ bool Chainstate::ActivateBestChainStep(BlockValidationState& state, CBlockIndex*
return true;
}

static SynchronizationState GetSynchronizationState(bool init)
static SynchronizationState GetSynchronizationState(bool init, bool reindexing)
{
if (!init) return SynchronizationState::POST_INIT;
if (::fReindex) return SynchronizationState::INIT_REINDEX;
if (reindexing) return SynchronizationState::INIT_REINDEX;
return SynchronizationState::INIT_DOWNLOAD;
}

Expand All @@ -3280,7 +3279,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), pindexHeader->nHeight, pindexHeader->nTime, false);
chainman.GetNotifications().headerTip(GetSynchronizationState(fInitialBlockDownload, chainman.m_blockman.m_reindexing), pindexHeader->nHeight, pindexHeader->nTime, false);
}
return fNotify;
}
Expand Down Expand Up @@ -3399,7 +3398,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), *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
// be changed to bubble up the kernel::Interrupted value to
// the caller so the caller could distinguish between
Expand Down Expand Up @@ -3625,7 +3624,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()), *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;
}
Expand Down Expand Up @@ -4264,7 +4263,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t
m_last_presync_update = now;
}
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) {
int64_t blocks_left{(NodeClock::now() - NodeSeconds{std::chrono::seconds{timestamp}}) / GetConsensus().PowTargetSpacing()};
blocks_left = std::max<int64_t>(0, blocks_left);
Expand Down Expand Up @@ -4791,8 +4790,8 @@ bool ChainstateManager::LoadBlockIndex()
{
AssertLockHeld(cs_main);
// Load block index from databases
bool needs_init = fReindex;
if (!fReindex) {
bool needs_init = m_blockman.m_reindexing;
if (!m_blockman.m_reindexing) {
bool ret{m_blockman.LoadBlockIndexDB(SnapshotBlockhash())};
if (!ret) return false;

Expand Down Expand Up @@ -4829,8 +4828,8 @@ bool ChainstateManager::LoadBlockIndex()

if (needs_init) {
// Everything here is for *new* reindex/DBs. Thus, though
// LoadBlockIndexDB may have set fReindex if we shut down
// mid-reindex previously, we don't check fReindex and
// 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.

Expand Down Expand Up @@ -4975,7 +4974,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.
// this is a tradeoff to conserve disk space at the expense of time
// spent updating the tip to be able to prune.
Expand Down

0 comments on commit 058af75

Please sign in to comment.